From cd67fd60ff207ff2570bd86548b203d029da1248 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Tue, 28 Feb 2023 18:13:33 +0000 Subject: snk/hng64_3d.ipp : Use 16-bit indexed format for 3D layer buffer. (#10941) --- src/devices/cpu/tlcs870/tlcs870.cpp | 44 ++++++ src/mame/snk/hng64.cpp | 56 +++++-- src/mame/snk/hng64.h | 20 +-- src/mame/snk/hng64_3d.ipp | 295 ++++++++++-------------------------- src/mame/snk/hng64_sprite.ipp | 25 +-- src/mame/snk/hng64_v.cpp | 87 +++++++++-- 6 files changed, 269 insertions(+), 258 deletions(-) diff --git a/src/devices/cpu/tlcs870/tlcs870.cpp b/src/devices/cpu/tlcs870/tlcs870.cpp index c010de7e03b..f23cd725952 100644 --- a/src/devices/cpu/tlcs870/tlcs870.cpp +++ b/src/devices/cpu/tlcs870/tlcs870.cpp @@ -1251,6 +1251,50 @@ void tlcs870_device::device_start() m_tcx_timer[1] = timer_alloc(FUNC(tlcs870_device::tc2_cb), this); m_tcx_timer[2] = timer_alloc(FUNC(tlcs870_device::tc3_cb), this); m_tcx_timer[3] = timer_alloc(FUNC(tlcs870_device::tc4_cb), this); + + save_item(NAME(m_prvpc)); + save_item(NAME(m_pc)); + save_item(NAME(m_sp)); + save_item(NAME(m_port_out_latch)); + save_item(NAME(m_read_input_port)); + save_item(NAME(m_port0_cr)); + save_item(NAME(m_port1_cr)); + save_item(NAME(m_port6_cr)); + save_item(NAME(m_port7_cr)); + save_item(NAME(m_cycles)); + save_item(NAME(m_tmppc)); + save_item(NAME(m_addr)); + save_item(NAME(m_F)); + save_item(NAME(m_RBS)); + save_item(NAME(m_IL)); + save_item(NAME(m_EIR)); + save_item(NAME(m_EINTCR)); + save_item(NAME(m_ADCCR)); + save_item(NAME(m_ADCDR)); + save_item(NAME(m_SYSCR1)); + save_item(NAME(m_SYSCR2)); + save_item(NAME(m_TBTCR)); + save_item(NAME(m_TREG1A)); + save_item(NAME(m_TREG1B)); + save_item(NAME(m_TC1CR)); + save_item(NAME(m_TREG2)); + save_item(NAME(m_TC2CR)); + save_item(NAME(m_TREG3A)); + save_item(NAME(m_TREG3B)); + save_item(NAME(m_TC3CR)); + save_item(NAME(m_TREG4)); + save_item(NAME(m_TC4CR)); + save_item(NAME(m_SIOCR1)); + save_item(NAME(m_SIOCR2)); + save_item(NAME(m_WDTCR1)); + save_item(NAME(m_irqstate)); + save_item(NAME(m_transfer_numbytes)); + save_item(NAME(m_transfer_pos)); + save_item(NAME(m_transfer_shiftreg)); + save_item(NAME(m_transfer_shiftpos)); + save_item(NAME(m_transfer_mode)); + save_item(NAME(m_transmit_bits)); + save_item(NAME(m_receive_bits)); } diff --git a/src/mame/snk/hng64.cpp b/src/mame/snk/hng64.cpp index 48d57fe4090..355562ed125 100644 --- a/src/mame/snk/hng64.cpp +++ b/src/mame/snk/hng64.cpp @@ -1800,13 +1800,6 @@ void hng64_state::init_hng64_reorder_gfx() void hng64_state::init_hng64() { - /* 1 meg of virtual address space for the com cpu */ - m_com_virtual_mem = std::make_unique(0x100000); - m_com_op_base = std::make_unique(0x10000); - - m_soundram = std::make_unique(0x200000/2); - m_soundram2 = std::make_unique(0x200000/2); - init_hng64_reorder_gfx(); } @@ -2113,13 +2106,20 @@ TIMER_DEVICE_CALLBACK_MEMBER(hng64_state::hng64_irq) void hng64_state::machine_start() { + /* 1 meg of virtual address space for the com cpu */ + m_com_virtual_mem = std::make_unique(0x100000); + m_com_op_base = std::make_unique(0x10000); + + m_soundram = std::make_unique(0x200000 / 2); + m_soundram2 = std::make_unique(0x200000 / 2); + /* set the fastest DRC options */ m_maincpu->mips3drc_set_options(MIPS3DRC_FASTEST_OPTIONS + MIPS3DRC_STRICT_VERIFY); /* configure fast RAM regions */ m_maincpu->add_fastram(0x00000000, 0x00ffffff, false, m_mainram); - m_maincpu->add_fastram(0x04000000, 0x05ffffff, true, m_cart); - m_maincpu->add_fastram(0x1fc00000, 0x1fc7ffff, true, m_rombase); + m_maincpu->add_fastram(0x04000000, 0x05ffffff, true, m_cart); + m_maincpu->add_fastram(0x1fc00000, 0x1fc7ffff, true, m_rombase); for (int i = 0; i < 0x38 / 4; i++) { @@ -2132,6 +2132,43 @@ void hng64_state::machine_start() m_comhack_timer = timer_alloc(FUNC(hng64_state::comhack_callback), this); init_io(); + + save_pointer(NAME(m_com_virtual_mem), 0x100000); + save_pointer(NAME(m_com_op_base), 0x10000); + save_pointer(NAME(m_soundram), 0x200000 / 2); + save_pointer(NAME(m_soundram2), 0x200000 / 2); + + save_item(NAME(m_fbcontrol)); + + save_item(NAME(m_dma_start)); + save_item(NAME(m_dma_dst)); + save_item(NAME(m_dma_len)); + + save_item(NAME(m_mcu_en)); + + save_item(NAME(m_activeDisplayList)); + save_item(NAME(m_no_machine_error_code)); + + save_item(NAME(m_unk_vreg_toggle)); + save_item(NAME(m_p1_trig)); + + save_item(NAME(m_screen_dis)); + + save_item(NAME(m_old_animmask)); + save_item(NAME(m_old_animbits)); + save_item(NAME(m_old_tileflags)); + + save_item(NAME(m_port7)); + save_item(NAME(m_port1)); + save_item(NAME(m_ex_ramaddr)); + save_item(NAME(m_ex_ramaddr_upper)); + + save_item(NAME(m_irq_pending)); + + save_item(NAME(m_irq_level)); + + save_item(NAME(main_latch)); + save_item(NAME(sound_latch)); } TIMER_CALLBACK_MEMBER(hng64_state::comhack_callback) @@ -2472,6 +2509,7 @@ void hng64_state::hng64(machine_config &config) m_screen->screen_vblank().set(FUNC(hng64_state::screen_vblank_hng64)); PALETTE(config, m_palette).set_format(palette_device::xRGB_888, 0x1000); + PALETTE(config, m_palette_3d).set_format(palette_device::xRGB_888, 0x1000 * 0x10); hng64_audio(config); hng64_network(config); diff --git a/src/mame/snk/hng64.h b/src/mame/snk/hng64.h index 58732b9cf61..2111aeee95a 100644 --- a/src/mame/snk/hng64.h +++ b/src/mame/snk/hng64.h @@ -18,7 +18,6 @@ #include "screen.h" #include "tilemap.h" - ///////////////// /// 3d Engine /// ///////////////// @@ -32,9 +31,9 @@ struct polyVert float normal[4]{}; // Normal (X Y Z 1.0) float clipCoords[4]{}; // Homogeneous screen space coordinates (X Y Z W) - float light[3]{}; // The intensity of the illumination at this point + float light; // The intensity of the illumination at this point - uint16_t colorIndex = 0; // Flat shaded polygons, no texture, no lighting + //uint16_t colorIndex = 0; // Flat shaded polygons, no texture, no lighting }; struct polygon @@ -53,8 +52,7 @@ struct polygon uint8_t texPageVertOffset = 0; // If it does use small texture pages, how far is this page vertically offset? uint32_t palOffset = 0; // The base offset where this object's palette starts. - - uint32_t debugColor = 0; // Will go away someday. Used to explicitly color polygons for debugging. + uint16_t colorIndex = 0; }; @@ -86,8 +84,8 @@ struct hng64_poly_data uint8_t texPageSmall = 0; uint8_t texPageHorizOffset = 0; uint8_t texPageVertOffset = 0; - int palOffset = 0; - int debugColor = 0; + uint32_t palOffset = 0; + uint16_t colorIndex = 0; }; class hng64_state; @@ -102,14 +100,14 @@ public: void render_flat_scanline(int32_t scanline, const extent_t& extent, const hng64_poly_data& renderData, int threadid); hng64_state& state() { return m_state; } - bitmap_rgb32& colorBuffer3d() { return m_colorBuffer3d; } + bitmap_ind16& colorBuffer3d() { return m_colorBuffer3d; } float* depthBuffer3d() { return m_depthBuffer3d.get(); } private: hng64_state& m_state; // (Temporarily class members - someday they will live in the memory map) - bitmap_rgb32 m_colorBuffer3d; + bitmap_ind16 m_colorBuffer3d; std::unique_ptr m_depthBuffer3d; }; @@ -139,6 +137,7 @@ public: driver_device(mconfig, type, tag), m_screen(*this, "screen"), m_palette(*this, "palette"), + m_palette_3d(*this, "palette3d"), m_paletteram(*this, "paletteram"), m_vblank(*this, "VBLANK"), m_maincpu(*this, "maincpu"), @@ -186,6 +185,7 @@ public: uint8_t *m_texturerom = nullptr; required_device m_screen; required_device m_palette; + required_device m_palette_3d; required_shared_ptr m_paletteram; required_ioport m_vblank; @@ -344,6 +344,7 @@ private: void dl_unk_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); uint32_t dl_vreg_r(); + void set_single_palette_entry(int entry, uint8_t r, uint8_t g, uint8_t b); void update_palette_entry(int entry); void pal_w(offs_t offset, uint32_t data, uint32_t mem_mask); void tcram_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); @@ -457,6 +458,7 @@ private: void setLighting(const uint16_t* packet); void set3dFlags(const uint16_t* packet); void setCameraProjectionMatrix(const uint16_t* packet); + void recoverStandardVerts(polygon& currentPoly, int m, uint16_t* chunkOffset_verts, int& counter); void recoverPolygonBlock(const uint16_t* packet, int& numPolys); void printPacket(const uint16_t* packet, int hex); float uToF(uint16_t input); diff --git a/src/mame/snk/hng64_3d.ipp b/src/mame/snk/hng64_3d.ipp index 9722359a5c0..e9be258b0ee 100644 --- a/src/mame/snk/hng64_3d.ipp +++ b/src/mame/snk/hng64_3d.ipp @@ -325,6 +325,23 @@ void hng64_state::setCameraProjectionMatrix(const uint16_t* packet) m_projectionMatrix[15] = 0.0f; } +void hng64_state::recoverStandardVerts(polygon& currentPoly, int m, uint16_t* chunkOffset_verts, int& counter) +{ + currentPoly.vert[m].worldCoords[0] = uToF(chunkOffset_verts[counter++]); + currentPoly.vert[m].worldCoords[1] = uToF(chunkOffset_verts[counter++]); + currentPoly.vert[m].worldCoords[2] = uToF(chunkOffset_verts[counter++]); + currentPoly.vert[m].worldCoords[3] = 1.0f; + currentPoly.n = 3; + + [[maybe_unused]] uint16_t unused = chunkOffset_verts[counter++]; // chunkOffset_verts[ xxxx+3 ] is set to 0x70 on some 'blended' objects (fatfurwa translucent globe, buriki shadows, but not on fatfurwa shadows) + + currentPoly.vert[m].texCoords[0] = uToF(chunkOffset_verts[counter]); + if (currentPoly.flatShade) + currentPoly.colorIndex = chunkOffset_verts[counter] >> 5; + counter++; + currentPoly.vert[m].texCoords[1] = uToF(chunkOffset_verts[counter++]); +} + // Operation 0100 // Polygon rasterization. void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) @@ -479,12 +496,6 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) address[2] |= (megaOffset << 16); address[3] |= (megaOffset << 16); - // Debug - ajg - //uint32_t tdColor = 0xff000000; - //if (threeDPointer[14] & 0x0002) tdColor |= 0x00ff0000; - //if (threeDPointer[14] & 0x0001) tdColor |= 0x0000ff00; - //if (threeDPointer[14] & 0x0000) tdColor |= 0x000000ff; - // For all 4 polygon chunks for (int k = 0; k < 4; k++) { @@ -526,10 +537,6 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) // Syntactical simplification polygon& currentPoly = m_polys[numPolys]; - // Debug - Colors polygons with certain flags bright blue! ajg - currentPoly.debugColor = 0; - //currentPoly.debugColor = tdColor; - // Debug - ajg //logerror("%d (%08x) : %04x %04x %04x\n", k, address[k]*3*2, chunkOffset[0], chunkOffset[1], chunkOffset[2]); //break; @@ -584,18 +591,8 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) currentPoly.palOffset += explicitPaletteValue; -#if 0 - if (((chunkOffset[2] & 0xc000) == 0x4000) && (m_screen->frame_number() & 1)) - { - // if (chunkOffset[2] == 0xd870) - { - currentPoly.debugColor = 0xffff0000; - logerror("%d (%08x) : %04x %04x %04x\n", k, address[k] * 3 * 2, chunkOffset[0], chunkOffset[1], chunkOffset[2]); - } - } -#endif - uint8_t chunkLength = 0; + int counter = 3; switch(chunkType) { /*///////////////////////// @@ -616,35 +613,26 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) // 33 word chunk, 3 vertices, per-vertex UVs & normals, per-face normal case 0x05: // 0000 0101 case 0x0f: // 0000 1111 + { for (int m = 0; m < 3; m++) { - currentPoly.vert[m].worldCoords[0] = uToF(chunkOffset[3 + (9*m)]); - currentPoly.vert[m].worldCoords[1] = uToF(chunkOffset[4 + (9*m)]); - currentPoly.vert[m].worldCoords[2] = uToF(chunkOffset[5 + (9*m)]); - currentPoly.vert[m].worldCoords[3] = 1.0f; - currentPoly.n = 3; - - // chunkOffset[6 + (9*m)] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select - currentPoly.vert[m].texCoords[0] = uToF(chunkOffset[7 + (9*m)]); - currentPoly.vert[m].texCoords[1] = uToF(chunkOffset[8 + (9*m)]); - - currentPoly.vert[m].normal[0] = uToF(chunkOffset[9 + (9*m)]); - currentPoly.vert[m].normal[1] = uToF(chunkOffset[10 + (9*m)]); - currentPoly.vert[m].normal[2] = uToF(chunkOffset[11 + (9*m)]); - currentPoly.vert[m].normal[3] = 0.0f; + recoverStandardVerts(currentPoly, m, chunkOffset, counter); - if (currentPoly.flatShade) - currentPoly.vert[m].colorIndex = chunkOffset[7 + (9*m)] >> 5; + currentPoly.vert[m].normal[0] = uToF(chunkOffset[counter++]); + currentPoly.vert[m].normal[1] = uToF(chunkOffset[counter++]); + currentPoly.vert[m].normal[2] = uToF(chunkOffset[counter++]); + currentPoly.vert[m].normal[3] = 0.0f; } // Redundantly called, but it works... - currentPoly.faceNormal[0] = uToF(chunkOffset[30]); - currentPoly.faceNormal[1] = uToF(chunkOffset[31]); - currentPoly.faceNormal[2] = uToF(chunkOffset[32]); + currentPoly.faceNormal[0] = uToF(chunkOffset[counter++]); + currentPoly.faceNormal[1] = uToF(chunkOffset[counter++]); + currentPoly.faceNormal[2] = uToF(chunkOffset[counter++]); currentPoly.faceNormal[3] = 0.0f; - chunkLength = 33; + chunkLength = counter; break; + } // 24 word chunk, 3 vertices, per-vertex UVs @@ -652,73 +640,52 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) case 0x0e: // 0000 1110 case 0x24: // 0010 0100 case 0x2e: // 0010 1110 + { for (int m = 0; m < 3; m++) { - currentPoly.vert[m].worldCoords[0] = uToF(chunkOffset[3 + (6*m)]); - currentPoly.vert[m].worldCoords[1] = uToF(chunkOffset[4 + (6*m)]); - currentPoly.vert[m].worldCoords[2] = uToF(chunkOffset[5 + (6*m)]); - currentPoly.vert[m].worldCoords[3] = 1.0f; - currentPoly.n = 3; - - // chunkOffset[6 + (6*m)] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select - currentPoly.vert[m].texCoords[0] = uToF(chunkOffset[7 + (6*m)]); - currentPoly.vert[m].texCoords[1] = uToF(chunkOffset[8 + (6*m)]); - - if (currentPoly.flatShade) - currentPoly.vert[m].colorIndex = chunkOffset[7 + (6*m)] >> 5; - - currentPoly.vert[m].normal[0] = uToF(chunkOffset[21]); - currentPoly.vert[m].normal[1] = uToF(chunkOffset[22]); - currentPoly.vert[m].normal[2] = uToF(chunkOffset[23]); - currentPoly.vert[m].normal[3] = 0.0f; + recoverStandardVerts(currentPoly, m, chunkOffset, counter); } + currentPoly.vert[0].normal[0] = currentPoly.vert[1].normal[0] = currentPoly.vert[2].normal[0] = uToF(chunkOffset[counter++]); + currentPoly.vert[0].normal[1] = currentPoly.vert[1].normal[1] = currentPoly.vert[2].normal[1] = uToF(chunkOffset[counter++]); + currentPoly.vert[0].normal[2] = currentPoly.vert[1].normal[2] = currentPoly.vert[2].normal[2] = uToF(chunkOffset[counter++]); + currentPoly.vert[0].normal[3] = currentPoly.vert[1].normal[3] = currentPoly.vert[2].normal[3] = 0.0f; + // Redundantly called, but it works... currentPoly.faceNormal[0] = currentPoly.vert[2].normal[0]; currentPoly.faceNormal[1] = currentPoly.vert[2].normal[1]; currentPoly.faceNormal[2] = currentPoly.vert[2].normal[2]; currentPoly.faceNormal[3] = 0.0f; - chunkLength = 24; + chunkLength = counter; break; - + } // 15 word chunk, 1 vertex, per-vertex UVs & normals, face normal case 0x87: // 1000 0111 case 0x97: // 1001 0111 case 0xd7: // 1101 0111 case 0xc7: // 1100 0111 + { // Copy over the proper vertices from the previous triangle... memcpy(¤tPoly.vert[1], &lastPoly.vert[0], sizeof(polyVert)); memcpy(¤tPoly.vert[2], &lastPoly.vert[2], sizeof(polyVert)); - // Fill in the appropriate data... - currentPoly.vert[0].worldCoords[0] = uToF(chunkOffset[3]); - currentPoly.vert[0].worldCoords[1] = uToF(chunkOffset[4]); - currentPoly.vert[0].worldCoords[2] = uToF(chunkOffset[5]); - currentPoly.vert[0].worldCoords[3] = 1.0f; - currentPoly.n = 3; - - // chunkOffset[6] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select - currentPoly.vert[0].texCoords[0] = uToF(chunkOffset[7]); - currentPoly.vert[0].texCoords[1] = uToF(chunkOffset[8]); + recoverStandardVerts(currentPoly, 0, chunkOffset, counter); - if (currentPoly.flatShade) - currentPoly.vert[0].colorIndex = chunkOffset[7] >> 5; - - currentPoly.vert[0].normal[0] = uToF(chunkOffset[9]); - currentPoly.vert[0].normal[1] = uToF(chunkOffset[10]); - currentPoly.vert[0].normal[2] = uToF(chunkOffset[11]); + currentPoly.vert[0].normal[0] = uToF(chunkOffset[counter++]); + currentPoly.vert[0].normal[1] = uToF(chunkOffset[counter++]); + currentPoly.vert[0].normal[2] = uToF(chunkOffset[counter++]); currentPoly.vert[0].normal[3] = 0.0f; - currentPoly.faceNormal[0] = uToF(chunkOffset[12]); - currentPoly.faceNormal[1] = uToF(chunkOffset[13]); - currentPoly.faceNormal[2] = uToF(chunkOffset[14]); + currentPoly.faceNormal[0] = uToF(chunkOffset[counter++]); + currentPoly.faceNormal[1] = uToF(chunkOffset[counter++]); + currentPoly.faceNormal[2] = uToF(chunkOffset[counter++]); currentPoly.faceNormal[3] = 0.0f; - chunkLength = 15; + chunkLength = counter; break; - + } // 12 word chunk, 1 vertex, per-vertex UVs case 0x86: // 1000 0110 @@ -726,22 +693,12 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) case 0xb6: // 1011 0110 case 0xc6: // 1100 0110 case 0xd6: // 1101 0110 + { // Copy over the proper vertices from the previous triangle... memcpy(¤tPoly.vert[1], &lastPoly.vert[0], sizeof(polyVert)); memcpy(¤tPoly.vert[2], &lastPoly.vert[2], sizeof(polyVert)); - currentPoly.vert[0].worldCoords[0] = uToF(chunkOffset[3]); - currentPoly.vert[0].worldCoords[1] = uToF(chunkOffset[4]); - currentPoly.vert[0].worldCoords[2] = uToF(chunkOffset[5]); - currentPoly.vert[0].worldCoords[3] = 1.0f; - currentPoly.n = 3; - - // chunkOffset[6] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select - currentPoly.vert[0].texCoords[0] = uToF(chunkOffset[7]); - currentPoly.vert[0].texCoords[1] = uToF(chunkOffset[8]); - - if (currentPoly.flatShade) - currentPoly.vert[0].colorIndex = chunkOffset[7] >> 5; + recoverStandardVerts(currentPoly, 0, chunkOffset, counter); // This normal could be right, but I'm not entirely sure - there is no normal in the 18 bytes! currentPoly.vert[0].normal[0] = lastPoly.faceNormal[0]; @@ -755,25 +712,17 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) currentPoly.faceNormal[3] = lastPoly.faceNormal[3]; // TODO: I'm not reading 3 necessary words here (maybe face normal) + [[maybe_unused]] uint16_t unused; + unused = chunkOffset[counter++]; + unused = chunkOffset[counter++]; + unused = chunkOffset[counter++]; -#if 0 - // DEBUG - logerror("0x?6 : %08x (%d/%d)\n", address[k]*3*2, l, size[k]-1); - for (int m = 0; m < 13; m++) - logerror("%04x ", chunkOffset[m]); - logerror("\n"); - - for (int m = 0; m < 13; m++) - logerror("%3.4f ", uToF(chunkOffset[m])); - logerror("\n\n"); -#endif - - chunkLength = 12; + chunkLength = counter; break; - + } default: logerror("UNKNOWN geometry CHUNK TYPE : %02x\n", chunkType); - chunkLength = 0; + chunkLength = counter; break; } @@ -817,9 +766,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) intensity *= 128.0; // Maps intensity to the range [0.0, 2.0] if (intensity >= 255.0f) intensity = 255.0f; - currentPoly.vert[v].light[0] = intensity; - currentPoly.vert[v].light[1] = intensity; - currentPoly.vert[v].light[2] = intensity; + currentPoly.vert[v].light = intensity; } } else @@ -827,13 +774,10 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) // Just clear out the light values for (int v = 0; v < 3; v++) { - currentPoly.vert[v].light[0] = 0; - currentPoly.vert[v].light[1] = 0; - currentPoly.vert[v].light[2] = 0; + currentPoly.vert[v].light = 0; } } - float cullRay[4]; float cullNorm[4]; @@ -883,9 +827,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) clipVerts[m].w = currentPoly.vert[m].clipCoords[3]; clipVerts[m].p[0] = currentPoly.vert[m].texCoords[0]; clipVerts[m].p[1] = currentPoly.vert[m].texCoords[1]; - clipVerts[m].p[2] = currentPoly.vert[m].light[0]; - clipVerts[m].p[3] = currentPoly.vert[m].light[1]; - clipVerts[m].p[4] = currentPoly.vert[m].light[2]; + clipVerts[m].p[2] = currentPoly.vert[m].light; } if (currentPoly.visible) @@ -903,9 +845,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) currentPoly.vert[m].clipCoords[3] = clipVerts[m].w; currentPoly.vert[m].texCoords[0] = clipVerts[m].p[0]; currentPoly.vert[m].texCoords[1] = clipVerts[m].p[1]; - currentPoly.vert[m].light[0] = clipVerts[m].p[2]; - currentPoly.vert[m].light[1] = clipVerts[m].p[3]; - currentPoly.vert[m].light[2] = clipVerts[m].p[4]; + currentPoly.vert[m].light = clipVerts[m].p[2]; } const rectangle& visarea = m_screen->visible_area(); @@ -1228,22 +1168,18 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent // Pull the parameters out of the extent structure float z = extent.param[0].start; float w = extent.param[1].start; - float lightR = extent.param[2].start; - float lightG = extent.param[3].start; - float lightB = extent.param[4].start; + float light = extent.param[2].start; float s = extent.param[5].start; float t = extent.param[6].start; const float dz = extent.param[0].dpdx; const float dw = extent.param[1].dpdx; - const float dlightR = extent.param[2].dpdx; - const float dlightG = extent.param[3].dpdx; - const float dlightB = extent.param[4].dpdx; + const float dlight = extent.param[2].dpdx; const float ds = extent.param[5].dpdx; const float dt = extent.param[6].dpdx; // Pointers to the pixel buffers - uint32_t* colorBuffer = &m_colorBuffer3d.pix(scanline, extent.startx); + uint16_t* colorBuffer = &m_colorBuffer3d.pix(scanline, extent.startx); float* depthBuffer = &m_depthBuffer3d[(scanline * m_state.m_screen->visible_area().width()) + extent.startx]; const uint8_t *textureOffset = &m_state.m_texturerom[renderData.texIndex * 1024 * 1024]; @@ -1256,26 +1192,9 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent // Multiply back through by w for everything that was interpolated perspective-correctly const float sCorrect = s / w; const float tCorrect = t / w; - const float rCorrect = lightR / w; - const float gCorrect = lightG / w; - const float bCorrect = lightB / w; - if ((renderData.debugColor & 0xff000000) == 0x01000000) - { - // ST color mode - *colorBuffer = rgb_t(255, uint8_t(sCorrect*255.0f), uint8_t(tCorrect*255.0f), uint8_t(0)); - } - else if ((renderData.debugColor & 0xff000000) == 0x02000000) - { - // Lighting only - *colorBuffer = rgb_t(255, (uint8_t)rCorrect, (uint8_t)gCorrect, (uint8_t)bCorrect); - } - else if ((renderData.debugColor & 0xff000000) == 0xff000000) - { - // Debug color mode - *colorBuffer = renderData.debugColor; - } - else + const float rCorrect = light / w; + { float textureS = 0.0f; float textureT = 0.0f; @@ -1325,28 +1244,9 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent // Naive Alpha Implementation (?) - don't draw if you're at texture index 0... if (paletteEntry != 0) { - // The color out of the texture - rgb_t color = m_state.m_palette->pen((renderData.palOffset + paletteEntry) & 0xfff); - - // Apply the lighting - float rIntensity = rCorrect / 255.0f; - float gIntensity = gCorrect / 255.0f; - float bIntensity = bCorrect / 255.0f; - float red = color.r() * rIntensity; - float green = color.g() * gIntensity; - float blue = color.b() * bIntensity; - - // Clamp and finalize - red = color.r() + red; - green = color.g() + green; - blue = color.b() + blue; - - if (red >= 255) red = 255; - if (green >= 255) green = 255; - if (blue >= 255) blue = 255; - - color = rgb_t(255, (uint8_t)red, (uint8_t)green, (uint8_t)blue); - + float rIntensity = rCorrect / 16.0f; + uint8_t lightval = (uint8_t)rIntensity; + uint16_t color = ((renderData.palOffset + paletteEntry) & 0xfff) | (lightval << 12); *colorBuffer = color; *depthBuffer = z; } @@ -1355,9 +1255,7 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent z += dz; w += dw; - lightR += dlightR; - lightG += dlightG; - lightB += dlightB; + light += dlight; s += ds; t += dt; @@ -1370,17 +1268,10 @@ void hng64_poly_renderer::render_flat_scanline(int32_t scanline, const extent_t& { // Pull the parameters out of the extent structure float z = extent.param[0].start; - float r = extent.param[1].start; - float g = extent.param[2].start; - float b = extent.param[3].start; - const float dz = extent.param[0].dpdx; - const float dr = extent.param[1].dpdx; - const float dg = extent.param[2].dpdx; - const float db = extent.param[3].dpdx; // Pointers to the pixel buffers - uint32_t* colorBuffer = &m_colorBuffer3d.pix(scanline, extent.startx); + uint16_t* colorBuffer = &m_colorBuffer3d.pix(scanline, extent.startx); float* depthBuffer = &m_depthBuffer3d[(scanline * m_state.m_screen->visible_area().width()) + extent.startx]; // Step over each pixel in the horizontal span @@ -1388,22 +1279,11 @@ void hng64_poly_renderer::render_flat_scanline(int32_t scanline, const extent_t& { if (z < *depthBuffer) { - - // Clamp and finalize - if (r >= 255) r = 255; - if (g >= 255) g = 255; - if (b >= 255) b = 255; - - rgb_t color = rgb_t(255, (uint8_t)r, (uint8_t)g, (uint8_t)b); - - *colorBuffer = color; + *colorBuffer = renderData.palOffset + renderData.colorIndex; *depthBuffer = z; } z += dz; - r += dr; - g += dg; - b += db; colorBuffer++; depthBuffer++; @@ -1417,10 +1297,10 @@ void hng64_poly_renderer::drawShaded(polygon *p) rOptions.tex4bpp = p->tex4bpp; rOptions.texIndex = p->texIndex; rOptions.palOffset = p->palOffset; - rOptions.debugColor = p->debugColor; rOptions.texPageSmall = p->texPageSmall; rOptions.texPageHorizOffset = p->texPageHorizOffset; rOptions.texPageVertOffset = p->texPageVertOffset; + rOptions.colorIndex = p->colorIndex; // Pass the render data into the rasterizer hng64_poly_data& renderData = object_data().next(); @@ -1435,34 +1315,21 @@ void hng64_poly_renderer::drawShaded(polygon *p) { // Build some MAME rasterizer vertices from the hng64 vertices vertex_t pVert[3]; - rgb_t color; const polyVert& pv0 = p->vert[0]; - color = m_state.m_palette->pen(renderData.palOffset + pv0.colorIndex); pVert[0].x = pv0.clipCoords[0]; pVert[0].y = pv0.clipCoords[1]; pVert[0].p[0] = pv0.clipCoords[2]; - pVert[0].p[1] = color.r(); - pVert[0].p[2] = color.g(); - pVert[0].p[3] = color.b(); const polyVert& pvj = p->vert[j]; - color = m_state.m_palette->pen(renderData.palOffset + pvj.colorIndex); pVert[1].x = pvj.clipCoords[0]; pVert[1].y = pvj.clipCoords[1]; pVert[1].p[0] = pvj.clipCoords[2]; - pVert[1].p[1] = color.r(); - pVert[1].p[2] = color.g(); - pVert[1].p[3] = color.b(); const polyVert& pvjp1 = p->vert[j+1]; - color = m_state.m_palette->pen(renderData.palOffset + pvjp1.colorIndex); pVert[2].x = pvjp1.clipCoords[0]; pVert[2].y = pvjp1.clipCoords[1]; pVert[2].p[0] = pvjp1.clipCoords[2]; - pVert[2].p[1] = color.r(); - pVert[2].p[2] = color.g(); - pVert[2].p[3] = color.b(); render_triangle<4>(visibleArea, render_delegate(&hng64_poly_renderer::render_flat_scanline, this), pVert[0], pVert[1], pVert[2]); } @@ -1474,9 +1341,7 @@ void hng64_poly_renderer::drawShaded(polygon *p) for (int j = 0; j < p->n; j++) { p->vert[j].clipCoords[3] = 1.0f / p->vert[j].clipCoords[3]; - p->vert[j].light[0] = p->vert[j].light[0] * p->vert[j].clipCoords[3]; - p->vert[j].light[1] = p->vert[j].light[1] * p->vert[j].clipCoords[3]; - p->vert[j].light[2] = p->vert[j].light[2] * p->vert[j].clipCoords[3]; + p->vert[j].light = p->vert[j].light * p->vert[j].clipCoords[3]; p->vert[j].texCoords[0] = p->vert[j].texCoords[0] * p->vert[j].clipCoords[3]; p->vert[j].texCoords[1] = p->vert[j].texCoords[1] * p->vert[j].clipCoords[3]; } @@ -1492,9 +1357,7 @@ void hng64_poly_renderer::drawShaded(polygon *p) pVert[0].y = pv0.clipCoords[1]; pVert[0].p[0] = pv0.clipCoords[2]; pVert[0].p[1] = pv0.clipCoords[3]; - pVert[0].p[2] = pv0.light[0]; - pVert[0].p[3] = pv0.light[1]; - pVert[0].p[4] = pv0.light[2]; + pVert[0].p[2] = pv0.light; pVert[0].p[5] = pv0.texCoords[0]; pVert[0].p[6] = pv0.texCoords[1]; @@ -1503,9 +1366,7 @@ void hng64_poly_renderer::drawShaded(polygon *p) pVert[1].y = pvj.clipCoords[1]; pVert[1].p[0] = pvj.clipCoords[2]; pVert[1].p[1] = pvj.clipCoords[3]; - pVert[1].p[2] = pvj.light[0]; - pVert[1].p[3] = pvj.light[1]; - pVert[1].p[4] = pvj.light[2]; + pVert[1].p[2] = pvj.light; pVert[1].p[5] = pvj.texCoords[0]; pVert[1].p[6] = pvj.texCoords[1]; @@ -1514,9 +1375,7 @@ void hng64_poly_renderer::drawShaded(polygon *p) pVert[2].y = pvjp1.clipCoords[1]; pVert[2].p[0] = pvjp1.clipCoords[2]; pVert[2].p[1] = pvjp1.clipCoords[3]; - pVert[2].p[2] = pvjp1.light[0]; - pVert[2].p[3] = pvjp1.light[1]; - pVert[2].p[4] = pvjp1.light[2]; + pVert[2].p[2] = pvjp1.light; pVert[2].p[5] = pvjp1.texCoords[0]; pVert[2].p[6] = pvjp1.texCoords[1]; diff --git a/src/mame/snk/hng64_sprite.ipp b/src/mame/snk/hng64_sprite.ipp index 2428a1c14fd..1d5564596b3 100644 --- a/src/mame/snk/hng64_sprite.ipp +++ b/src/mame/snk/hng64_sprite.ipp @@ -45,7 +45,7 @@ do \ { \ uint32_t srcdata = (SOURCE); \ - if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left() && ypos <= cliprect.bottom() && ypos >= cliprect.top()) \ + if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left()) \ { \ if (zval < (DESTZ)) \ { \ @@ -64,7 +64,7 @@ while (0) do \ { \ uint32_t srcdata = (SOURCE); \ - if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left() && ypos <= cliprect.bottom() && ypos >= cliprect.top()) \ + if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left()) \ { \ if (zval > (DESTZ)) \ { \ @@ -112,7 +112,7 @@ do \ } \ while (0) -void hng64_state::drawline(bitmap_ind16 & dest, bitmap_ind16 & destz, const rectangle & cliprect, +inline void hng64_state::drawline(bitmap_ind16 & dest, bitmap_ind16 & destz, const rectangle & cliprect, gfx_element * gfx, uint32_t code, uint32_t color, int flipy, int32_t xpos, int32_t dx, int32_t dy, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int32_t ypos, const u8 *srcdata, int32_t srcx, uint32_t leftovers, int curyy, uint16_t &srcpix) { @@ -146,7 +146,7 @@ void hng64_state::drawline(bitmap_ind16 & dest, bitmap_ind16 & destz, const rect } } -void hng64_state::zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const rectangle &cliprect, +inline void hng64_state::zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int32_t xpos, int32_t ypos, int32_t dx, int32_t dy, uint32_t dstwidth, uint32_t trans_pen, uint32_t zval, bool zrev, bool blend, bool checkerboard, uint8_t mosaic, uint8_t &mosaic_count_x, int curyy, uint16_t &srcpix) { @@ -196,7 +196,7 @@ void hng64_state::zoom_transpen(bitmap_ind16 &dest, bitmap_ind16 &destz, const r } -void hng64_state::get_tile_details(bool chain, uint16_t spritenum, uint8_t xtile, uint8_t ytile, uint8_t xsize, uint8_t ysize, bool xflip, bool yflip, uint32_t& tileno, uint16_t& pal, uint8_t &gfxregion) +inline void hng64_state::get_tile_details(bool chain, uint16_t spritenum, uint8_t xtile, uint8_t ytile, uint8_t xsize, uint8_t ysize, bool xflip, bool yflip, uint32_t& tileno, uint16_t& pal, uint8_t &gfxregion) { int offset; if (!xflip) @@ -357,11 +357,14 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl } } - uint32_t full_srcpix_y2 = realline * dy; - int used_ysource_pos = full_srcpix_y2 >> 16; - int ytilebbb = used_ysource_pos / 0x10; - int use_tile_line = used_ysource_pos & 0xf; - draw_sprite_line(screen, cliprect, use_tile_line, ypos, xpos, chainx, dx, dy, ytilebbb, chaini, currentsprite, chainy, xflip, yflip, zval, zsort, blend, checkerboard, mosaic); + if (ypos <= cliprect.bottom() && ypos >= cliprect.top()) + { + uint32_t full_srcpix_y2 = realline * dy; + int used_ysource_pos = full_srcpix_y2 >> 16; + int ytilebbb = used_ysource_pos / 0x10; + int use_tile_line = used_ysource_pos & 0xf; + draw_sprite_line(screen, cliprect, use_tile_line, ypos, xpos, chainx, dx, dy, ytilebbb, chaini, currentsprite, chainy, xflip, yflip, zval, zsort, blend, checkerboard, mosaic); + } ypos++; } @@ -370,7 +373,7 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl } -void hng64_state::draw_sprite_line(screen_device& screen, const rectangle& cliprect, int32_t curyy, int16_t ypos, int16_t xpos, int chainx, int32_t dx, int32_t dy, int ytileblock, int chaini, int currentsprite, int chainy, int xflip, int yflip, uint16_t zval, bool zsort, bool blend, bool checkerboard, uint8_t mosaic) +inline void hng64_state::draw_sprite_line(screen_device& screen, const rectangle& cliprect, int32_t curyy, int16_t ypos, int16_t xpos, int chainx, int32_t dx, int32_t dy, int ytileblock, int chaini, int currentsprite, int chainy, int xflip, int yflip, uint16_t zval, bool zsort, bool blend, bool checkerboard, uint8_t mosaic) { uint32_t srcpix_x = 0; uint16_t srcpix = 0; diff --git a/src/mame/snk/hng64_v.cpp b/src/mame/snk/hng64_v.cpp index 5368ee9e6cf..9d6c123c31a 100644 --- a/src/mame/snk/hng64_v.cpp +++ b/src/mame/snk/hng64_v.cpp @@ -801,19 +801,34 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b } } + /* + Each framebuffer has enough RAM for 24 bits of data for a 512x256 + layer (screen is interlaced, so it doesn't really have 448 pixels + in height) + + theory: 11 bit palette index (can use either half of palette) + 1 bit 'blend' + 4 bit 'light' + 8 bit depth? + */ + // 3d gets drawn next + pen_t const *const clut_3d = &m_palette_3d->pen(0); if (!(m_fbcontrol[0] & 0x01)) { // Blit the color buffer into the primary bitmap for (int y = cliprect.min_y; y <= cliprect.max_y; y++) { - const uint32_t *src = &m_poly_renderer->colorBuffer3d().pix(y, cliprect.min_x); + const uint16_t *src = &m_poly_renderer->colorBuffer3d().pix(y, cliprect.min_x); uint32_t *dst = &bitmap.pix(y, cliprect.min_x); for (int x = cliprect.min_x; x <= cliprect.max_x; x++) { - if (*src & 0xff000000) - *dst = *src; + uint16_t srcpix = *src; + if (srcpix & 0x0fff) + { + *dst = clut_3d[srcpix]; + } dst++; src++; @@ -825,6 +840,18 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b draw_sprites_buffer(screen, cliprect); // copy sprites into display + + // this correctly allows buriki intro sprites to use regular alpha, not additive + // while also being correct for sams64, which wants additive, but appears to be + // incorrect for Fatal Fury's hit effects which want additive + // + // the 6 regs around here have the same values in fatfur and buriki, so are unlikely + // to control the blend type. + //uint8_t spriteblendtype = (m_tcram[0x10 / 4] >> 16) & 0x10; + + // would be an odd place for it, after the 'vblank' flag but... + uint8_t spriteblendtype = (m_tcram[0x4c / 4] >> 16) & 0x01; + pen_t const *const clut = &m_palette->pen(0); for (int y = cliprect.min_y; y <= cliprect.max_y; y++) { @@ -838,7 +865,10 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b { if (srcpix & 0x8000) { - *dst = add_blend_r32(*dst, clut[srcpix & 0x7fff]); + if (spriteblendtype) + *dst = alpha_blend_r32(*(uint32_t *)dst, clut[srcpix & 0x7fff], 0x80); + else + *dst = add_blend_r32(*dst, clut[srcpix & 0x7fff]); } else { @@ -876,17 +906,19 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b m_videoregs[0x0d]); if (1) - popmessage("TC: %08x MINX(%d) MINY(%d) MAXX(%d) MAXY(%d)\nBLEND ENABLES? %02x %02x %02x | %02x %02x %02x\nUNUSED?(%04x)\n%04x\n%04x\nMASTER FADES?(%08x %08x)\nUNUSED?(%08x)\nBITFIELD REGS(%04x)\nPALEFFECT_ENABLES(%d %d %d %d %d %d %d %d)\n PALFADES?(%08x %08x : %08x %08x : %08x %08x : %08x %08x)\n % 08x % 08x : % 08x % 08x % 08x % 08x", + popmessage("TC: %08x MINX(%d) MINY(%d) MAXX(%d) MAXY(%d)\nBLEND ENABLES? %02x %02x %02x | %02x %02x %02x\nUNUSED?(%04x)\n%04x\n%04x\nMASTER FADES - ADD?(%08x) - SUBTRACT?(%08x)\nUNUSED?(%08x)\nBITFIELD REGS(%04x)\nPALEFFECT_ENABLES(%d %d %d %d %d %d %d %d)\n PALFADES?(%08x %08x : %08x %08x : %08x %08x : %08x %08x)\n % 08x % 08x : % 08x % 08x % 08x % 08x", m_tcram[0x00 / 4], // 0007 00e4 (fatfurwa, bbust2) (m_tcram[0x04 / 4] >> 16) & 0xffff, (m_tcram[0x04 / 4] >> 0) & 0xffff, // 0000 0010 (fatfurwa) 0000 0000 (bbust2, xrally) (m_tcram[0x08 / 4] >> 16) & 0xffff, (m_tcram[0x08 / 4] >> 0) & 0xffff, // 0200 01b0 (fatfurwa) 0200 01c0 (bbust2, xrally) + // is this 2 groups of 3 regS? (m_tcram[0x0c / 4] >> 24) & 0xff, // 04 = 'blend' on tm1 - (m_tcram[0x0c / 4] >> 16) & 0xff, // 04 = blend all sprites? (buriki intro, text fades?) - (m_tcram[0x0c / 4] >> 8) & 0xff, + (m_tcram[0x0c / 4] >> 16) & 0xff, // 04 = set when fades are going on with blended sprites in buriki intro? otherwise usually 00 + (m_tcram[0x0c / 4] >> 8) & 0xff, // upper bit not used? value usually 2x, 4x, 5x or 6x + // 2nd group? (m_tcram[0x0c / 4] >> 0) & 0xff, // 04 = 'blend' on tm3 (used in transitions?) - (m_tcram[0x10 / 4] >> 24) & 0xff, - (m_tcram[0x10 / 4] >> 16) & 0xff, + (m_tcram[0x10 / 4] >> 24) & 0xff, // usually (always?) 00 + (m_tcram[0x10 / 4] >> 16) & 0xff, // upper bit not used? value usually 2x, 4x, 5x or 6x m_tcram[0x10 / 4] & 0xffff, // unused? @@ -928,7 +960,7 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b m_tcram[0x48 / 4], // this is where the 'vblank' thing lives - m_tcram[0x4c / 4], + m_tcram[0x4c / 4], // 0001 0000 or 0000 0000 - works(?) as blend type selection for sprite mixing? m_tcram[0x50 / 4], m_tcram[0x54 / 4], m_tcram[0x58 / 4], @@ -1010,6 +1042,33 @@ WRITE_LINE_MEMBER(hng64_state::screen_vblank_hng64) * Or maybe they set transition type (there seems to be a cute scaling-squares transition in there somewhere)... */ +inline void hng64_state::set_single_palette_entry(int entry, uint8_t r, uint8_t g, uint8_t b) +{ + m_palette->set_pen_color(entry, r, g, b); + + // our code assumes the 'lighting' values from the 3D framebuffer can be 4-bit precision + // based on 'banding' seen in buriki reference videos. precalculate those here to avoid + // having to do it in the video update function + // + // note, it is unlikely intensity is meant to be added, probably instead it should + // be multipled, reducing overall brightness, not increasing beyond max? + for (int intensity = 0; intensity < 0x10; intensity++) + { + uint16_t newr = r + (intensity << 2); + uint16_t newg = g + (intensity << 2); + uint16_t newb = b + (intensity << 2); + + if (newr > 255) + newr = 255; + if (newg > 255) + newg = 255; + if (newb > 255) + newb = 255; + + m_palette_3d->set_pen_color((intensity * 0x1000) + entry, newr, newg, newb); + } +} + void hng64_state::update_palette_entry(int entry) { uint32_t data = m_paletteram[entry]; @@ -1021,6 +1080,12 @@ void hng64_state::update_palette_entry(int entry) for (int i = 0; i < 8; i++) { uint32_t tcdata = m_tcram[(0x28 / 4) + i]; + + // correct for buriki (jumbotron fading images) and xrally / roadedge (palette effect on front of car in first person view) + // + // however this logic fails on fatal fury fades, as the msb is 00, indicating apply to palette entries 000-0ff but the actual + // palette needing the changes is 0x900 - 0x9ff (hng64 logo white flash) so there must be further ways in which this is + // configured uint8_t tcregion = (tcdata & 0x0f000000) >> 24; if (tcregion == (entry >> 8)) @@ -1062,7 +1127,7 @@ void hng64_state::update_palette_entry(int entry) } } - m_palette->set_pen_color(entry, r,g,b); + set_single_palette_entry(entry, r, g, b); } void hng64_state::pal_w(offs_t offset, uint32_t data, uint32_t mem_mask) -- cgit v1.2.3