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.
This commit is contained in:
David Haywood 2023-03-15 16:46:08 +00:00 committed by GitHub
parent d78c88c427
commit f9de654f59
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 51 additions and 70 deletions

View File

@ -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<uint32_t, Values...
return s_values;
}
static const uint32_t texlayout_yoffset_4[1024] = { STEP1024(0,4096) };
template <uint32_t... Values>
static auto const &texlayout_yoffset_4(std::integer_sequence<uint32_t, Values...>)
{
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<uint32_t, 1024>()),
texlayout_yoffset_4
texlayout_yoffset_4(std::make_integer_sequence<uint32_t, 2048>())
};

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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]);