From f9de654f5992bbdd6ca0cacf9c5ed242b19313a9 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Wed, 15 Mar 2023 16:46:08 +0000 Subject: snk/hng64.cpp: Improved rendering: (#10990) * Fixed roadedge name entry screen. * Render sprites before mixing. * Fixed texture scroll (visible on roadedge billboards). * Added safety checks on texture fetches. --- src/mame/snk/hng64.cpp | 49 +++++++++---------------------------------- src/mame/snk/hng64.h | 9 ++------ src/mame/snk/hng64_3d.ipp | 39 +++++++++++++++++++--------------- src/mame/snk/hng64_sprite.ipp | 15 ++++++++++++- src/mame/snk/hng64_v.cpp | 9 +++----- 5 files changed, 51 insertions(+), 70 deletions(-) diff --git a/src/mame/snk/hng64.cpp b/src/mame/snk/hng64.cpp index 34d2715bdbc..139700fe6fe 100644 --- a/src/mame/snk/hng64.cpp +++ b/src/mame/snk/hng64.cpp @@ -29,40 +29,6 @@ Notes: * The Japanese text on the Roads Edge network screen says : "waiting to connect network... please wait without touching machine" - * Xrally and Roads Edge have a symbols table at respectively 0xb2f30 and 0xe10c0 - -ToDo: - * Sprite garbage in Beast Busters: Second Nightmare, another irq issue? - * Samurai Shodown 64 2 puts "Press 1p & 2p button" msg in gameplay, known to be a MCU simulation issue, i/o port 4 doesn't - seem to be just an input port but controls program flow too. - * Work out the purpose of the interrupts and how many are needed. - * Correct game speed (seems too fast). - - 2d: - * Scroll (base registers?) - * ROZ (4th tilemap in fatal fury should be floor [in progress], background should zoom) - * Find registers to control tilemap mode (4bpp/8bpp, 8x8, 16x16) - * Fix zooming sprites (zoom registers not understood, center versus edge pivot) - * Priorities - * Is all the bitmap decoding right? - * Upgrade to modern video timing. - - 3d: - * Find where the remainder of the 3d display list information is 'hiding' - -- should the 3d 'ram' be treated like a fifo, instead of like RAM (see Dreamcast etc.) - * Remaining 3d bits - glowing, etc. - * Populate the display buffers - * Does the hng64 do perspective-correct texture mapping? Doesn't look like it... - - Other: - * Translate KL5C80 docs and finish up the implementation - * Figure out what IO $54 & $72 are on the communications CPU - * Fix sound - * Backup ram etc. - * Correct cpu speed - * How to use the FPGA data ('ROM1') - - ------------------------------------------------------------------------------ Hyper NeoGeo 64, SNK 1997-1999 Hardware info by Guru @@ -1777,8 +1743,12 @@ static auto const &texlayout_xoffset_4(std::integer_sequence +static auto const &texlayout_yoffset_4(std::integer_sequence) +{ + static constexpr uint32_t const s_values[sizeof...(Values)] = { (Values * 4096)... }; + return s_values; +} static const gfx_layout hng64_1024x1024x8_texlayout = { @@ -1793,17 +1763,18 @@ static const gfx_layout hng64_1024x1024x8_texlayout = texlayout_yoffset }; +// it appears that 4bpp tiles can only be in the top 1024 part of this as indexing is the same as 8bpp? static const gfx_layout hng64_1024x1024x4_texlayout = { - 1024, 1024, + 1024, 2048, RGN_FRAC(1,1), 4, { 0,1,2,3 }, EXTENDED_XOFFS, EXTENDED_YOFFS, - 1024*1024*4, + 1024*2048*4, texlayout_xoffset_4(std::make_integer_sequence()), - texlayout_yoffset_4 + texlayout_yoffset_4(std::make_integer_sequence()) }; diff --git a/src/mame/snk/hng64.h b/src/mame/snk/hng64.h index 90f0d6516b2..1d86db8fc26 100644 --- a/src/mame/snk/hng64.h +++ b/src/mame/snk/hng64.h @@ -48,10 +48,7 @@ struct polygon uint8_t texIndex = 0; // Which texture to draw from (0x00-0x0f) uint8_t tex4bpp = 0; // How to index into the texture - uint8_t texPageSmall = 0; // Does this polygon use 'small' texture pages? - uint8_t texPageHorizOffset = 0; // If it does use small texture pages, how far is this page horizontally offset? - uint8_t texPageVertOffset = 0; // If it does use small texture pages, how far is this page vertically offset? - + uint16_t texPageSmall = 0; // Does this polygon use 'small' texture pages? uint32_t palOffset = 0; // The base offset where this object's palette starts. uint16_t colorIndex = 0; @@ -85,9 +82,7 @@ struct hng64_poly_data { uint8_t tex4bpp = 0; uint8_t texIndex = 0; - uint8_t texPageSmall = 0; - uint8_t texPageHorizOffset = 0; - uint8_t texPageVertOffset = 0; + uint16_t texPageSmall = 0; uint32_t palOffset = 0; uint16_t colorIndex = 0; bool blend = false; diff --git a/src/mame/snk/hng64_3d.ipp b/src/mame/snk/hng64_3d.ipp index 85ce34d9f1b..3fc58f1bee1 100644 --- a/src/mame/snk/hng64_3d.ipp +++ b/src/mame/snk/hng64_3d.ipp @@ -602,10 +602,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys) if (chunkOffset[1] & 0x1000) currentPoly.tex4bpp = 0x1; else currentPoly.tex4bpp = 0x0; - currentPoly.texPageSmall = (chunkOffset[2] & 0xc000)>>14; // Just a guess. - currentPoly.texPageHorizOffset = (chunkOffset[2] & 0x3800) >> 11; - currentPoly.texPageVertOffset = (chunkOffset[2] & 0x0070) >> 4; - + currentPoly.texPageSmall = chunkOffset[2]; currentPoly.texIndex = chunkOffset[1] & 0x000f; // Flat shaded polygon, no texture, no lighting @@ -1352,37 +1349,47 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent textureS = sCorrect * 1024.0f; textureT = tCorrect * 1024.0f; - textureS += (renderData.texscrolly & 0x3fff)>>4; - textureT += (renderData.texscrollx & 0x3fff)>>4; + textureS += (renderData.texscrolly & 0x3fff)>>5; + textureT += (renderData.texscrollx & 0x3fff)>>5; #if 1 + + int textPageSub = (renderData.texPageSmall & 0xc000) >> 14; + int texPageHorizOffset = (renderData.texPageSmall & 0x3800) >> 11; + int texPageVertOffset = (renderData.texPageSmall & 0x0070) >> 4; + // Small-Page textures - if (renderData.texPageSmall == 2) + if (textPageSub == 2) { textureT = fmod(textureT, 256.0f); textureS = fmod(textureS, 256.0f); - textureT += (256.0f * (renderData.texPageHorizOffset>>1)); - textureS += (256.0f * (renderData.texPageVertOffset>>1)); + textureT += (256.0f * (texPageHorizOffset>>1)); + textureS += (256.0f * (texPageVertOffset>>1)); } - else if (renderData.texPageSmall == 3) + else if (textPageSub == 3) { // this can't be 128x128 textures, it is needed for the road etc. in xrally which is 256 wide, // but also overhead objects which are 128 (eg lamps, near top left hand side on 8bpp texture page 8) textureT = fmod(textureT, 128.0f); textureS = fmod(textureS, 128.0f); - textureT += (128.0f * (renderData.texPageHorizOffset >> 0)); - textureS += (128.0f * (renderData.texPageVertOffset >> 0)); + textureT += (128.0f * (texPageHorizOffset >> 0)); + textureS += (128.0f * (texPageVertOffset >> 0)); } #endif uint8_t paletteEntry; int t = (int)textureT; + int s = (int)textureS; + + t &= 1023; + s &= 1023; // 4bpp pages seem to be limited to 1024 pixels, with page numbering being the same, the bottom 1024 pixels of 4bpp pages are unsed? + if (renderData.tex4bpp) { - paletteEntry = textureOffset[((int)textureS) * 512 + (t >> 1)]; + paletteEntry = textureOffset[s * 512 + (t >> 1)]; if (t & 1) paletteEntry = (paletteEntry >> 4) & 0x0f; @@ -1391,10 +1398,10 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent } else { - paletteEntry = textureOffset[((int)textureS) * 1024 + t]; + paletteEntry = textureOffset[s * 1024 + t]; } - // Naive Alpha Implementation (?) - don't draw if you're at texture index 0... + // pen 0 in textures is always transparent if (paletteEntry != 0) { float rIntensity = rCorrect / 16.0f; @@ -1451,8 +1458,6 @@ void hng64_poly_renderer::drawShaded(polygon *p) rOptions.texIndex = p->texIndex; rOptions.palOffset = p->palOffset; rOptions.texPageSmall = p->texPageSmall; - rOptions.texPageHorizOffset = p->texPageHorizOffset; - rOptions.texPageVertOffset = p->texPageVertOffset; rOptions.colorIndex = p->colorIndex; rOptions.blend = p->blend; rOptions.texscrollx = p->texscrollx; diff --git a/src/mame/snk/hng64_sprite.ipp b/src/mame/snk/hng64_sprite.ipp index f9933feca63..4555450d432 100644 --- a/src/mame/snk/hng64_sprite.ipp +++ b/src/mame/snk/hng64_sprite.ipp @@ -66,7 +66,7 @@ do \ uint32_t srcdata = (SOURCE); \ if (xdrawpos <= cliprect.right() && xdrawpos >= cliprect.left()) \ { \ - if (zval > (DESTZ)) \ + if (zval >= (DESTZ)) \ { \ if (srcdata != trans_pen) \ { \ @@ -277,6 +277,7 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl { uint16_t zval = (m_spriteram[(currentsprite * 8) + 2] & 0x07ff0000) >> 16; + int16_t ypos = (m_spriteram[(currentsprite * 8) + 0] & 0xffff0000) >> 16; int16_t xpos = (m_spriteram[(currentsprite * 8) + 0] & 0x0000ffff) >> 0; @@ -322,6 +323,18 @@ void hng64_state::draw_sprites_buffer(screen_device& screen, const rectangle& cl continue; }; + // skip the lowest sprite priority depending on the zsort mode + // it was previously assumed the default buffer fill would take care of this + // but unless there's a sign bit, the roadedge name entry screen disagrees as it + // requires a >= check on the sprite draw, not > + // + // for the non-zsort/zrev case, fatfurywa char selectappears requires <, not <= + if (zsort && (zval == 0)) + { + currentsprite = nextsprite; + continue; + } + int32_t dx, dy; if (zoom_factor == 0x100) diff --git a/src/mame/snk/hng64_v.cpp b/src/mame/snk/hng64_v.cpp index 73d53670c5e..683c2104eaa 100644 --- a/src/mame/snk/hng64_v.cpp +++ b/src/mame/snk/hng64_v.cpp @@ -837,6 +837,9 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b if (m_screen_dis) return 0; + // Draw sprites to buffer for later mixing + draw_sprites_buffer(screen, cliprect); + // set during transitions, could be 'disable all palette output'? if ((m_tcram[0x24 / 4] >> 16) & 0x0002) return 0; @@ -990,12 +993,6 @@ uint32_t hng64_state::screen_update_hng64(screen_device &screen, bitmap_rgb32 &b } } - // Draw the sprites on top of everything - draw_sprites_buffer(screen, cliprect); - - - - #if HNG64_VIDEO_DEBUG if (0) popmessage("%08x %08x %08x %08x %08x", m_spriteregs[0], m_spriteregs[1], m_spriteregs[2], m_spriteregs[3], m_spriteregs[4]); -- cgit v1.2.3