trunk/src/mame/video/hng64.c
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | } |
| r244677 | r244678 | |
| 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 | } |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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); |
| r244677 | r244678 | |
| 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 */ |
| r244677 | r244678 | |
| 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(); |
| r244677 | r244678 | |
| 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 | { |
| r244677 | r244678 | |
| 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 | { |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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)) |
| r244677 | r244678 | |
| 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) |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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 | */ |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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)) |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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); |
| r244677 | r244678 | |
| 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, |
| r244677 | r244678 | |
| 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", |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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 // |
| r244677 | r244678 | |
| 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); |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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) |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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? |
| r244677 | r244678 | |
| 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 | } |
| r244677 | r244678 | |
| 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 | |
| r244677 | r244678 | |
| 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 | { |
| r244677 | r244678 | |
| 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++) |
| r244677 | r244678 | |
| 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 // |
| r244677 | r244678 | |
| 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 **/ |
| r244677 | r244678 | |
| 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++) |
| r244677 | r244678 | |
| 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; |
| r244677 | r244678 | |
| 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 |
| r244677 | r244678 | |
| 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); |
| r244677 | r244678 | |
| 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); |
| r244677 | r244678 | |
| 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 !!! |
| r244677 | r244678 | |
| 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, |