trunk/src/mame/video/hng64.c
| r244679 | r244680 | |
| 7 | 7 | |
| 8 | 8 | |
| 9 | 9 | |
| 10 | | void hng64_state::hng64_mark_all_tiles_dirty( int tilemap ) |
| 10 | static void hng64_mark_all_tiles_dirty( hng64_state *state, int tilemap ) |
| 11 | 11 | { |
| 12 | | m_tilemap[tilemap].m_tilemap_8x8->mark_all_dirty(); |
| 13 | | m_tilemap[tilemap].m_tilemap_16x16->mark_all_dirty(); |
| 14 | | m_tilemap[tilemap].m_tilemap_16x16_alt->mark_all_dirty(); |
| 12 | if (tilemap == 0) |
| 13 | { |
| 14 | state->m_tilemap0_8x8->mark_all_dirty(); |
| 15 | state->m_tilemap0_16x16->mark_all_dirty(); |
| 16 | state->m_tilemap0_16x16_alt->mark_all_dirty(); |
| 17 | } |
| 18 | else if (tilemap == 1) |
| 19 | { |
| 20 | state->m_tilemap1_8x8->mark_all_dirty(); |
| 21 | state->m_tilemap1_16x16->mark_all_dirty(); |
| 22 | state->m_tilemap1_16x16_alt->mark_all_dirty(); |
| 23 | } |
| 24 | else if (tilemap == 2) |
| 25 | { |
| 26 | state->m_tilemap2_8x8->mark_all_dirty(); |
| 27 | state->m_tilemap2_16x16->mark_all_dirty(); |
| 28 | state->m_tilemap2_16x16_alt->mark_all_dirty(); |
| 29 | } |
| 30 | else if (tilemap == 3) |
| 31 | { |
| 32 | state->m_tilemap3_8x8->mark_all_dirty(); |
| 33 | state->m_tilemap3_16x16->mark_all_dirty(); |
| 34 | state->m_tilemap3_16x16_alt->mark_all_dirty(); |
| 35 | } |
| 15 | 36 | } |
| 16 | 37 | |
| 17 | | void hng64_state::hng64_mark_tile_dirty( int tilemap, int tile_index ) |
| 38 | static void hng64_mark_tile_dirty( hng64_state *state, int tilemap, int tile_index ) |
| 18 | 39 | { |
| 19 | | m_tilemap[tilemap].m_tilemap_8x8->mark_tile_dirty(tile_index); |
| 20 | | m_tilemap[tilemap].m_tilemap_16x16->mark_tile_dirty(tile_index); |
| 21 | | m_tilemap[tilemap].m_tilemap_16x16_alt->mark_tile_dirty(tile_index); |
| 40 | if (tilemap == 0) |
| 41 | { |
| 42 | state->m_tilemap0_8x8->mark_tile_dirty(tile_index); |
| 43 | state->m_tilemap0_16x16->mark_tile_dirty(tile_index); |
| 44 | state->m_tilemap0_16x16_alt->mark_tile_dirty(tile_index); |
| 45 | } |
| 46 | else if (tilemap == 1) |
| 47 | { |
| 48 | state->m_tilemap1_8x8->mark_tile_dirty(tile_index); |
| 49 | state->m_tilemap1_16x16->mark_tile_dirty(tile_index); |
| 50 | state->m_tilemap1_16x16_alt->mark_tile_dirty(tile_index); |
| 51 | } |
| 52 | else if (tilemap == 2) |
| 53 | { |
| 54 | state->m_tilemap2_8x8->mark_tile_dirty(tile_index); |
| 55 | state->m_tilemap2_16x16->mark_tile_dirty(tile_index); |
| 56 | state->m_tilemap2_16x16_alt->mark_tile_dirty(tile_index); |
| 57 | } |
| 58 | else if (tilemap == 3) |
| 59 | { |
| 60 | state->m_tilemap3_8x8->mark_tile_dirty(tile_index); |
| 61 | state->m_tilemap3_16x16->mark_tile_dirty(tile_index); |
| 62 | state->m_tilemap3_16x16_alt->mark_tile_dirty(tile_index); |
| 63 | } |
| 22 | 64 | } |
| 23 | 65 | |
| 24 | 66 | |
| r244679 | r244680 | |
| 63 | 105 | * 0x0e0 in Samurai Shodown/Xrally games, 0x1c0 in all the others, zooming factor? |
| 64 | 106 | */ |
| 65 | 107 | |
| 66 | | void hng64_state::draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 108 | static void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 67 | 109 | { |
| 110 | hng64_state *state = screen.machine().driver_data<hng64_state>(); |
| 68 | 111 | gfx_element *gfx; |
| 69 | | UINT32 *source = m_spriteram; |
| 70 | | UINT32 *finish = m_spriteram + 0xc000/4; |
| 112 | UINT32 *source = state->m_spriteram; |
| 113 | UINT32 *finish = state->m_spriteram + 0xc000/4; |
| 71 | 114 | |
| 72 | 115 | // global offsets in sprite regs |
| 73 | | int spriteoffsx = (m_spriteregs[1]>>0)&0xffff; |
| 74 | | int spriteoffsy = (m_spriteregs[1]>>16)&0xffff; |
| 116 | int spriteoffsx = (state->m_spriteregs[1]>>0)&0xffff; |
| 117 | int spriteoffsy = (state->m_spriteregs[1]>>16)&0xffff; |
| 75 | 118 | |
| 76 | 119 | #if 0 |
| 77 | 120 | for (int iii = 0; iii < 0x0f; iii++) |
| 78 | | osd_printf_debug("%.8x ", m_videoregs[iii]); |
| 121 | osd_printf_debug("%.8x ", state->m_videoregs[iii]); |
| 79 | 122 | osd_printf_debug("\n"); |
| 80 | 123 | #endif |
| 81 | 124 | |
| r244679 | r244680 | |
| 139 | 182 | int zoom_factor; |
| 140 | 183 | |
| 141 | 184 | /* FIXME: regular zoom mode has precision bugs, can be easily seen in Samurai Shodown 64 intro */ |
| 142 | | zoom_factor = (m_spriteregs[0] & 0x08000000) ? 0x1000 : 0x100; |
| 185 | zoom_factor = (state->m_spriteregs[0] & 0x08000000) ? 0x1000 : 0x100; |
| 143 | 186 | if(!zoomx) zoomx=zoom_factor; |
| 144 | 187 | if(!zoomy) zoomy=zoom_factor; |
| 145 | 188 | |
| r244679 | r244680 | |
| 154 | 197 | zoomy += (int)((foomY - floor(foomY)) * (float)0x10000); |
| 155 | 198 | } |
| 156 | 199 | |
| 157 | | if (m_spriteregs[0] & 0x00800000) //bpp switch |
| 200 | if (state->m_spriteregs[0] & 0x00800000) //bpp switch |
| 158 | 201 | { |
| 159 | | gfx= m_gfxdecode->gfx(4); |
| 202 | gfx= state->m_gfxdecode->gfx(4); |
| 160 | 203 | } |
| 161 | 204 | else |
| 162 | 205 | { |
| 163 | | gfx= m_gfxdecode->gfx(5); |
| 206 | gfx= state->m_gfxdecode->gfx(5); |
| 164 | 207 | tileno>>=1; |
| 165 | 208 | pal&=0xf; |
| 166 | 209 | } |
| r244679 | r244680 | |
| 219 | 262 | tileno=(source[4]&0x0007ffff); |
| 220 | 263 | pal =(source[3]&0x00ff0000)>>16; |
| 221 | 264 | |
| 222 | | if (m_spriteregs[0] & 0x00800000) //bpp switch |
| 265 | if (state->m_spriteregs[0] & 0x00800000) //bpp switch |
| 223 | 266 | { |
| 224 | | gfx= m_gfxdecode->gfx(4); |
| 267 | gfx= state->m_gfxdecode->gfx(4); |
| 225 | 268 | } |
| 226 | 269 | else |
| 227 | 270 | { |
| 228 | | gfx= m_gfxdecode->gfx(5); |
| 271 | gfx= state->m_gfxdecode->gfx(5); |
| 229 | 272 | tileno>>=1; |
| 230 | 273 | pal&=0xf; |
| 231 | 274 | } |
| r244679 | r244680 | |
| 285 | 328 | */ |
| 286 | 329 | |
| 287 | 330 | /* this is broken for the 'How to Play' screen in Buriki after attract, disabled for now */ |
| 288 | | void hng64_state::transition_control( bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 331 | static void transition_control(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 289 | 332 | { |
| 290 | | UINT32 *hng64_tcram = m_tcram; |
| 333 | hng64_state *state = machine.driver_data<hng64_state>(); |
| 334 | UINT32 *hng64_tcram = state->m_tcram; |
| 291 | 335 | int i, j; |
| 292 | 336 | |
| 293 | 337 | // float colorScaleR, colorScaleG, colorScaleB; |
| r244679 | r244680 | |
| 504 | 548 | WRITE32_MEMBER(hng64_state::hng64_videoram_w) |
| 505 | 549 | { |
| 506 | 550 | int realoff; |
| 551 | hng64_state *state = machine().driver_data<hng64_state>(); |
| 507 | 552 | COMBINE_DATA(&m_videoram[offset]); |
| 508 | 553 | |
| 509 | 554 | realoff = offset*4; |
| 510 | 555 | |
| 511 | 556 | if ((realoff>=0) && (realoff<0x10000)) |
| 512 | 557 | { |
| 513 | | hng64_mark_tile_dirty(0, offset&0x3fff); |
| 558 | hng64_mark_tile_dirty(state, 0, offset&0x3fff); |
| 514 | 559 | } |
| 515 | 560 | else if ((realoff>=0x10000) && (realoff<0x20000)) |
| 516 | 561 | { |
| 517 | | hng64_mark_tile_dirty(1, offset&0x3fff); |
| 562 | hng64_mark_tile_dirty(state, 1, offset&0x3fff); |
| 518 | 563 | } |
| 519 | 564 | else if ((realoff>=0x20000) && (realoff<0x30000)) |
| 520 | 565 | { |
| 521 | | hng64_mark_tile_dirty(2, offset&0x3fff); |
| 566 | hng64_mark_tile_dirty(state, 2, offset&0x3fff); |
| 522 | 567 | } |
| 523 | 568 | else if ((realoff>=0x30000) && (realoff<0x40000)) |
| 524 | 569 | { |
| 525 | | hng64_mark_tile_dirty(3, offset&0x3fff); |
| 570 | hng64_mark_tile_dirty(state, 3, offset&0x3fff); |
| 526 | 571 | } |
| 527 | 572 | |
| 528 | 573 | // if ((realoff>=0x40000)) osd_printf_debug("offsw %08x %08x\n",realoff,data); |
| r244679 | r244680 | |
| 531 | 576 | } |
| 532 | 577 | |
| 533 | 578 | /* internal set of transparency states for rendering */ |
| 579 | enum hng64trans_t |
| 580 | { |
| 581 | HNG64_TILEMAP_NORMAL = 1, |
| 582 | HNG64_TILEMAP_ADDITIVE, |
| 583 | HNG64_TILEMAP_ALPHA |
| 584 | }; |
| 534 | 585 | |
| 535 | 586 | |
| 587 | struct blit_parameters |
| 588 | { |
| 589 | bitmap_rgb32 * bitmap; |
| 590 | rectangle cliprect; |
| 591 | UINT32 tilemap_priority_code; |
| 592 | UINT8 mask; |
| 593 | UINT8 value; |
| 594 | UINT8 alpha; |
| 595 | hng64trans_t drawformat; |
| 596 | }; |
| 597 | |
| 598 | |
| 599 | |
| 536 | 600 | static void hng64_configure_blit_parameters(blit_parameters *blit, tilemap_t *tmap, bitmap_rgb32 &dest, const rectangle &cliprect, UINT32 flags, UINT8 priority, UINT8 priority_mask, hng64trans_t drawformat) |
| 537 | 601 | { |
| 538 | 602 | /* start with nothing */ |
| r244679 | r244680 | |
| 609 | 673 | *(UINT32 *)dest = alpha_blend_r32(*(UINT32 *)dest, clut[INPUT_VAL], alpha); \ |
| 610 | 674 | } while (0) |
| 611 | 675 | |
| 612 | | void hng64_state::hng64_tilemap_draw_roz_core(screen_device &screen, tilemap_t *tmap, const blit_parameters *blit, |
| 676 | static void hng64_tilemap_draw_roz_core(screen_device &screen, tilemap_t *tmap, const blit_parameters *blit, |
| 613 | 677 | UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound) |
| 614 | 678 | { |
| 615 | | const pen_t *clut = &m_palette->pen(blit->tilemap_priority_code >> 16); |
| 679 | hng64_state *state = screen.machine().driver_data<hng64_state>(); |
| 680 | const pen_t *clut = &state->m_palette->pen(blit->tilemap_priority_code >> 16); |
| 616 | 681 | bitmap_ind8 &priority_bitmap = screen.priority(); |
| 617 | 682 | bitmap_rgb32 &destbitmap = *blit->bitmap; |
| 618 | 683 | bitmap_ind16 &srcbitmap = tmap->pixmap(); |
| r244679 | r244680 | |
| 786 | 851 | |
| 787 | 852 | |
| 788 | 853 | |
| 789 | | void hng64_state::hng64_tilemap_draw_roz_primask(screen_device &screen, bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, |
| 854 | static void hng64_tilemap_draw_roz_primask(screen_device &screen, bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, |
| 790 | 855 | UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, |
| 791 | 856 | int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask, hng64trans_t drawformat) |
| 792 | 857 | { |
| r244679 | r244680 | |
| 814 | 879 | } |
| 815 | 880 | |
| 816 | 881 | |
| 817 | | inline void hng64_state::hng64_tilemap_draw_roz(screen_device &screen, bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, |
| 882 | INLINE void hng64_tilemap_draw_roz(screen_device &screen, bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, |
| 818 | 883 | UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, |
| 819 | 884 | int wraparound, UINT32 flags, UINT8 priority, hng64trans_t drawformat) |
| 820 | 885 | { |
| r244679 | r244680 | |
| 823 | 888 | |
| 824 | 889 | |
| 825 | 890 | |
| 826 | | void hng64_state::hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int tm ) |
| 891 | static void hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int tm ) |
| 827 | 892 | { |
| 828 | | UINT32 *hng64_videoregs = m_videoregs; |
| 829 | | UINT32 *hng64_videoram = m_videoram; |
| 893 | hng64_state *state = screen.machine().driver_data<hng64_state>(); |
| 894 | UINT32 *hng64_videoregs = state->m_videoregs; |
| 895 | UINT32 *hng64_videoram = state->m_videoram; |
| 830 | 896 | tilemap_t* tilemap = 0; |
| 831 | 897 | UINT32 scrollbase = 0; |
| 832 | 898 | UINT32 tileregs = 0; |
| r244679 | r244680 | |
| 837 | 903 | |
| 838 | 904 | int global_dimensions = (global_tileregs&0x03000000)>>24; |
| 839 | 905 | |
| 840 | | if ( (m_additive_tilemap_debug&(1 << tm))) |
| 906 | if ( (state->m_additive_tilemap_debug&(1 << tm))) |
| 841 | 907 | debug_blend_enabled = 1; |
| 842 | 908 | |
| 843 | 909 | if ((global_dimensions != 0) && (global_dimensions != 3)) |
| r244679 | r244680 | |
| 847 | 913 | { |
| 848 | 914 | scrollbase = (hng64_videoregs[0x04]&0x3fff0000)>>16; |
| 849 | 915 | tileregs = (hng64_videoregs[0x02]&0xffff0000)>>16; |
| 916 | |
| 917 | if (global_dimensions==0) |
| 918 | { |
| 919 | if (tileregs&0x0200) tilemap = state->m_tilemap0_16x16; |
| 920 | else tilemap = state->m_tilemap0_8x8; |
| 921 | } |
| 922 | else |
| 923 | { |
| 924 | if (tileregs&0x0200) tilemap = state->m_tilemap0_16x16_alt; |
| 925 | else tilemap = state->m_tilemap0_8x8; // _alt |
| 926 | } |
| 850 | 927 | } |
| 851 | 928 | else if (tm==1) |
| 852 | 929 | { |
| 853 | 930 | scrollbase = (hng64_videoregs[0x04]&0x00003fff)>>0; |
| 854 | 931 | tileregs = (hng64_videoregs[0x02]&0x0000ffff)>>0; |
| 932 | |
| 933 | if (global_dimensions==0) |
| 934 | { |
| 935 | if (tileregs&0x0200) tilemap = state->m_tilemap1_16x16; |
| 936 | else tilemap = state->m_tilemap1_8x8; |
| 937 | } |
| 938 | else |
| 939 | { |
| 940 | if (tileregs&0x0200) tilemap = state->m_tilemap1_16x16_alt; |
| 941 | else tilemap = state->m_tilemap1_8x8; // _alt |
| 942 | } |
| 855 | 943 | } |
| 856 | 944 | else if (tm==2) |
| 857 | 945 | { |
| 858 | 946 | scrollbase = (hng64_videoregs[0x05]&0x3fff0000)>>16; |
| 859 | 947 | tileregs = (hng64_videoregs[0x03]&0xffff0000)>>16; |
| 948 | |
| 949 | if (global_dimensions==0) |
| 950 | { |
| 951 | if (tileregs&0x0200) tilemap = state->m_tilemap2_16x16; |
| 952 | else tilemap = state->m_tilemap2_8x8; |
| 953 | } |
| 954 | else |
| 955 | { |
| 956 | if (tileregs&0x0200) tilemap = state->m_tilemap2_16x16_alt; |
| 957 | else tilemap = state->m_tilemap2_8x8; // _alt |
| 958 | } |
| 860 | 959 | } |
| 861 | 960 | else if (tm==3) |
| 862 | 961 | { |
| 863 | 962 | scrollbase = (hng64_videoregs[0x05]&0x00003fff)>>0; |
| 864 | 963 | tileregs = (hng64_videoregs[0x03]&0x0000ffff)>>0; |
| 865 | | } |
| 866 | 964 | |
| 867 | | if (global_dimensions==0) |
| 868 | | { |
| 869 | | if (tileregs&0x0200) tilemap = m_tilemap[tm].m_tilemap_16x16; |
| 870 | | else tilemap = m_tilemap[tm].m_tilemap_8x8; |
| 965 | if (global_dimensions==0) |
| 966 | { |
| 967 | if (tileregs&0x0200) tilemap = state->m_tilemap3_16x16; |
| 968 | else tilemap = state->m_tilemap3_8x8; |
| 969 | } |
| 970 | else |
| 971 | { |
| 972 | if (tileregs&0x0200) tilemap = state->m_tilemap3_16x16_alt; |
| 973 | else tilemap = state->m_tilemap3_8x8; // _alt |
| 974 | } |
| 871 | 975 | } |
| 872 | | else |
| 873 | | { |
| 874 | | if (tileregs&0x0200) tilemap = m_tilemap[tm].m_tilemap_16x16_alt; |
| 875 | | else tilemap = m_tilemap[tm].m_tilemap_8x8; // _alt |
| 876 | | } |
| 877 | 976 | |
| 878 | 977 | // xrally's pink tilemaps make me think this is a tilemap enable bit. |
| 879 | 978 | // fatfurwa makes me think otherwise. |
| 880 | | // if (!(tileregs & 0x0040)) return; |
| 979 | //if (!(tileregs & 0x0040)) return; |
| 881 | 980 | |
| 882 | 981 | // set the transmask so our manual copy is correct |
| 883 | 982 | if (tileregs & 0x0400) |
| r244679 | r244680 | |
| 1027 | 1126 | bitmap_ind16 &bm = tilemap->pixmap(); |
| 1028 | 1127 | int bmheight = bm.height(); |
| 1029 | 1128 | int bmwidth = bm.width(); |
| 1030 | | const pen_t *paldata = m_palette->pens(); |
| 1129 | const pen_t *paldata = state->m_palette->pens(); |
| 1031 | 1130 | UINT32* dstptr; |
| 1032 | 1131 | UINT16* srcptr; |
| 1033 | 1132 | int xx,yy; |
| r244679 | r244680 | |
| 1123 | 1222 | bitmap_ind16 &bm = tilemap->pixmap(); |
| 1124 | 1223 | int bmheight = bm.height(); |
| 1125 | 1224 | int bmwidth = bm.width(); |
| 1126 | | const pen_t *paldata = m_palette->pens(); |
| 1225 | const pen_t *paldata = state->m_palette->pens(); |
| 1127 | 1226 | UINT32* dstptr; |
| 1128 | 1227 | UINT16* srcptr; |
| 1129 | 1228 | int xx,yy; |
| r244679 | r244680 | |
| 1212 | 1311 | // 0940 - samurai shodown 64 |
| 1213 | 1312 | // 0880 - buriki |
| 1214 | 1313 | |
| 1215 | | // mmmm dbrz zzzz zzzz |
| 1314 | // mmmm dbr? ??e? ???? |
| 1216 | 1315 | // m = mosaic related? |
| 1217 | 1316 | // -- they seem to enable mosaic at the same time as rowscroll in several cases (floor in buriki / ff) |
| 1218 | 1317 | // and also on the rotating logo in buriki.. does it cause some kind of aliasing side-effect, or.. ? |
| 1219 | 1318 | // r = tile size (seems correct) |
| 1220 | 1319 | // b = 4bpp/8bpp (seems correct) (beast busters, samsh64, sasm64 2, xrally switch it for some screens) |
| 1221 | 1320 | // d = line (floor) mode - buriki, fatafurwa, some backgrounds in ss64_2 |
| 1222 | | // z = z depth? tilemaps might also be affected by min / max clip values somewhere? (debug layer on buriki has priority 0x020, which would be highest) |
| 1321 | // e = enable according to sams64_2 debug mode, buriki and xrally.. but NOT fatal fury :-( |
| 1223 | 1322 | |
| 1224 | 1323 | |
| 1225 | 1324 | */ |
| r244679 | r244680 | |
| 1235 | 1334 | UINT32 *hng64_tcram = m_tcram; |
| 1236 | 1335 | UINT32 animmask; |
| 1237 | 1336 | UINT32 animbits; |
| 1238 | | UINT16 tileflags[4]; |
| 1337 | UINT16 tileflags0, tileflags1; |
| 1338 | UINT16 tileflags2, tileflags3; |
| 1239 | 1339 | |
| 1240 | 1340 | #if 0 |
| 1241 | 1341 | // press in sams64_2 attract mode for a nice debug screen from the game |
| r244679 | r244680 | |
| 1256 | 1356 | |
| 1257 | 1357 | animmask = hng64_videoregs[0x0b]; |
| 1258 | 1358 | animbits = hng64_videoregs[0x0c]; |
| 1259 | | tileflags[0] = hng64_videoregs[0x02]>>16; |
| 1260 | | tileflags[1] = hng64_videoregs[0x02]&0xffff; |
| 1261 | | tileflags[2] = hng64_videoregs[0x03]>>16; |
| 1262 | | tileflags[3] = hng64_videoregs[0x03]&0xffff; |
| 1359 | tileflags0 = hng64_videoregs[0x02]>>16; |
| 1360 | tileflags1 = hng64_videoregs[0x02]&0xffff; |
| 1361 | tileflags2 = hng64_videoregs[0x03]>>16; |
| 1362 | tileflags3 = hng64_videoregs[0x03]&0xffff; |
| 1263 | 1363 | |
| 1264 | 1364 | /* if the auto-animation mask or bits have changed search for tiles using them and mark as dirty */ |
| 1265 | 1365 | if ((m_old_animmask != animmask) || (m_old_animbits != animbits)) |
| r244679 | r244680 | |
| 1269 | 1369 | { |
| 1270 | 1370 | if (hng64_videoram[tile_index+(0x00000/4)]&0x200000) |
| 1271 | 1371 | { |
| 1272 | | hng64_mark_tile_dirty(0, tile_index); |
| 1372 | hng64_mark_tile_dirty(this, 0, tile_index); |
| 1273 | 1373 | } |
| 1274 | 1374 | if (hng64_videoram[tile_index+(0x10000/4)]&0x200000) |
| 1275 | 1375 | { |
| 1276 | | hng64_mark_tile_dirty(1, tile_index); |
| 1376 | hng64_mark_tile_dirty(this, 1, tile_index); |
| 1277 | 1377 | } |
| 1278 | 1378 | if (hng64_videoram[tile_index+(0x20000/4)]&0x200000) |
| 1279 | 1379 | { |
| 1280 | | hng64_mark_tile_dirty(2, tile_index); |
| 1380 | hng64_mark_tile_dirty(this, 2, tile_index); |
| 1281 | 1381 | } |
| 1282 | 1382 | if (hng64_videoram[tile_index+(0x30000/4)]&0x200000) |
| 1283 | 1383 | { |
| 1284 | | hng64_mark_tile_dirty(3, tile_index); |
| 1384 | hng64_mark_tile_dirty(this, 3, tile_index); |
| 1285 | 1385 | } |
| 1286 | 1386 | } |
| 1287 | 1387 | |
| r244679 | r244680 | |
| 1289 | 1389 | m_old_animbits = animbits; |
| 1290 | 1390 | } |
| 1291 | 1391 | |
| 1292 | | for (int i = 0; i < 4; i++) |
| 1392 | if ((m_old_tileflags0&IMPORTANT_DIRTY_TILEFLAG_MASK)!=(tileflags0&IMPORTANT_DIRTY_TILEFLAG_MASK)) |
| 1293 | 1393 | { |
| 1294 | | if ((m_old_tileflags[i]&IMPORTANT_DIRTY_TILEFLAG_MASK)!=(tileflags[i]&IMPORTANT_DIRTY_TILEFLAG_MASK)) |
| 1295 | | { |
| 1296 | | hng64_mark_all_tiles_dirty(i); |
| 1297 | | m_old_tileflags[i] = tileflags[i]; |
| 1298 | | } |
| 1394 | hng64_mark_all_tiles_dirty(this, 0); |
| 1395 | m_old_tileflags0 = tileflags0; |
| 1299 | 1396 | } |
| 1300 | 1397 | |
| 1398 | if ((m_old_tileflags1&IMPORTANT_DIRTY_TILEFLAG_MASK)!=(tileflags1&IMPORTANT_DIRTY_TILEFLAG_MASK)) |
| 1399 | { |
| 1400 | hng64_mark_all_tiles_dirty(this, 1); |
| 1401 | m_old_tileflags1 = tileflags1; |
| 1402 | } |
| 1301 | 1403 | |
| 1404 | if ((m_old_tileflags2&IMPORTANT_DIRTY_TILEFLAG_MASK)!=(tileflags2&IMPORTANT_DIRTY_TILEFLAG_MASK)) |
| 1405 | { |
| 1406 | hng64_mark_all_tiles_dirty(this, 2); |
| 1407 | m_old_tileflags2 = tileflags2; |
| 1408 | } |
| 1409 | |
| 1410 | if ((m_old_tileflags3&IMPORTANT_DIRTY_TILEFLAG_MASK)!=(tileflags3&IMPORTANT_DIRTY_TILEFLAG_MASK)) |
| 1411 | { |
| 1412 | hng64_mark_all_tiles_dirty(this, 3); |
| 1413 | m_old_tileflags3 = tileflags3; |
| 1414 | } |
| 1415 | |
| 1416 | // mark all frames as dirty if for some reason we don't trust the above code |
| 1417 | //hng64_mark_all_tiles_dirty(this, 0); |
| 1418 | //hng64_mark_all_tiles_dirty(this, 1); |
| 1419 | //hng64_mark_all_tiles_dirty(this, 2); |
| 1420 | //hng64_mark_all_tiles_dirty(this, 3); |
| 1421 | |
| 1302 | 1422 | hng64_drawtilemap(screen,bitmap,cliprect, 3); |
| 1303 | 1423 | hng64_drawtilemap(screen,bitmap,cliprect, 2); |
| 1304 | 1424 | hng64_drawtilemap(screen,bitmap,cliprect, 1); |
| r244679 | r244680 | |
| 1330 | 1450 | draw_sprites(screen, bitmap,cliprect); |
| 1331 | 1451 | |
| 1332 | 1452 | if(0) |
| 1333 | | transition_control(bitmap, cliprect); |
| 1453 | transition_control(machine(), bitmap, cliprect); |
| 1334 | 1454 | |
| 1335 | 1455 | if (0) |
| 1336 | 1456 | popmessage("%08x %08x %08x %08x %08x", m_spriteregs[0], m_spriteregs[1], m_spriteregs[2], m_spriteregs[3], m_spriteregs[4]); |
| 1337 | 1457 | |
| 1338 | | if (1) |
| 1339 | | popmessage("%08x %08x TR(%04x %04x %04x %04x) SB(%04x %04x %04x %04x) %08x %08x %08x %08x %08x AA(%08x %08x) %08x", |
| 1458 | if (0) |
| 1459 | popmessage("%08x %08x TR(%04x %04x %04x %04x) SB(%04x %04x %04x %04x) %08x %08x %08x %08x %08x AA(%08x %08x) %08x %08x", |
| 1340 | 1460 | hng64_videoregs[0x00], |
| 1341 | 1461 | hng64_videoregs[0x01], |
| 1342 | | (hng64_videoregs[0x02]>>16)&0x01ff, // ---- bits we're sure about are masked out |
| 1343 | | (hng64_videoregs[0x02]>>0)&0x01ff, // ss64_2 debug mode indicates that 0x0040 is enable! |
| 1344 | | (hng64_videoregs[0x03]>>16)&0x01ff, // buriki agrees (debug data on text layer) xrally agress (pink layer) |
| 1345 | | (hng64_videoregs[0x03]>>0)&0x01ff, // fatal fury doesn't (all backgrounds have it set) joy |
| 1462 | (hng64_videoregs[0x02]>>16)&0xf9ff, // ---- bits we're sure about are masked out |
| 1463 | (hng64_videoregs[0x02]>>0)&0xf9ff, // ss64_2 debug mode indicates that 0x0040 is enable! |
| 1464 | (hng64_videoregs[0x03]>>16)&0xf9ff, // buriki agrees (debug data on text layer) xrally agress (pink layer) |
| 1465 | (hng64_videoregs[0x03]>>0)&0xf9ff, // fatal fury doesn't (all backgrounds have it set) joy |
| 1346 | 1466 | (hng64_videoregs[0x04]>>16)&0xffff, |
| 1347 | 1467 | (hng64_videoregs[0x04]>>0)&0xffff, |
| 1348 | 1468 | (hng64_videoregs[0x05]>>16)&0xffff, |
| r244679 | r244680 | |
| 1354 | 1474 | hng64_videoregs[0x0a], |
| 1355 | 1475 | hng64_videoregs[0x0b], |
| 1356 | 1476 | hng64_videoregs[0x0c], |
| 1357 | | hng64_videoregs[0x0d]); |
| 1477 | hng64_videoregs[0x0d], |
| 1478 | hng64_videoregs[0x0e]); |
| 1358 | 1479 | |
| 1359 | 1480 | if (0) |
| 1360 | 1481 | popmessage("3D: %08x %08x %08x %08x : %08x %08x %08x %08x : %08x %08x %08x %08x", |
| r244679 | r244680 | |
| 1426 | 1547 | |
| 1427 | 1548 | m_old_animmask = -1; |
| 1428 | 1549 | m_old_animbits = -1; |
| 1429 | | m_old_tileflags[0] = -1; |
| 1430 | | m_old_tileflags[1] = -1; |
| 1431 | | m_old_tileflags[2] = -1; |
| 1432 | | m_old_tileflags[3] = -1; |
| 1550 | m_old_tileflags0 = -1; |
| 1551 | m_old_tileflags1 = -1; |
| 1552 | m_old_tileflags2 = -1; |
| 1553 | m_old_tileflags3 = -1; |
| 1433 | 1554 | |
| 1434 | | m_tilemap[0].m_tilemap_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile0_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1435 | | m_tilemap[0].m_tilemap_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile0_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1436 | | m_tilemap[0].m_tilemap_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile0_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1555 | m_tilemap0_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile0_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1556 | m_tilemap0_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile0_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1557 | m_tilemap0_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile0_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1437 | 1558 | |
| 1438 | | m_tilemap[1].m_tilemap_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile1_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1439 | | m_tilemap[1].m_tilemap_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile1_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1440 | | m_tilemap[1].m_tilemap_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile1_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1559 | m_tilemap1_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile1_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1560 | m_tilemap1_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile1_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1561 | m_tilemap1_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile1_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1441 | 1562 | |
| 1442 | | m_tilemap[2].m_tilemap_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile2_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1443 | | m_tilemap[2].m_tilemap_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile2_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1444 | | m_tilemap[2].m_tilemap_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile2_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1563 | m_tilemap2_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile2_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1564 | m_tilemap2_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile2_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1565 | m_tilemap2_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile2_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1445 | 1566 | |
| 1446 | | m_tilemap[3].m_tilemap_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile3_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1447 | | m_tilemap[3].m_tilemap_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile3_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1448 | | m_tilemap[3].m_tilemap_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile3_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1567 | m_tilemap3_8x8 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile3_8x8_info),this), TILEMAP_SCAN_ROWS, 8, 8, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1568 | m_tilemap3_16x16 = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile3_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 128, 128); /* 128x128x4 = 0x10000 */ |
| 1569 | m_tilemap3_16x16_alt = &machine().tilemap().create(m_gfxdecode, tilemap_get_info_delegate(FUNC(hng64_state::get_hng64_tile3_16x16_info),this), TILEMAP_SCAN_ROWS, 16, 16, 256, 64); /* 128x128x4 = 0x10000 */ |
| 1449 | 1570 | |
| 1450 | | for (int i = 0; i < 4; i++) |
| 1451 | | { |
| 1452 | | m_tilemap[i].m_tilemap_8x8->set_transparent_pen(0); |
| 1453 | | m_tilemap[i].m_tilemap_16x16->set_transparent_pen(0); |
| 1454 | | m_tilemap[i].m_tilemap_16x16_alt->set_transparent_pen(0); |
| 1455 | | } |
| 1571 | m_tilemap0_8x8->set_transparent_pen(0); |
| 1572 | m_tilemap0_16x16->set_transparent_pen(0); |
| 1573 | m_tilemap0_16x16_alt->set_transparent_pen(0); |
| 1456 | 1574 | |
| 1575 | m_tilemap1_8x8->set_transparent_pen(0); |
| 1576 | m_tilemap1_16x16->set_transparent_pen(0); |
| 1577 | m_tilemap1_16x16_alt->set_transparent_pen(0); |
| 1578 | |
| 1579 | m_tilemap2_8x8->set_transparent_pen(0); |
| 1580 | m_tilemap2_16x16->set_transparent_pen(0); |
| 1581 | m_tilemap2_16x16_alt->set_transparent_pen(0); |
| 1582 | |
| 1583 | m_tilemap3_8x8->set_transparent_pen(0); |
| 1584 | m_tilemap3_16x16->set_transparent_pen(0); |
| 1585 | m_tilemap3_16x16_alt->set_transparent_pen(0); |
| 1586 | |
| 1457 | 1587 | // Debug switch, turn on / off additive blending on a per-tilemap basis |
| 1458 | 1588 | m_additive_tilemap_debug = 0; |
| 1459 | 1589 | |
| r244679 | r244680 | |
| 1504 | 1634 | static void vecmatmul4(float *product, const float *a, const float *b); |
| 1505 | 1635 | static float vecDotProduct(const float *a, const float *b); |
| 1506 | 1636 | static void normalize(float* x); |
| 1637 | |
| 1507 | 1638 | static void performFrustumClip(struct polygon *p); |
| 1639 | static void drawShaded(running_machine &machine, struct polygon *p); |
| 1640 | //static void plot(running_machine &machine, INT32 x, INT32 y, UINT32 color); |
| 1641 | //static void drawline2d(running_machine &machine, INT32 x0, INT32 y0, INT32 x1, INT32 y1, UINT32 color); |
| 1642 | //static void DrawWireframe(running_machine &machine, struct polygon *p); |
| 1643 | |
| 1508 | 1644 | static float uToF(UINT16 input); |
| 1509 | 1645 | |
| 1510 | 1646 | |
| r244679 | r244680 | |
| 1542 | 1678 | |
| 1543 | 1679 | // Operation 0001 |
| 1544 | 1680 | // Camera transformation. |
| 1545 | | void hng64_state::setCameraTransformation(const UINT16* packet) |
| 1681 | static void setCameraTransformation(hng64_state *state, const UINT16* packet) |
| 1546 | 1682 | { |
| 1547 | | float *cameraMatrix = m_cameraMatrix; |
| 1683 | float *cameraMatrix = state->m_cameraMatrix; |
| 1548 | 1684 | |
| 1549 | 1685 | /*////////////// |
| 1550 | 1686 | // PACKET FORMAT |
| r244679 | r244680 | |
| 1589 | 1725 | |
| 1590 | 1726 | // Operation 0010 |
| 1591 | 1727 | // Lighting information |
| 1592 | | void hng64_state::setLighting(const UINT16* packet) |
| 1728 | static void setLighting(hng64_state *state, const UINT16* packet) |
| 1593 | 1729 | { |
| 1594 | | float *lightVector = m_lightVector; |
| 1730 | float *lightVector = state->m_lightVector; |
| 1595 | 1731 | |
| 1596 | 1732 | /*////////////// |
| 1597 | 1733 | // PACKET FORMAT |
| r244679 | r244680 | |
| 1618 | 1754 | lightVector[0] = uToF(packet[3]); |
| 1619 | 1755 | lightVector[1] = uToF(packet[4]); |
| 1620 | 1756 | lightVector[2] = uToF(packet[5]); |
| 1621 | | m_lightStrength = uToF(packet[9]); |
| 1757 | state->m_lightStrength = uToF(packet[9]); |
| 1622 | 1758 | } |
| 1623 | 1759 | |
| 1624 | 1760 | // Operation 0011 |
| 1625 | 1761 | // Palette / Model flags? |
| 1626 | | void hng64_state::set3dFlags(const UINT16* packet) |
| 1762 | static void set3dFlags(hng64_state *state, const UINT16* packet) |
| 1627 | 1763 | { |
| 1628 | 1764 | /*////////////// |
| 1629 | 1765 | // PACKET FORMAT |
| r244679 | r244680 | |
| 1644 | 1780 | // [14] - ???? ... ? '' '' |
| 1645 | 1781 | // [15] - ???? ... ? '' '' |
| 1646 | 1782 | ////////////*/ |
| 1647 | | m_paletteState3d = (packet[8] & 0xff00) >> 8; |
| 1783 | state->m_paletteState3d = (packet[8] & 0xff00) >> 8; |
| 1648 | 1784 | } |
| 1649 | 1785 | |
| 1650 | 1786 | // Operation 0012 |
| 1651 | 1787 | // Projection Matrix. |
| 1652 | | void hng64_state::setCameraProjectionMatrix(const UINT16* packet) |
| 1788 | static void setCameraProjectionMatrix(hng64_state *state, const UINT16* packet) |
| 1653 | 1789 | { |
| 1654 | | float *projectionMatrix = m_projectionMatrix; |
| 1790 | float *projectionMatrix = state->m_projectionMatrix; |
| 1655 | 1791 | |
| 1656 | 1792 | /*////////////// |
| 1657 | 1793 | // PACKET FORMAT |
| r244679 | r244680 | |
| 1707 | 1843 | |
| 1708 | 1844 | // Operation 0100 |
| 1709 | 1845 | // Polygon rasterization. |
| 1710 | | void hng64_state::recoverPolygonBlock(const UINT16* packet, struct polygon* polys, int* numPolys) |
| 1846 | static void recoverPolygonBlock(running_machine& machine, const UINT16* packet, struct polygon* polys, int* numPolys) |
| 1711 | 1847 | { |
| 1712 | 1848 | /*////////////// |
| 1713 | 1849 | // PACKET FORMAT |
| r244679 | r244680 | |
| 1744 | 1880 | // [15] - xxxx ... Transformation matrix |
| 1745 | 1881 | ////////////*/ |
| 1746 | 1882 | |
| 1883 | hng64_state *state = machine.driver_data<hng64_state>(); |
| 1747 | 1884 | UINT32 size[4]; |
| 1748 | 1885 | UINT32 address[4]; |
| 1749 | 1886 | UINT32 megaOffset; |
| r244679 | r244680 | |
| 1757 | 1894 | setIdentity(objectMatrix); |
| 1758 | 1895 | |
| 1759 | 1896 | struct polygon lastPoly = { 0 }; |
| 1760 | | const rectangle &visarea = m_screen->visible_area(); |
| 1897 | const rectangle &visarea = machine.first_screen()->visible_area(); |
| 1761 | 1898 | |
| 1762 | 1899 | ///////////////// |
| 1763 | 1900 | // HEADER INFO // |
| r244679 | r244680 | |
| 1813 | 1950 | //////////////////////////////////////////////*/ |
| 1814 | 1951 | |
| 1815 | 1952 | // 3d ROM Offset |
| 1816 | | UINT16* threeDRoms = (UINT16*)memregion("verts")->base(); |
| 1953 | UINT16* threeDRoms = (UINT16*)(machine.root_device().memregion("verts")->base()); |
| 1817 | 1954 | UINT32 threeDOffset = (((UINT32)packet[2]) << 16) | ((UINT32)packet[3]); |
| 1818 | 1955 | UINT16* threeDPointer = &threeDRoms[threeDOffset * 3]; |
| 1819 | 1956 | |
| 1820 | | if (threeDOffset >= memregion("verts")->bytes()) |
| 1957 | if (threeDOffset >= machine.root_device().memregion("verts")->bytes()) |
| 1821 | 1958 | { |
| 1822 | 1959 | printf("Strange geometry packet: (ignoring)\n"); |
| 1823 | 1960 | printPacket(packet, 1); |
| r244679 | r244680 | |
| 1942 | 2079 | /* FIXME: This isn't correct. |
| 1943 | 2080 | Buriki & Xrally need this line. Roads Edge needs it removed. |
| 1944 | 2081 | So instead we're looking for a bit that is on for XRally & Buriki, but noone else. */ |
| 1945 | | if (m_3dregs[0x00/4] & 0x2000) |
| 2082 | if (state->m_3dregs[0x00/4] & 0x2000) |
| 1946 | 2083 | { |
| 1947 | | if (strcmp(machine().basename(), "roadedge")) |
| 2084 | if (strcmp(machine.basename(), "roadedge")) |
| 1948 | 2085 | polys[*numPolys].palOffset += 0x800; |
| 1949 | 2086 | } |
| 1950 | 2087 | |
| r244679 | r244680 | |
| 1958 | 2095 | // Apply the dynamic palette offset if its flag is set, otherwise stick with the fixed one |
| 1959 | 2096 | if ((packet[1] & 0x0100)) |
| 1960 | 2097 | { |
| 1961 | | explicitPaletteValue1 = m_paletteState3d * 0x80; |
| 2098 | explicitPaletteValue1 = state->m_paletteState3d * 0x80; |
| 1962 | 2099 | explicitPaletteValue2 = 0; // This is probably hiding somewhere in operation 0011 |
| 1963 | 2100 | } |
| 1964 | 2101 | |
| r244679 | r244680 | |
| 2152 | 2289 | //////////////////////////////////// |
| 2153 | 2290 | // Perform the world transformations... |
| 2154 | 2291 | // !! Can eliminate this step with a matrix stack (maybe necessary?) !! |
| 2155 | | setIdentity(m_modelViewMatrix); |
| 2156 | | if (m_mcu_type != SAMSHO_MCU) |
| 2292 | setIdentity(state->m_modelViewMatrix); |
| 2293 | if (state->m_mcu_type != SAMSHO_MCU) |
| 2157 | 2294 | { |
| 2158 | 2295 | // The sams64 games transform the geometry in front of a stationary camera. |
| 2159 | 2296 | // This is fine in sams64_2, since it never calls the 'camera transformation' function |
| 2160 | 2297 | // (thus using the identity matrix for this transform), but sams64 calls the |
| 2161 | 2298 | // camera transformation function with rotation values. |
| 2162 | 2299 | // It remains to be seen what those might do... |
| 2163 | | matmul4(m_modelViewMatrix, m_modelViewMatrix, m_cameraMatrix); |
| 2300 | matmul4(state->m_modelViewMatrix, state->m_modelViewMatrix, state->m_cameraMatrix); |
| 2164 | 2301 | } |
| 2165 | | matmul4(m_modelViewMatrix, m_modelViewMatrix, objectMatrix); |
| 2302 | matmul4(state->m_modelViewMatrix, state->m_modelViewMatrix, objectMatrix); |
| 2166 | 2303 | |
| 2167 | 2304 | // LIGHTING |
| 2168 | | if (packet[1] & 0x0008 && m_lightStrength > 0.0f) |
| 2305 | if (packet[1] & 0x0008 && state->m_lightStrength > 0.0f) |
| 2169 | 2306 | { |
| 2170 | 2307 | for (int v = 0; v < 3; v++) |
| 2171 | 2308 | { |
| 2172 | 2309 | float transformedNormal[4]; |
| 2173 | 2310 | vecmatmul4(transformedNormal, objectMatrix, polys[*numPolys].vert[v].normal); |
| 2174 | 2311 | normalize(transformedNormal); |
| 2175 | | normalize(m_lightVector); |
| 2312 | normalize(state->m_lightVector); |
| 2176 | 2313 | |
| 2177 | | float intensity = vecDotProduct(transformedNormal, m_lightVector) * -1.0f; |
| 2314 | float intensity = vecDotProduct(transformedNormal, state->m_lightVector) * -1.0f; |
| 2178 | 2315 | intensity = (intensity <= 0.0f) ? (0.0f) : (intensity); |
| 2179 | | intensity *= m_lightStrength * 128.0f; // Turns 0x0100 into 1.0 |
| 2316 | intensity *= state->m_lightStrength * 128.0f; // Turns 0x0100 into 1.0 |
| 2180 | 2317 | intensity *= 128.0; // Maps intensity to the range [0.0, 2.0] |
| 2181 | 2318 | if (intensity >= 255.0f) intensity = 255.0f; |
| 2182 | 2319 | |
| r244679 | r244680 | |
| 2219 | 2356 | |
| 2220 | 2357 | |
| 2221 | 2358 | // BEHIND-THE-CAMERA CULL // |
| 2222 | | vecmatmul4(cullRay, m_modelViewMatrix, polys[*numPolys].vert[0].worldCoords); |
| 2359 | vecmatmul4(cullRay, state->m_modelViewMatrix, polys[*numPolys].vert[0].worldCoords); |
| 2223 | 2360 | if (cullRay[2] > 0.0f) // Camera is pointing down -Z |
| 2224 | 2361 | { |
| 2225 | 2362 | polys[*numPolys].visible = 0; |
| r244679 | r244680 | |
| 2232 | 2369 | for (int m = 0; m < polys[*numPolys].n; m++) |
| 2233 | 2370 | { |
| 2234 | 2371 | // Transform and project the vertex into pre-divided homogeneous coordinates... |
| 2235 | | vecmatmul4(eyeCoords, m_modelViewMatrix, polys[*numPolys].vert[m].worldCoords); |
| 2236 | | vecmatmul4(polys[*numPolys].vert[m].clipCoords, m_projectionMatrix, eyeCoords); |
| 2372 | vecmatmul4(eyeCoords, state->m_modelViewMatrix, polys[*numPolys].vert[m].worldCoords); |
| 2373 | vecmatmul4(polys[*numPolys].vert[m].clipCoords, state->m_projectionMatrix, eyeCoords); |
| 2237 | 2374 | } |
| 2238 | 2375 | |
| 2239 | 2376 | if (polys[*numPolys].visible) |
| r244679 | r244680 | |
| 2273 | 2410 | } |
| 2274 | 2411 | } |
| 2275 | 2412 | |
| 2276 | | void hng64_state::hng64_command3d(const UINT16* packet) |
| 2413 | void hng64_command3d(running_machine& machine, const UINT16* packet) |
| 2277 | 2414 | { |
| 2415 | hng64_state *state = machine.driver_data<hng64_state>(); |
| 2278 | 2416 | |
| 2279 | 2417 | /* A temporary place to put some polygons. This will optimize away if the compiler's any good. */ |
| 2280 | 2418 | int numPolys = 0; |
| 2281 | 2419 | dynamic_array<polygon> polys(1024*5); |
| 2282 | 2420 | |
| 2283 | | //printf("packet type : %04x %04x|%04x %04x|%04x %04x|%04x %04x | %04x %04x %04x %04x %04x %04x %04x %04x\n", packet[0],packet[1],packet[2],packet[3],packet[4],packet[5],packet[6],packet[7], packet[8], packet[9], packet[10], packet[11], packet[12], packet[13], packet[14], packet[15]); |
| 2284 | | |
| 2421 | //printf("packet type : %04x %04x|%04x %04x|%04x %04x|%04x %04x\n", packet[0],packet[1],packet[2],packet[3],packet[4],packet[5],packet[6],packet[7]); |
| 2285 | 2422 | switch (packet[0]) |
| 2286 | 2423 | { |
| 2287 | 2424 | case 0x0000: // Appears to be a NOP. |
| 2288 | 2425 | break; |
| 2289 | 2426 | |
| 2290 | 2427 | case 0x0001: // Camera transformation. |
| 2291 | | setCameraTransformation(packet); |
| 2428 | setCameraTransformation(state, packet); |
| 2292 | 2429 | break; |
| 2293 | 2430 | |
| 2294 | 2431 | case 0x0010: // Lighting information. |
| 2295 | 2432 | //if (packet[9]) printPacket(packet, 1); |
| 2296 | | setLighting(packet); |
| 2433 | setLighting(state, packet); |
| 2297 | 2434 | break; |
| 2298 | 2435 | |
| 2299 | 2436 | case 0x0011: // Palette / Model flags? |
| 2300 | 2437 | //printPacket(packet, 1); printf("\n"); |
| 2301 | | set3dFlags(packet); |
| 2438 | set3dFlags(state, packet); |
| 2302 | 2439 | break; |
| 2303 | 2440 | |
| 2304 | 2441 | case 0x0012: // Projection Matrix |
| 2305 | 2442 | //printPacket(packet, 1); |
| 2306 | | setCameraProjectionMatrix(packet); |
| 2443 | setCameraProjectionMatrix(state, packet); |
| 2307 | 2444 | break; |
| 2308 | 2445 | |
| 2309 | 2446 | case 0x0100: |
| 2310 | 2447 | case 0x0101: // Geometry with full transformations |
| 2311 | 2448 | // HACK. Masks out a piece of geo bbust2's drawShaded() crashes on. |
| 2312 | | if (packet[2] == 0x0003 && packet[3] == 0x8f37 && m_mcu_type == SHOOT_MCU) |
| 2449 | if (packet[2] == 0x0003 && packet[3] == 0x8f37 && state->m_mcu_type == SHOOT_MCU) |
| 2313 | 2450 | break; |
| 2314 | 2451 | |
| 2315 | | recoverPolygonBlock( packet, polys, &numPolys); |
| 2452 | recoverPolygonBlock(machine, packet, polys, &numPolys); |
| 2316 | 2453 | break; |
| 2317 | 2454 | |
| 2318 | 2455 | case 0x0102: // Geometry with only translation |
| r244679 | r244680 | |
| 2332 | 2469 | miniPacket[7] = 0x7fff; |
| 2333 | 2470 | miniPacket[11] = 0x7fff; |
| 2334 | 2471 | miniPacket[15] = 0x7fff; |
| 2335 | | recoverPolygonBlock( miniPacket, polys, &numPolys); |
| 2472 | recoverPolygonBlock(machine, miniPacket, polys, &numPolys); |
| 2336 | 2473 | |
| 2337 | 2474 | memset(miniPacket, 0, sizeof(UINT16)*16); |
| 2338 | 2475 | for (int i = 0; i < 7; i++) miniPacket[i] = packet[i+8]; |
| 2339 | | for (int i = 0; i < 7; i++) miniPacket[i] = packet[i+8]; |
| 2340 | 2476 | miniPacket[7] = 0x7fff; |
| 2341 | 2477 | miniPacket[11] = 0x7fff; |
| 2342 | 2478 | miniPacket[15] = 0x7fff; |
| 2343 | | recoverPolygonBlock( miniPacket, polys, &numPolys); |
| 2479 | recoverPolygonBlock(machine, miniPacket, polys, &numPolys); |
| 2344 | 2480 | break; |
| 2345 | 2481 | |
| 2346 | 2482 | case 0x1000: // Unknown: Some sort of global flags? |
| r244679 | r244680 | |
| 2361 | 2497 | { |
| 2362 | 2498 | if (polys[i].visible) |
| 2363 | 2499 | { |
| 2364 | | //DrawWireframe( &polys[i]); |
| 2365 | | drawShaded( &polys[i]); |
| 2500 | //DrawWireframe(machine, &polys[i]); |
| 2501 | drawShaded(machine, &polys[i]); |
| 2366 | 2502 | } |
| 2367 | 2503 | } |
| 2368 | 2504 | } |
| r244679 | r244680 | |
| 2648 | 2784 | // wireframe rendering // |
| 2649 | 2785 | ///////////////////////// |
| 2650 | 2786 | #ifdef UNUSED_FUNCTION |
| 2651 | | static void plot( INT32 x, INT32 y, UINT32 color) |
| 2787 | static void plot(running_machine &machine, INT32 x, INT32 y, UINT32 color) |
| 2652 | 2788 | { |
| 2653 | 2789 | UINT32* cb = &(colorBuffer3d[(y * machine.first_screen()->visible_area().max_x) + x]); |
| 2654 | 2790 | *cb = color; |
| 2655 | 2791 | } |
| 2656 | 2792 | |
| 2657 | 2793 | // Stolen from http://en.wikipedia.org/wiki/Bresenham's_line_algorithm (no copyright denoted) - the non-optimized version |
| 2658 | | static void drawline2d( INT32 x0, INT32 y0, INT32 x1, INT32 y1, UINT32 color) |
| 2794 | static void drawline2d(running_machine &machine, INT32 x0, INT32 y0, INT32 x1, INT32 y1, UINT32 color) |
| 2659 | 2795 | { |
| 2660 | 2796 | #define SWAP(a,b) tmpswap = a; a = b; b = tmpswap; |
| 2661 | 2797 | |
| r244679 | r244680 | |
| 2693 | 2829 | { |
| 2694 | 2830 | if (steep) |
| 2695 | 2831 | { |
| 2696 | | plot( x0, y0, color); |
| 2832 | plot(machine, x0, y0, color); |
| 2697 | 2833 | } |
| 2698 | 2834 | else |
| 2699 | 2835 | { |
| 2700 | | plot( y0, x0, color); |
| 2836 | plot(machine, y0, x0, color); |
| 2701 | 2837 | } |
| 2702 | 2838 | while (e >= 0) |
| 2703 | 2839 | { |
| r244679 | r244680 | |
| 2711 | 2847 | #undef SWAP |
| 2712 | 2848 | } |
| 2713 | 2849 | |
| 2714 | | static void DrawWireframe( struct polygon *p) |
| 2850 | static void DrawWireframe(running_machine &machine, struct polygon *p) |
| 2715 | 2851 | { |
| 2716 | 2852 | int j; |
| 2717 | 2853 | for (j = 0; j < p->n; j++) |
| r244679 | r244680 | |
| 2719 | 2855 | // osd_printf_debug("now drawing : %f %f %f, %f %f %f\n", p->vert[j].clipCoords[0], p->vert[j].clipCoords[1], p->vert[j].clipCoords[2], p->vert[(j+1)%p->n].clipCoords[0], p->vert[(j+1)%p->n].clipCoords[1], p->vert[(j+1)%p->n].clipCoords[2]); |
| 2720 | 2856 | // osd_printf_debug("%f %f %f %f\n", p->vert[j].clipCoords[0], p->vert[j].clipCoords[1], p->vert[(j+1)%p->n].clipCoords[0], p->vert[(j+1)%p->n].clipCoords[1]); |
| 2721 | 2857 | UINT32 color = rgb_t((UINT8)255, (UINT8)255, (UINT8)0, (UINT8)0); |
| 2722 | | drawline2d( p->vert[j].clipCoords[0], p->vert[j].clipCoords[1], p->vert[(j+1)%p->n].clipCoords[0], p->vert[(j+1)%p->n].clipCoords[1], color); |
| 2858 | drawline2d(machine, p->vert[j].clipCoords[0], p->vert[j].clipCoords[1], p->vert[(j+1)%p->n].clipCoords[0], p->vert[(j+1)%p->n].clipCoords[1], color); |
| 2723 | 2859 | } |
| 2724 | 2860 | |
| 2725 | 2861 | // SHOWS THE CLIPPING // |
| r244679 | r244680 | |
| 2734 | 2870 | } |
| 2735 | 2871 | #endif |
| 2736 | 2872 | |
| 2873 | /////////////////////// |
| 2874 | // polygon rendering // |
| 2875 | /////////////////////// |
| 2737 | 2876 | |
| 2877 | struct polygonRasterOptions |
| 2878 | { |
| 2879 | UINT8 texType; |
| 2880 | UINT8 texIndex; |
| 2881 | UINT8 texPageSmall; |
| 2882 | UINT8 texPageHorizOffset; |
| 2883 | UINT8 texPageVertOffset; |
| 2884 | int palOffset; |
| 2885 | int palPageSize; |
| 2886 | int debugColor; |
| 2887 | }; |
| 2888 | |
| 2738 | 2889 | /*********************************************************************/ |
| 2739 | 2890 | /** FillSmoothTexPCHorizontalLine **/ |
| 2740 | 2891 | /** Input: Color Buffer (framebuffer), depth buffer, width and **/ |
| r244679 | r244680 | |
| 2744 | 2895 | /** **/ |
| 2745 | 2896 | /** Output: none **/ |
| 2746 | 2897 | /*********************************************************************/ |
| 2747 | | inline void hng64_state::FillSmoothTexPCHorizontalLine( |
| 2898 | INLINE void FillSmoothTexPCHorizontalLine(running_machine &machine, |
| 2748 | 2899 | const polygonRasterOptions& prOptions, |
| 2749 | 2900 | int x_start, int x_end, int y, float z_start, float z_delta, |
| 2750 | 2901 | float w_start, float w_delta, float r_start, float r_delta, |
| 2751 | 2902 | float g_start, float g_delta, float b_start, float b_delta, |
| 2752 | 2903 | float s_start, float s_delta, float t_start, float t_delta) |
| 2753 | 2904 | { |
| 2754 | | float* db = &(m_depthBuffer3d[(y * m_screen->visible_area().max_x) + x_start]); |
| 2755 | | UINT32* cb = &(m_colorBuffer3d[(y * m_screen->visible_area().max_x) + x_start]); |
| 2905 | hng64_state *state = machine.driver_data<hng64_state>(); |
| 2906 | float* db = &(state->m_depthBuffer3d[(y * machine.first_screen()->visible_area().max_x) + x_start]); |
| 2907 | UINT32* cb = &(state->m_colorBuffer3d[(y * machine.first_screen()->visible_area().max_x) + x_start]); |
| 2756 | 2908 | |
| 2757 | 2909 | UINT8 paletteEntry = 0; |
| 2758 | 2910 | float t_coord, s_coord; |
| 2759 | | const UINT8 *gfx = memregion("textures")->base(); |
| 2911 | const UINT8 *gfx = state->memregion("textures")->base(); |
| 2760 | 2912 | const UINT8 *textureOffset = &gfx[prOptions.texIndex * 1024 * 1024]; |
| 2761 | 2913 | |
| 2762 | 2914 | for (; x_start <= x_end; x_start++) |
| r244679 | r244680 | |
| 2818 | 2970 | { |
| 2819 | 2971 | // The color out of the texture |
| 2820 | 2972 | paletteEntry %= prOptions.palPageSize; |
| 2821 | | rgb_t color = m_palette->pen(prOptions.palOffset + paletteEntry); |
| 2973 | rgb_t color = state->m_palette->pen(prOptions.palOffset + paletteEntry); |
| 2822 | 2974 | |
| 2823 | 2975 | // Apply the lighting |
| 2824 | 2976 | float rIntensity = (r_start/w_start) / 255.0f; |
| r244679 | r244680 | |
| 2886 | 3038 | // nearest and bilinear filtering: Filtering={0,1} |
| 2887 | 3039 | // replace and modulate application modes: Function={0,1} |
| 2888 | 3040 | //--------------------------------------------------------------------------- |
| 2889 | | void hng64_state::RasterizeTriangle_SMOOTH_TEX_PC( |
| 3041 | static void RasterizeTriangle_SMOOTH_TEX_PC(running_machine &machine, |
| 2890 | 3042 | float A[4], float B[4], float C[4], |
| 2891 | 3043 | float Ca[3], float Cb[3], float Cc[3], // PER-VERTEX RGB COLORS |
| 2892 | 3044 | float Ta[2], float Tb[2], float Tc[2], // PER-VERTEX (S,T) TEX-COORDS |
| r244679 | r244680 | |
| 3080 | 3232 | |
| 3081 | 3233 | // Pass the horizontal line to the filler, this could be put in the routine |
| 3082 | 3234 | // then interpolate for the next values of x and z |
| 3083 | | FillSmoothTexPCHorizontalLine( prOptions, |
| 3235 | FillSmoothTexPCHorizontalLine(machine, prOptions, |
| 3084 | 3236 | x_start, x_end, y_min, z_interp_x, z_delta_x, w_interp_x, w_delta_x, |
| 3085 | 3237 | r_interp_x, r_delta_x, g_interp_x, g_delta_x, b_interp_x, b_delta_x, |
| 3086 | 3238 | s_interp_x, s_delta_x, t_interp_x, t_delta_x); |
| r244679 | r244680 | |
| 3159 | 3311 | |
| 3160 | 3312 | // Pass the horizontal line to the filler, this could be put in the routine |
| 3161 | 3313 | // then interpolate for the next values of x and z |
| 3162 | | FillSmoothTexPCHorizontalLine( prOptions, |
| 3314 | FillSmoothTexPCHorizontalLine(machine, prOptions, |
| 3163 | 3315 | x_start, x_end, y_mid, z_interp_x, z_delta_x, w_interp_x, w_delta_x, |
| 3164 | 3316 | r_interp_x, r_delta_x, g_interp_x, g_delta_x, b_interp_x, b_delta_x, |
| 3165 | 3317 | s_interp_x, s_delta_x, t_interp_x, t_delta_x); |
| r244679 | r244680 | |
| 3174 | 3326 | } |
| 3175 | 3327 | } |
| 3176 | 3328 | |
| 3177 | | void hng64_state::drawShaded( struct polygon *p) |
| 3329 | static void drawShaded(running_machine &machine, struct polygon *p) |
| 3178 | 3330 | { |
| 3179 | 3331 | // The perspective-correct texture divide... |
| 3180 | 3332 | // !!! There is a very good chance the HNG64 hardware does not do perspective-correct texture-mapping !!! |
| r244679 | r244680 | |
| 3202 | 3354 | |
| 3203 | 3355 | for (j = 1; j < p->n-1; j++) |
| 3204 | 3356 | { |
| 3205 | | RasterizeTriangle_SMOOTH_TEX_PC( |
| 3357 | RasterizeTriangle_SMOOTH_TEX_PC(machine, |
| 3206 | 3358 | p->vert[0].clipCoords, p->vert[j].clipCoords, p->vert[j+1].clipCoords, |
| 3207 | 3359 | p->vert[0].light, p->vert[j].light, p->vert[j+1].light, |
| 3208 | 3360 | p->vert[0].texCoords, p->vert[j].texCoords, p->vert[j+1].texCoords, |
trunk/src/mess/drivers/gamate.c
| r244679 | r244680 | |
| 3 | 3 | Peter Wilhelmsen peter.wilhelmsen@gmail.com |
| 4 | 4 | Morten Shearman Kirkegaard morten+gamate@afdelingp.dk |
| 5 | 5 | Juan F??lix Mateos vectrex@hackermesh.org |
| 6 | ******************************************************************************/ |
| 6 | 7 | |
| 7 | | nmi unknown |
| 8 | | cube up audio sometimes missing |
| 9 | | bomb blast top status line missing |
| 10 | | ******************************************************************************/ |
| 11 | | |
| 12 | 8 | #include "emu.h" |
| 13 | 9 | #include "cpu/m6502/m6502.h" |
| 14 | 10 | #include "bus/generic/slot.h" |
| r244679 | r244680 | |
| 40 | 36 | DECLARE_WRITE8_MEMBER(cart_bankswitch_w); |
| 41 | 37 | DECLARE_READ8_MEMBER(gamate_video_r); |
| 42 | 38 | DECLARE_READ8_MEMBER(gamate_pad_r); |
| 43 | | DECLARE_READ8_MEMBER(gamate_nmi_r); |
| 44 | 39 | DECLARE_WRITE8_MEMBER(gamate_video_w); |
| 45 | 40 | DECLARE_READ8_MEMBER(gamate_audio_r); |
| 46 | 41 | DECLARE_WRITE8_MEMBER(gamate_audio_w); |
| r244679 | r244680 | |
| 56 | 51 | |
| 57 | 52 | struct |
| 58 | 53 | { |
| 59 | | UINT8 reg[8]; |
| 60 | | struct { |
| 61 | | bool page2; // else page1 |
| 54 | UINT8 reg[8]; |
| 55 | struct { |
| 56 | bool write; |
| 57 | bool page2; // else page1 |
| 62 | 58 | UINT8 ypos, xpos/*tennis*/; |
| 63 | | UINT8 data[2][0x100][0x20]; |
| 64 | | } bitmap; |
| 65 | | UINT8 x, y; |
| 59 | UINT8 data[2][0x100][0x20]; |
| 60 | } bitmap; |
| 61 | UINT8 x, y; |
| 66 | 62 | bool y_increment; |
| 67 | 63 | } video; |
| 68 | 64 | |
| 69 | 65 | struct { |
| 70 | | bool set; |
| 66 | bool set; |
| 71 | 67 | int bit_shifter; |
| 72 | 68 | UINT8 cartridge_byte; |
| 73 | 69 | UINT16 address; // in reality something more like short local cartridge address offset |
| 74 | 70 | bool unprotected; |
| 75 | 71 | bool failed; |
| 76 | | |
| 72 | |
| 77 | 73 | } card_protection; |
| 78 | 74 | |
| 79 | 75 | required_device<cpu_device> m_maincpu; |
| r244679 | r244680 | |
| 84 | 80 | required_shared_ptr<UINT8> m_bios; |
| 85 | 81 | emu_timer *timer1; |
| 86 | 82 | emu_timer *timer2; |
| 87 | | UINT8 bank_multi; |
| 83 | UINT8 bank_multi; |
| 88 | 84 | }; |
| 89 | 85 | |
| 90 | 86 | WRITE8_MEMBER( gamate_state::gamate_cart_protection_w ) |
| 91 | 87 | { |
| 92 | | logerror("%.6f protection write %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, data, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 93 | | |
| 88 | logerror("%.6f protection write %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, data, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 89 | |
| 94 | 90 | switch (offset) { |
| 95 | 91 | case 0: |
| 96 | 92 | card_protection.failed= card_protection.failed || ((card_protection.cartridge_byte&0x80)!=0) != ((data&4)!=0); |
| r244679 | r244680 | |
| 104 | 100 | } |
| 105 | 101 | READ8_MEMBER( gamate_state::gamate_cart_protection_r ) |
| 106 | 102 | { |
| 107 | | |
| 108 | | UINT8 ret=1; |
| 109 | | if (card_protection.bit_shifter==7 && card_protection.unprotected) { |
| 110 | | ret=m_cart->get_rom_base()[bank_multi*0x4000]; |
| 111 | | } else { |
| 103 | UINT8 ret=1; |
| 104 | if (card_protection.bit_shifter==7 && card_protection.unprotected) { |
| 105 | ret=m_cart->get_rom_base()[bank_multi*0x4000]; |
| 106 | } else { |
| 112 | 107 | card_protection.bit_shifter++; |
| 113 | 108 | if (card_protection.bit_shifter==8) { |
| 114 | 109 | card_protection.bit_shifter=0; |
| r244679 | r244680 | |
| 117 | 112 | } |
| 118 | 113 | ret=(card_protection.cartridge_byte&0x80)?2:0; |
| 119 | 114 | if (card_protection.bit_shifter==7 && !card_protection.failed) { // now protection chip on cartridge activates cartridge chip select on cpu accesses |
| 120 | | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); // next time I will try to get this working |
| 115 | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); // next time I will try to get this working |
| 121 | 116 | } |
| 122 | 117 | card_protection.cartridge_byte<<=1; |
| 123 | | } |
| 124 | | logerror("%.6f protection read %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, ret, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 125 | | return ret; |
| 118 | } |
| 119 | logerror("%.6f protection read %x %x address:%x data:%x shift:%d\n",machine().time().as_double(), offset, ret, card_protection.address, card_protection.cartridge_byte, card_protection.bit_shifter); |
| 120 | return ret; |
| 126 | 121 | } |
| 127 | 122 | |
| 128 | 123 | READ8_MEMBER( gamate_state::protection_r ) { return card_protection.set? 3: 1; } // bits 0 and 1 checked |
| 129 | 124 | |
| 130 | 125 | WRITE8_MEMBER( gamate_state::protection_reset ) |
| 131 | 126 | { |
| 132 | | // writes 0x20 |
| 133 | | card_protection.address=0x6005-0x6001; |
| 134 | | card_protection.bit_shifter=0; |
| 135 | | card_protection.cartridge_byte=m_cart->get_rom_base()[card_protection.address++];//m_cart_rom[card_protection.address++]; |
| 136 | | card_protection.failed=false; |
| 137 | | card_protection.unprotected=false; |
| 127 | // writes 0x20 |
| 128 | card_protection.address=0x6005-0x6001; |
| 129 | card_protection.bit_shifter=0; |
| 130 | card_protection.cartridge_byte=m_cart->get_rom_base()[card_protection.address++];//m_cart_rom[card_protection.address++]; |
| 131 | card_protection.failed=false; |
| 132 | card_protection.unprotected=false; |
| 138 | 133 | } |
| 139 | 134 | |
| 140 | 135 | READ8_MEMBER( gamate_state::newer_protection_set ) |
| 141 | 136 | { |
| 142 | | card_protection.set=true; |
| 143 | | return 0; |
| 137 | card_protection.set=true; |
| 138 | return 0; |
| 144 | 139 | } |
| 145 | 140 | |
| 146 | 141 | |
| 147 | 142 | WRITE8_MEMBER( gamate_state::gamate_video_w ) |
| 148 | 143 | { |
| 149 | | video.reg[offset]=data; |
| 150 | | switch (offset) { |
| 151 | | case 1: |
| 152 | | if (data&0xf) printf("lcd mode %x\n", data); |
| 153 | | video.y_increment=data&0x40; |
| 154 | | break; |
| 155 | | case 2: video.bitmap.xpos=data;break; |
| 156 | | case 3: |
| 157 | | if (data>=200) printf("lcd ypos: %x\n", data); |
| 158 | | video.bitmap.ypos=data; |
| 159 | | break; |
| 160 | | case 4: video.bitmap.page2=data&0x80;video.x=data&0x1f;break; |
| 161 | | case 5: video.y=data;break; |
| 162 | | case 7: |
| 163 | | video.bitmap.data[video.bitmap.page2][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]=data; |
| 164 | | if (video.y_increment) video.y++; |
| 165 | | else video.x++; // overruns |
| 166 | | } |
| 144 | video.reg[offset]=data; |
| 145 | switch (offset) { |
| 146 | case 1: |
| 147 | if (data&0xf) printf("lcd mode %x\n", data); |
| 148 | video.bitmap.write=data&0xc0; // more addressing mode |
| 149 | video.y_increment=data&0x40; |
| 150 | break; |
| 151 | case 2: video.bitmap.xpos=data;break; |
| 152 | case 3: |
| 153 | if (data>=200) printf("lcd ypos: %x\n", data); |
| 154 | video.bitmap.ypos=data; |
| 155 | break; |
| 156 | case 4: video.bitmap.page2=data&0x80;video.x=data&0x7f;break; |
| 157 | case 5: video.y=data;break; |
| 158 | case 7: |
| 159 | if (video.y>=200) |
| 160 | machine().ui().popup_time(2, "bitmap write to x:%x y:%x mode:%x data:%x\n", video.x, video.y, video.reg[1], data); |
| 161 | if (video.bitmap.write) { |
| 162 | video.bitmap.data[video.bitmap.page2][video.y][video.x]=data; |
| 163 | } else { |
| 164 | video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]=data; |
| 165 | } |
| 166 | if (video.y_increment) video.y++; |
| 167 | else video.x++; |
| 168 | } |
| 167 | 169 | } |
| 168 | 170 | |
| 169 | 171 | WRITE8_MEMBER( gamate_state::cart_bankswitchmulti_w ) |
| 170 | 172 | { |
| 171 | | bank_multi=data; |
| 172 | | membank("bankmulti")->set_base(m_cart->get_rom_base()+0x4000*data+1); |
| 173 | bank_multi=data; |
| 174 | membank("bankmulti")->set_base(m_cart->get_rom_base()+0x4000*data+1); |
| 173 | 175 | } |
| 174 | 176 | |
| 175 | 177 | WRITE8_MEMBER( gamate_state::cart_bankswitch_w ) |
| r244679 | r244680 | |
| 179 | 181 | |
| 180 | 182 | READ8_MEMBER( gamate_state::gamate_video_r ) |
| 181 | 183 | { |
| 182 | | if (offset!=6) return 0; |
| 183 | | UINT8 data=0; |
| 184 | | data=video.bitmap.data[video.bitmap.page2][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]; |
| 184 | if (offset!=6) return 0; |
| 185 | UINT8 data=0; |
| 186 | if (video.bitmap.write) { |
| 187 | data=video.bitmap.data[video.bitmap.page2][video.y][video.x]; |
| 188 | } else { |
| 189 | data=video.bitmap.data[0][video.y][video.x&(ARRAY_LENGTH(video.bitmap.data[0][0])-1)]; |
| 190 | } |
| 185 | 191 | // if (m_maincpu->pc()<0xf000) |
| 186 | 192 | // machine().ui().popup_time(2, "lcd read x:%x y:%x mode:%x data:%x\n", video.x, video.y, video.reg[1], data); |
| 187 | | if (video.y_increment) video.y++; |
| 188 | | else video.x++; // overruns? |
| 189 | | |
| 190 | | return data; |
| 193 | return data; |
| 191 | 194 | } |
| 192 | 195 | |
| 193 | 196 | WRITE8_MEMBER( gamate_state::gamate_audio_w ) |
| 194 | 197 | { |
| 195 | 198 | // printf("audio write %x:%x\n", offset, data);//logerror("%.6f %04x audio write %04x %02x\n",machine().time().as_double(),m_maincpu->pc(),offset,data); |
| 196 | | m_sound->device_w(space, offset, data); |
| 199 | m_sound->device_w(space, offset, data); |
| 197 | 200 | } |
| 198 | 201 | |
| 199 | 202 | READ8_MEMBER( gamate_state::gamate_audio_r ) |
| 200 | 203 | { |
| 201 | | UINT8 data=m_sound->device_r(space, offset); |
| 202 | | return data; |
| 204 | // legend of dragon knight |
| 205 | // machine().ui().popup_time(2, "%.6f %04x audio read %04x \n",machine().time().as_double(),m_maincpu->pc(),offset); |
| 206 | return 0; |
| 203 | 207 | } |
| 204 | 208 | |
| 205 | 209 | |
| 206 | 210 | READ8_MEMBER( gamate_state::gamate_pad_r ) |
| 207 | 211 | { |
| 208 | | UINT8 data=m_io_joy->read(); |
| 209 | | return data; |
| 212 | UINT8 data=m_io_joy->read(); |
| 213 | return data; |
| 210 | 214 | } |
| 211 | 215 | |
| 212 | | READ8_MEMBER( gamate_state::gamate_nmi_r ) |
| 213 | | { |
| 214 | | UINT8 data=0; |
| 215 | | machine().ui().popup_time(2, "nmi/4800 read\n"); |
| 216 | | return data; |
| 217 | | } |
| 218 | | |
| 219 | 216 | static ADDRESS_MAP_START( gamate_mem, AS_PROGRAM, 8, gamate_state ) |
| 220 | | AM_RANGE(0x0000, 0x03ff) AM_RAM |
| 221 | | AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w) |
| 222 | | AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r) |
| 223 | | AM_RANGE(0x4800, 0x4800) AM_READ(gamate_nmi_r) |
| 224 | | AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w) |
| 225 | | AM_RANGE(0x5800, 0x5800) AM_READ(newer_protection_set) |
| 226 | | AM_RANGE(0x5900, 0x5900) AM_WRITE(protection_reset) |
| 227 | | AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r) |
| 217 | AM_RANGE(0x0000, 0x03ff) AM_RAM |
| 218 | AM_RANGE(0x4000, 0x400d) AM_READWRITE(gamate_audio_r, gamate_audio_w) |
| 219 | AM_RANGE(0x4400, 0x4400) AM_READ(gamate_pad_r) |
| 220 | AM_RANGE(0x5000, 0x5007) AM_READWRITE(gamate_video_r, gamate_video_w) |
| 221 | AM_RANGE(0x5800, 0x5800) AM_READ(newer_protection_set) |
| 222 | AM_RANGE(0x5900, 0x5900) AM_WRITE(protection_reset) |
| 223 | AM_RANGE(0x5a00, 0x5a00) AM_READ(protection_r) |
| 228 | 224 | |
| 229 | | AM_RANGE(0x6001, 0x9fff) AM_READ_BANK("bankmulti") |
| 230 | | AM_RANGE(0xa000, 0xdfff) AM_READ_BANK("bank") |
| 225 | AM_RANGE(0x6001, 0x9fff) AM_READ_BANK("bankmulti") |
| 226 | AM_RANGE(0xa000, 0xdfff) AM_READ_BANK("bank") |
| 231 | 227 | |
| 232 | 228 | AM_RANGE(0x6000, 0x6000) AM_READWRITE(gamate_cart_protection_r, gamate_cart_protection_w) |
| 233 | 229 | AM_RANGE(0x8000, 0x8000) AM_WRITE(cart_bankswitchmulti_w) |
| 234 | 230 | AM_RANGE(0xc000, 0xc000) AM_WRITE(cart_bankswitch_w) |
| 235 | 231 | |
| 236 | | AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios") |
| 232 | AM_RANGE(0xf000, 0xffff) AM_ROM AM_SHARE("bios") |
| 237 | 233 | ADDRESS_MAP_END |
| 238 | 234 | |
| 239 | 235 | |
| r244679 | r244680 | |
| 249 | 245 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SELECT) PORT_NAME("Select") |
| 250 | 246 | INPUT_PORTS_END |
| 251 | 247 | |
| 252 | | static const unsigned short gamate_palette[4] = |
| 248 | ATTR_UNUSED static const unsigned short gamate_palette[4] = |
| 253 | 249 | { |
| 254 | 250 | 0,1,2,3 |
| 255 | 251 | }; |
| r244679 | r244680 | |
| 258 | 254 | /* palette in red, green, blue tribles */ |
| 259 | 255 | static const unsigned char gamate_colors[4][3] = |
| 260 | 256 | { |
| 261 | | { 255,255,255 }, |
| 262 | | { 0xa0, 0xa0, 0xa0 }, |
| 263 | | { 0x60, 0x60, 0x60 }, |
| 264 | | { 0, 0, 0 } |
| 257 | { 255,255,255 }, |
| 258 | { 0xa0, 0xa0, 0xa0 }, |
| 259 | { 0x60, 0x60, 0x60 }, |
| 260 | { 0, 0, 0 } |
| 265 | 261 | }; |
| 266 | 262 | |
| 267 | 263 | PALETTE_INIT_MEMBER(gamate_state, gamate) |
| r244679 | r244680 | |
| 284 | 280 | |
| 285 | 281 | UINT32 gamate_state::screen_update_gamate(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 286 | 282 | { |
| 287 | | int x, y, j; |
| 288 | | for (y=0;y<152;y++) { |
| 289 | | for (x=-(video.bitmap.xpos&7), j=0;x<160;x+=8, j++) { |
| 290 | | UINT8 d1, d2; |
| 291 | | if (video.bitmap.ypos<200) { |
| 283 | int x, y, j; |
| 284 | for (y=0;y<152;y++) { |
| 285 | for (x=-(video.bitmap.xpos&7), j=0;x<160;x+=8, j++) { |
| 286 | UINT8 d1, d2; |
| 287 | if (video.bitmap.ypos<200) { |
| 292 | 288 | d1=video.bitmap.data[0][(y+video.bitmap.ypos)%200][(j+video.bitmap.xpos/8)&0x1f]; |
| 293 | 289 | d2=video.bitmap.data[1][(y+video.bitmap.ypos)%200][(j+video.bitmap.xpos/8)&0x1f]; |
| 294 | | } else if ((video.bitmap.ypos&0xf)<8) { // lcdtest, of course still some registers not known, my gamate doesn't display bottom lines; most likely problematic 200 warp around hardware! no real usage |
| 290 | } else if ((video.bitmap.ypos&0xf)<8) { // lcdtest, of course still some registers not known, my gamate doesn't display bottom lines |
| 295 | 291 | int yi=(y+(video.bitmap.ypos&0xf)-8); |
| 296 | 292 | if (yi<0) yi=video.bitmap.ypos+y; // in this case only 2nd plane used!?, source of first plane? |
| 297 | 293 | d1=video.bitmap.data[0][yi][(j+video.bitmap.xpos/8)&0x1f]; // value of lines bevor 0 chaos |
| 298 | 294 | d2=video.bitmap.data[1][yi][(j+video.bitmap.xpos/8)&0x1f]; |
| 299 | | } else { |
| 295 | } else { |
| 300 | 296 | d1=video.bitmap.data[0][y][(j+video.bitmap.xpos/8)&0x1f]; |
| 301 | | d2=video.bitmap.data[1][y][(j+video.bitmap.xpos/8)&0x1f]; |
| 302 | | } |
| 303 | | BlitPlane(&bitmap.pix16(y, x+4), d1, d2); |
| 304 | | BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4); |
| 305 | | } |
| 306 | | } |
| 307 | | return 0; |
| 297 | d2=video.bitmap.data[1][y][(j+video.bitmap.xpos/8)&0x1f]; |
| 298 | } |
| 299 | BlitPlane(&bitmap.pix16(y, x+4), d1, d2); |
| 300 | BlitPlane(&bitmap.pix16(y, x), d1>>4, d2>>4); |
| 301 | } |
| 302 | } |
| 303 | return 0; |
| 308 | 304 | } |
| 309 | 305 | |
| 310 | 306 | DRIVER_INIT_MEMBER(gamate_state,gamate) |
| r244679 | r244680 | |
| 318 | 314 | void gamate_state::machine_start() |
| 319 | 315 | { |
| 320 | 316 | if (m_cart->exists()) { |
| 321 | | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); |
| 317 | // m_maincpu->space(AS_PROGRAM).install_read_handler(0x6000, 0x6000, READ8_DELEGATE(gamate_state, gamate_cart_protection_r)); |
| 322 | 318 | membank("bankmulti")->set_base(m_cart->get_rom_base()+1); |
| 323 | 319 | membank("bank")->set_base(m_cart->get_rom_base()+0x4000); // bankswitched games in reality no offset |
| 324 | 320 | } |
| 325 | | // m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // default bios: $47 protection readback |
| 321 | // m_bios[0xdf1]=0xea; m_bios[0xdf2]=0xea; // default bios: $47 protection readback |
| 326 | 322 | card_protection.set=false; |
| 327 | 323 | bank_multi=0; |
| 328 | 324 | card_protection.unprotected=false; |
| r244679 | r244680 | |
| 382 | 378 | MCFG_SOUND_ADD("custom", GAMATE_SND, 0) |
| 383 | 379 | MCFG_SOUND_ROUTE(0, "lspeaker", 0.50) |
| 384 | 380 | MCFG_SOUND_ROUTE(1, "rspeaker", 0.50) |
| 385 | | |
| 381 | |
| 386 | 382 | MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_linear_slot, "gamate_cart") |
| 387 | 383 | MCFG_GENERIC_MANDATORY |
| 388 | 384 | |
| r244679 | r244680 | |
| 400 | 396 | |
| 401 | 397 | |
| 402 | 398 | /* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */ |
| 403 | | CONS( 19??, gamate, 0, 0, gamate, gamate, gamate_state, gamate, "Bit Corp", "Gamate", 0) |
| 404 | | |
| 405 | | |
| 399 | CONS( 19??, gamate, 0, 0, gamate, gamate, gamate_state, gamate, "Bit Corp", "Gamate", GAME_IMPERFECT_SOUND) |
trunk/src/osd/sdl/video.c
| r244679 | r244680 | |
| 63 | 63 | |
| 64 | 64 | osd_video_config video_config; |
| 65 | 65 | |
| 66 | | sdl_monitor_info *sdl_monitor_info::primary_monitor = NULL; |
| 67 | | sdl_monitor_info *sdl_monitor_info::list = NULL; |
| 66 | osd_monitor_info *osd_monitor_info::list = NULL; |
| 68 | 67 | |
| 69 | 68 | //============================================================ |
| 70 | 69 | // LOCAL VARIABLES |
| r244679 | r244680 | |
| 133 | 132 | //============================================================ |
| 134 | 133 | // sdlvideo_monitor_refresh |
| 135 | 134 | //============================================================ |
| 136 | | |
| 135 | #if defined(SDLMAME_WIN32) // Win32 version |
| 136 | inline osd_rect RECT_to_osd_rect(const RECT &r) |
| 137 | { |
| 138 | return osd_rect(r.left, r.top, r.right - r.left, r.bottom - r.top); |
| 139 | } |
| 140 | #endif |
| 137 | 141 | void sdl_monitor_info::refresh() |
| 138 | 142 | { |
| 139 | 143 | #if (SDLMAME_SDL2) |
| r244679 | r244680 | |
| 144 | 148 | #else |
| 145 | 149 | SDL_GetCurrentDisplayMode(m_handle, &dmode); |
| 146 | 150 | #endif |
| 147 | | SDL_GetDisplayBounds(m_handle, &m_dimensions); |
| 151 | SDL_Rect dimensions; |
| 152 | SDL_GetDisplayBounds(m_handle, &dimensions); |
| 148 | 153 | |
| 149 | | // FIXME: Use SDL_GetDisplayBounds(monitor->handle, &tt) to update monitor_x |
| 150 | | // SDL_Rect tt; |
| 154 | m_pos_size = SDL_Rect_to_osd_rect(dimensions); |
| 155 | m_usuable_pos_size = SDL_Rect_to_osd_rect(dimensions); |
| 156 | m_is_primary = (m_handle == 0); |
| 157 | |
| 151 | 158 | #else |
| 152 | 159 | #if defined(SDLMAME_WIN32) // Win32 version |
| 153 | 160 | MONITORINFOEX info; |
| 154 | 161 | info.cbSize = sizeof(info); |
| 155 | 162 | GetMonitorInfo((HMONITOR)m_handle, (LPMONITORINFO)&info); |
| 156 | | m_dimensions.x = m_dimensions.y = 0; |
| 157 | | m_dimensions.w = info.rcMonitor.right - info.rcMonitor.left; |
| 158 | | m_dimensions.h = info.rcMonitor.bottom - info.rcMonitor.top; |
| 163 | m_pos_size = RECT_to_osd_rect(info.rcMonitor); |
| 164 | m_usuable_pos_size = RECT_to_osd_rect(info.rcWork); |
| 165 | m_is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) != 0); |
| 159 | 166 | char *temp = utf8_from_wstring(info.szDevice); |
| 160 | 167 | strncpy(m_name, temp, ARRAY_LENGTH(m_name) - 1); |
| 161 | 168 | osd_free(temp); |
| r244679 | r244680 | |
| 167 | 174 | primary = CGMainDisplayID(); |
| 168 | 175 | dbounds = CGDisplayBounds(primary); |
| 169 | 176 | |
| 170 | | m_dimensions.x = m_dimensions.y = 0; |
| 171 | | m_dimensions.w = dbounds.size.width - dbounds.origin.x; |
| 172 | | m_dimensions.h = dbounds.size.height - dbounds.origin.y; |
| 177 | m_is_primary = (m_handle == 0); |
| 178 | m_pos_size = osd_rect(0, 0, dbounds.size.width - dbounds.origin.x, dbounds.size.height - dbounds.origin.y); |
| 179 | m_usuable_pos_size = m_pos_size; |
| 173 | 180 | strncpy(m_name, "Mac OS X display", ARRAY_LENGTH(m_name) - 1); |
| 174 | 181 | #elif defined(SDLMAME_X11) || defined(SDLMAME_NO_X11) // X11 version |
| 175 | 182 | { |
| r244679 | r244680 | |
| 183 | 190 | { |
| 184 | 191 | screen = DefaultScreen(info.info.x11.display); |
| 185 | 192 | SDL_VideoDriverName(m_name, ARRAY_LENGTH(m_name) - 1); |
| 186 | | m_dimensions.x = m_dimensions.y = 0; |
| 187 | | m_dimensions.w = DisplayWidth(info.info.x11.display, screen); |
| 188 | | m_dimensions.h = DisplayHeight(info.info.x11.display, screen); |
| 193 | m_pos_size = osd_rect(0, 0, |
| 194 | DisplayWidth(info.info.x11.display, screen), |
| 195 | DisplayHeight(info.info.x11.display, screen)); |
| 189 | 196 | |
| 190 | 197 | /* FIXME: If Xinerame is used we should compile a list of monitors |
| 191 | 198 | * like we do for other targets and ignore SDL. |
| r244679 | r244680 | |
| 197 | 204 | |
| 198 | 205 | xineinfo = XineramaQueryScreens(info.info.x11.display, &numscreens); |
| 199 | 206 | |
| 200 | | m_dimensions.w = xineinfo[0].width; |
| 201 | | m_dimensions.h = xineinfo[0].height; |
| 207 | m_pos_size = osd_rect(0, 0, xineinfo[0].width, xineinfo[0].height); |
| 202 | 208 | |
| 203 | 209 | XFree(xineinfo); |
| 204 | 210 | } |
| 211 | m_usuable_pos_size = m_pos_size; |
| 212 | m_is_primary = (m_handle == 0); |
| 205 | 213 | } |
| 206 | 214 | else |
| 207 | 215 | #endif // defined(SDLMAME_X11) |
| r244679 | r244680 | |
| 238 | 246 | } |
| 239 | 247 | } |
| 240 | 248 | } |
| 241 | | m_dimensions.w = cw; |
| 242 | | m_dimensions.h = ch; |
| 249 | m_pos_size = osd_rect(0, 0, cw, ch); |
| 250 | m_usuable_pos_size = m_pos_size; |
| 251 | m_is_primary = (m_handle == 0); |
| 243 | 252 | } |
| 244 | 253 | } |
| 245 | 254 | #elif defined(SDLMAME_OS2) // OS2 version |
| 246 | | m_dimensions.x = m_dimensions.y = 0; |
| 247 | | m_dimensions.w = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ); |
| 248 | | m_dimensions.h = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ); |
| 255 | m_pos_size = osd_rect(0, 0, |
| 256 | WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ), |
| 257 | WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) ); |
| 258 | m_usuable_pos_size = m_pos_size; |
| 259 | m_is_primary = (m_handle == 0); |
| 249 | 260 | strncpy(m_name, "OS/2 display", ARRAY_LENGTH(m_name) - 1); |
| 250 | 261 | #else |
| 251 | 262 | #error Unknown SDLMAME_xx OS type! |
| r244679 | r244680 | |
| 256 | 267 | if (!info_shown) |
| 257 | 268 | { |
| 258 | 269 | osd_printf_verbose("SDL Device Driver : %s\n", m_name); |
| 259 | | osd_printf_verbose("SDL Monitor Dimensions: %d x %d\n", m_dimensions.w, m_dimensions.h); |
| 270 | osd_printf_verbose("SDL Monitor Dimensions: %d x %d\n", m_pos_size.width(), m_pos_size.height()); |
| 260 | 271 | info_shown = 1; |
| 261 | 272 | } |
| 262 | 273 | } |
| r244679 | r244680 | |
| 269 | 280 | // sdlvideo_monitor_get_aspect |
| 270 | 281 | //============================================================ |
| 271 | 282 | |
| 272 | | float sdl_monitor_info::aspect() |
| 283 | float osd_monitor_info::aspect() |
| 273 | 284 | { |
| 274 | 285 | // refresh the monitor information and compute the aspect |
| 275 | 286 | refresh(); |
| 276 | 287 | // FIXME: returning 0 looks odd, video_config is bad |
| 277 | 288 | if (video_config.keepaspect) |
| 278 | 289 | { |
| 279 | | return m_aspect / ((float)m_dimensions.w / (float)m_dimensions.h); |
| 290 | return m_aspect / ((float)m_pos_size.width() / (float)m_pos_size.height()); |
| 280 | 291 | } |
| 281 | 292 | return 0.0f; |
| 282 | 293 | } |
| r244679 | r244680 | |
| 320 | 331 | #if !defined(SDLMAME_WIN32) && !(SDLMAME_SDL2) |
| 321 | 332 | void sdl_monitor_info::add_primary_monitor(void *data) |
| 322 | 333 | { |
| 323 | | sdl_monitor_info ***tailptr = (sdl_monitor_info ***)data; |
| 324 | | sdl_monitor_info *monitor; |
| 334 | // make a list of monitors |
| 335 | osd_monitor_info::list = NULL; |
| 336 | osd_monitor_info **tailptr = &sdl_monitor_info::list; |
| 325 | 337 | |
| 326 | 338 | // allocate a new monitor info |
| 327 | | monitor = global_alloc_clear(sdl_monitor_info); |
| 339 | osd_monitor_info *monitor = global_alloc_clear(sdl_monitor_info(0, "", 1.0f)); |
| 328 | 340 | |
| 329 | | // copy in the data |
| 330 | | monitor->m_handle = 1; |
| 331 | | |
| 332 | | monitor->refresh(); |
| 333 | | |
| 341 | //monitor->refresh(); |
| 334 | 342 | // guess the aspect ratio assuming square pixels |
| 335 | | monitor->m_aspect = (float)(monitor->m_dimensions.w) / (float)(monitor->m_dimensions.h); |
| 343 | monitor->set_aspect((float)(monitor->position_size().width()) / (float)(monitor->position_size().height())); |
| 336 | 344 | |
| 337 | | // save the primary monitor handle |
| 338 | | primary_monitor = monitor; |
| 339 | | |
| 340 | 345 | // hook us into the list |
| 341 | | **tailptr = monitor; |
| 342 | | *tailptr = &monitor->m_next; |
| 346 | *tailptr = monitor; |
| 347 | //tailptr = &monitor->m_next; |
| 343 | 348 | } |
| 344 | 349 | #endif |
| 345 | 350 | |
| r244679 | r244680 | |
| 349 | 354 | //============================================================ |
| 350 | 355 | |
| 351 | 356 | #if defined(SDLMAME_WIN32) && !(SDLMAME_SDL2) |
| 352 | | static BOOL CALLBACK monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data) |
| 357 | BOOL CALLBACK sdl_monitor_info::monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data) |
| 353 | 358 | { |
| 354 | | sdl_monitor_info ***tailptr = (sdl_monitor_info ***)data; |
| 355 | | sdl_monitor_info *monitor; |
| 359 | osd_monitor_info ***tailptr = (osd_monitor_info ***)data; |
| 360 | osd_monitor_info *monitor; |
| 356 | 361 | MONITORINFOEX info; |
| 357 | 362 | BOOL result; |
| 358 | 363 | |
| r244679 | r244680 | |
| 371 | 376 | monitor = global_alloc(sdl_monitor_info((UINT64) handle, temp, aspect)); |
| 372 | 377 | osd_free(temp); |
| 373 | 378 | |
| 374 | | // save the primary monitor handle |
| 375 | | if (info.dwFlags & MONITORINFOF_PRIMARY) |
| 376 | | sdl_monitor_info::primary_monitor = monitor; |
| 377 | | |
| 378 | 379 | // hook us into the list |
| 379 | 380 | **tailptr = monitor; |
| 380 | 381 | *tailptr = &monitor->m_next; |
| r244679 | r244680 | |
| 391 | 392 | |
| 392 | 393 | void sdl_monitor_info::init() |
| 393 | 394 | { |
| 394 | | sdl_monitor_info **tailptr; |
| 395 | osd_monitor_info **tailptr; |
| 395 | 396 | |
| 396 | 397 | // make a list of monitors |
| 397 | | sdl_monitor_info::list = NULL; |
| 398 | | tailptr = &sdl_monitor_info::list; |
| 398 | osd_monitor_info::list = NULL; |
| 399 | tailptr = &osd_monitor_info::list; |
| 399 | 400 | |
| 400 | 401 | #if (SDLMAME_SDL2) |
| 401 | 402 | { |
| 402 | | int i, monx = 0; |
| 403 | int i; |
| 403 | 404 | |
| 404 | 405 | osd_printf_verbose("Enter init_monitors\n"); |
| 405 | 406 | |
| 406 | 407 | for (i = 0; i < SDL_GetNumVideoDisplays(); i++) |
| 407 | 408 | { |
| 408 | 409 | sdl_monitor_info *monitor; |
| 409 | | SDL_DisplayMode dmode; |
| 410 | 410 | |
| 411 | char temp[64]; |
| 412 | snprintf(temp, sizeof(temp)-1, "%s%d", OSDOPTION_SCREEN,i); |
| 413 | |
| 411 | 414 | // allocate a new monitor info |
| 412 | | monitor = global_alloc_clear(sdl_monitor_info); |
| 413 | | monitor->m_handle = i; |
| 414 | 415 | |
| 415 | | snprintf(monitor->m_name, sizeof(monitor->m_name)-1, "%s%d", OSDOPTION_SCREEN,i); |
| 416 | monitor = global_alloc_clear(sdl_monitor_info(i, temp, 1.0f)); |
| 416 | 417 | |
| 417 | | SDL_GetDesktopDisplayMode(i, &dmode); |
| 418 | | SDL_GetDisplayBounds(i, &monitor->m_dimensions); |
| 418 | osd_printf_verbose("Adding monitor %s (%d x %d)\n", monitor->devicename(), |
| 419 | monitor->position_size().width(), monitor->position_size().height()); |
| 419 | 420 | |
| 420 | 421 | // guess the aspect ratio assuming square pixels |
| 421 | | monitor->m_aspect = (float)(dmode.w) / (float)(dmode.h); |
| 422 | monitor->set_aspect((float)(monitor->position_size().width()) / (float)(monitor->position_size().height())); |
| 422 | 423 | |
| 423 | | osd_printf_verbose("Adding monitor %s (%d x %d)\n", monitor->m_name, dmode.w, dmode.h); |
| 424 | | |
| 425 | | monx += dmode.w; |
| 426 | | |
| 427 | | // save the primary monitor handle |
| 428 | | if (i == 0) |
| 429 | | primary_monitor = monitor; |
| 430 | | |
| 431 | 424 | // hook us into the list |
| 432 | 425 | *tailptr = monitor; |
| 433 | 426 | tailptr = &monitor->m_next; |
| r244679 | r244680 | |
| 446 | 439 | // free all of our monitor information |
| 447 | 440 | while (sdl_monitor_info::list != NULL) |
| 448 | 441 | { |
| 449 | | sdl_monitor_info *temp = sdl_monitor_info::list; |
| 442 | osd_monitor_info *temp = sdl_monitor_info::list; |
| 450 | 443 | sdl_monitor_info::list = temp->next(); |
| 451 | 444 | global_free(temp); |
| 452 | 445 | } |
| r244679 | r244680 | |
| 458 | 451 | //============================================================ |
| 459 | 452 | |
| 460 | 453 | #if (SDLMAME_SDL2) || defined(SDLMAME_WIN32) |
| 461 | | sdl_monitor_info *sdl_monitor_info::pick_monitor(sdl_options &options, int index) |
| 454 | osd_monitor_info *osd_monitor_info::pick_monitor(sdl_options &options, int index) |
| 462 | 455 | { |
| 463 | | sdl_monitor_info *monitor; |
| 456 | osd_monitor_info *monitor; |
| 464 | 457 | const char *scrname, *scrname2; |
| 465 | 458 | int moncount = 0; |
| 466 | 459 | float aspect; |
| r244679 | r244680 | |
| 494 | 487 | goto finishit; |
| 495 | 488 | |
| 496 | 489 | // return the primary just in case all else fails |
| 497 | | monitor = primary_monitor; |
| 490 | for (monitor = sdl_monitor_info::list; monitor != NULL; monitor = monitor->next()) |
| 491 | if (monitor->is_primary()) |
| 492 | goto finishit; |
| 498 | 493 | |
| 494 | // FIXME: FatalError? |
| 499 | 495 | finishit: |
| 500 | 496 | if (aspect != 0) |
| 501 | 497 | { |
| r244679 | r244680 | |
| 504 | 500 | return monitor; |
| 505 | 501 | } |
| 506 | 502 | #else |
| 507 | | sdl_monitor_info *sdl_monitor_info::pick_monitor(sdl_options &options, int index) |
| 503 | osd_monitor_info *osd_monitor_info::pick_monitor(sdl_options &options, int index) |
| 508 | 504 | { |
| 509 | | sdl_monitor_info *monitor; |
| 505 | osd_monitor_info *monitor; |
| 510 | 506 | float aspect; |
| 511 | 507 | |
| 512 | 508 | // get the aspect ratio |
| 513 | 509 | aspect = get_aspect(options.aspect(), options.aspect(index), TRUE); |
| 514 | 510 | |
| 515 | 511 | // return the primary just in case all else fails |
| 516 | | monitor = primary_monitor; |
| 512 | monitor = osd_monitor_info::list; |
| 517 | 513 | |
| 518 | 514 | if (aspect != 0) |
| 519 | 515 | { |