mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
snk/hng64_v.cpp: Improved rendering: (#10891)
* Filter out most (but not all) the bad polygons in roadedge/xrally by handling display list more correctly. * Fixed 4bpp texture handling (used extensively for background details on sams64/sams64_2). * Added 4bpp texture decode for easy viewing of the 4bpp texture pages. * Fixed some texture palette issues connected to the 4bpp textures and incorrect enable bits being used (wheels and windscreen palette in racing games for example). * Found a flag that seems to enable backface culling, improves bbust2 school bus without breaking roadedge. * Cleaned up logging.
This commit is contained in:
parent
2b9da4a413
commit
17d3ebd429
@ -218,8 +218,10 @@ uint16_t l7a1045_sound_device::l7a1045_sound_r(offs_t offset, uint16_t mem_mask)
|
||||
|
||||
//logerror("%s: read at %x (mask %04x)\n", tag(), offset, mem_mask);
|
||||
|
||||
if(offset == 0)
|
||||
printf("sound_select_r?\n");
|
||||
if (offset == 0)
|
||||
{
|
||||
//logerror("sound_select_r?\n");
|
||||
}
|
||||
else
|
||||
return sound_data_r(offset -1);
|
||||
|
||||
@ -255,7 +257,7 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data)
|
||||
l7a1045_voice *vptr = &m_voice[m_audiochannel];
|
||||
|
||||
//if(m_audioregister != 0 && m_audioregister != 1 && m_audioregister != 7)
|
||||
// printf("%04x %04x (%04x %04x)\n",offset,data,m_audioregister,m_audiochannel);
|
||||
// logerror("%04x %04x (%04x %04x)\n",offset,data,m_audioregister,m_audiochannel);
|
||||
|
||||
m_audiodat[m_audioregister][m_audiochannel].dat[offset] = data;
|
||||
|
||||
@ -281,9 +283,9 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data)
|
||||
break;
|
||||
case 0x01:
|
||||
// relative to start
|
||||
//printf("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0]);
|
||||
//printf("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[1]);
|
||||
//printf("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[2]);
|
||||
//logerror("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0]);
|
||||
//logerror("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[1]);
|
||||
//logerror("%04x\n",m_audiodat[m_audioregister][m_audiochannel].dat[2]);
|
||||
|
||||
if(m_audiodat[m_audioregister][m_audiochannel].dat[2] & 0x100)
|
||||
{
|
||||
@ -312,7 +314,7 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data)
|
||||
vptr->r_volume = (vptr->r_volume) | (vptr->r_volume << 8);
|
||||
vptr->l_volume = (m_audiodat[m_audioregister][m_audiochannel].dat[0] >> 8) & 0xff;
|
||||
vptr->l_volume = (vptr->l_volume) | (vptr->l_volume << 8);
|
||||
//printf("%04x %02x %02x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0],vptr->l_volume,vptr->r_volume);
|
||||
//logerror("%04x %02x %02x\n",m_audiodat[m_audioregister][m_audiochannel].dat[0],vptr->l_volume,vptr->r_volume);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -321,7 +323,7 @@ void l7a1045_sound_device::sound_data_w(offs_t offset, uint16_t data)
|
||||
|
||||
uint16_t l7a1045_sound_device::sound_data_r(offs_t offset)
|
||||
{
|
||||
//printf("%04x (%04x %04x)\n",offset,m_audioregister,m_audiochannel);
|
||||
//logerror("%04x (%04x %04x)\n",offset,m_audioregister,m_audiochannel);
|
||||
//machine().debug_break();
|
||||
l7a1045_voice *vptr = &m_voice[m_audiochannel];
|
||||
|
||||
@ -356,11 +358,11 @@ void l7a1045_sound_device::sound_status_w(uint16_t data)
|
||||
#if 0
|
||||
if(vptr->start != 0)
|
||||
{
|
||||
printf("%08x START\n",vptr->start);
|
||||
printf("%08x END\n",vptr->end);
|
||||
logerror("%08x START\n",vptr->start);
|
||||
logerror("%08x END\n",vptr->end);
|
||||
|
||||
for(int i=0;i<0x10;i++)
|
||||
printf("%02x (%02x) = %04x%04x%04x\n",m_audiochannel,i,m_audiodat[i][m_audiochannel].dat[2],m_audiodat[i][m_audiochannel].dat[1],m_audiodat[i][m_audiochannel].dat[0]);
|
||||
for(int i=0;i<0x10;i++)
|
||||
logerror("%02x (%02x) = %04x%04x%04x\n",m_audiochannel,i,m_audiodat[i][m_audiochannel].dat[2],m_audiodat[i][m_audiochannel].dat[1],m_audiodat[i][m_audiochannel].dat[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -990,7 +990,7 @@ void hng64_state::hng64_sysregs_w(offs_t offset, uint32_t data, uint32_t mem_mas
|
||||
|
||||
#if 0
|
||||
if(((offset*4) & 0xff00) == 0x1100)
|
||||
printf("HNG64 writing to SYSTEM Registers 0x%08x == 0x%08x. (PC=%08x)\n", offset*4, m_sysregs[offset], m_maincpu->pc());
|
||||
logerror("HNG64 writing to SYSTEM Registers 0x%08x == 0x%08x. (PC=%08x)\n", offset*4, m_sysregs[offset], m_maincpu->pc());
|
||||
#endif
|
||||
|
||||
switch(offset*4)
|
||||
@ -1720,20 +1720,47 @@ static const gfx_layout hng64_16x16x8_spritelayout =
|
||||
};
|
||||
|
||||
static const uint32_t texlayout_xoffset[1024] = { STEP1024(0,8) };
|
||||
static const uint32_t texlayout_yoffset[512] = { STEP512(0,8192) };
|
||||
static const gfx_layout hng64_texlayout =
|
||||
static const uint32_t texlayout_yoffset[1024] = { STEP1024(0,8192) };
|
||||
|
||||
static uint32_t texlayout_xoffset_4[1024];
|
||||
static const uint32_t texlayout_yoffset_4[1024] = { STEP1024(0,4096) };
|
||||
|
||||
void hng64_state::texlayout_xoffset_4_create()
|
||||
{
|
||||
1024, 512,
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
texlayout_xoffset_4[i] = (i * 4) ^ 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const gfx_layout hng64_1024x1024x8_texlayout =
|
||||
{
|
||||
1024, 1024,
|
||||
RGN_FRAC(1,1),
|
||||
8,
|
||||
{ 0,1,2,3,4,5,6,7 },
|
||||
EXTENDED_XOFFS,
|
||||
EXTENDED_YOFFS,
|
||||
1024*512*8,
|
||||
1024*1024*8,
|
||||
texlayout_xoffset,
|
||||
texlayout_yoffset
|
||||
};
|
||||
|
||||
static const gfx_layout hng64_1024x1024x4_texlayout =
|
||||
{
|
||||
1024, 1024,
|
||||
RGN_FRAC(1,1),
|
||||
4,
|
||||
{ 0,1,2,3 },
|
||||
EXTENDED_XOFFS,
|
||||
EXTENDED_YOFFS,
|
||||
1024*1024*4,
|
||||
texlayout_xoffset_4,
|
||||
texlayout_yoffset_4
|
||||
};
|
||||
|
||||
|
||||
static GFXDECODE_START( gfx_hng64 )
|
||||
/* tilemap tiles */
|
||||
GFXDECODE_ENTRY( "scrtile", 0, hng64_8x8x4_tilelayout, 0x0, 0x100 )
|
||||
@ -1745,7 +1772,10 @@ static GFXDECODE_START( gfx_hng64 )
|
||||
GFXDECODE_ENTRY( "sprtile", 0, hng64_16x16x4_spritelayout, 0x0, 0x100 )
|
||||
GFXDECODE_ENTRY( "sprtile", 0, hng64_16x16x8_spritelayout, 0x0, 0x10 )
|
||||
|
||||
GFXDECODE_ENTRY( "textures", 0, hng64_texlayout, 0x0, 0x10 ) /* textures */
|
||||
/* texture pages (not used by rendering code) */
|
||||
GFXDECODE_ENTRY( "textures", 0, hng64_1024x1024x4_texlayout, 0x0, 0x100 )
|
||||
GFXDECODE_ENTRY( "textures", 0, hng64_1024x1024x8_texlayout, 0x0, 0x10 )
|
||||
|
||||
GFXDECODE_END
|
||||
|
||||
static void hng64_reorder( uint8_t* gfxregion, size_t gfxregionsize)
|
||||
@ -2110,7 +2140,10 @@ TIMER_CALLBACK_MEMBER(hng64_state::comhack_callback)
|
||||
{
|
||||
LOG("comhack_callback %04x\n\n", m_comhack[0]);
|
||||
|
||||
m_comhack[0] = m_comhack[0] | 0x0002;
|
||||
// different network IDs give different default colours for the cars in roadedge
|
||||
uint8_t network_id = 0x01;
|
||||
|
||||
m_comhack[0] = m_comhack[0] | network_id;
|
||||
}
|
||||
|
||||
|
||||
@ -2969,13 +3002,13 @@ ROM_START( buriki )
|
||||
ROM_END
|
||||
|
||||
/* Bios */
|
||||
GAME( 1997, hng64, 0, hng64_default, hng64, hng64_state, init_hng64, ROT0, "SNK", "Hyper NeoGeo 64 Bios", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND|MACHINE_IS_BIOS_ROOT )
|
||||
GAME( 1997, hng64, 0, hng64_default, hng64, hng64_state, init_hng64, ROT0, "SNK", "Hyper NeoGeo 64 Bios", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND|MACHINE_IS_BIOS_ROOT )
|
||||
|
||||
/* Games */
|
||||
GAME( 1997, roadedge, hng64, hng64_drive, hng64_drive, hng64_state, init_roadedge, ROT0, "SNK", "Roads Edge / Round Trip RV (rev.B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 001 */
|
||||
GAME( 1998, sams64, hng64, hng64_fight, hng64_fight, hng64_state, init_ss64, ROT0, "SNK", "Samurai Shodown 64 / Samurai Spirits 64", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 002 */
|
||||
GAME( 1998, xrally, hng64, hng64_drive, hng64_drive, hng64_state, init_hng64_drive, ROT0, "SNK", "Xtreme Rally / Off Beat Racer!", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 003 */
|
||||
GAME( 1998, bbust2, hng64, hng64_shoot, hng64_shoot, hng64_state, init_hng64_shoot, ROT0, "SNK", "Beast Busters: Second Nightmare", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 004 */
|
||||
GAME( 1998, sams64_2, hng64, hng64_fight, hng64_fight, hng64_state, init_ss64, ROT0, "SNK", "Samurai Shodown 64: Warriors Rage / Samurai Spirits 2: Asura Zanmaden", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 005 */
|
||||
GAME( 1998, fatfurwa, hng64, hng64_fight, hng64_fight, hng64_state, init_hng64_fght, ROT0, "SNK", "Fatal Fury: Wild Ambition / Garou Densetsu: Wild Ambition (rev.A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 006 */
|
||||
GAME( 1999, buriki, hng64, hng64_fight, hng64_fight, hng64_state, init_hng64_fght, ROT0, "SNK", "Buriki One: World Grapple Tournament '99 in Tokyo (rev.B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 007 */
|
||||
GAME( 1997, roadedge, hng64, hng64_drive, hng64_drive, hng64_state, init_roadedge, ROT0, "SNK", "Roads Edge / Round Trip RV (rev.B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 001 */
|
||||
GAME( 1998, sams64, hng64, hng64_fight, hng64_fight, hng64_state, init_ss64, ROT0, "SNK", "Samurai Shodown 64 / Samurai Spirits 64", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 002 */
|
||||
GAME( 1998, xrally, hng64, hng64_drive, hng64_drive, hng64_state, init_hng64_drive, ROT0, "SNK", "Xtreme Rally / Off Beat Racer!", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 003 */
|
||||
GAME( 1998, bbust2, hng64, hng64_shoot, hng64_shoot, hng64_state, init_hng64_shoot, ROT0, "SNK / ADK", "Beast Busters: Second Nightmare", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 004 */ // ADK credited in the ending sequence
|
||||
GAME( 1998, sams64_2, hng64, hng64_fight, hng64_fight, hng64_state, init_ss64, ROT0, "SNK", "Samurai Shodown 64: Warriors Rage / Samurai Spirits 2: Asura Zanmaden", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 005 */
|
||||
GAME( 1998, fatfurwa, hng64, hng64_fight, hng64_fight, hng64_state, init_hng64_fght, ROT0, "SNK", "Fatal Fury: Wild Ambition / Garou Densetsu: Wild Ambition (rev.A)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 006 */
|
||||
GAME( 1999, buriki, hng64, hng64_fight, hng64_fight, hng64_state, init_hng64_fght, ROT0, "SNK", "Buriki One: World Grapple Tournament '99 in Tokyo (rev.B)", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) /* 007 */
|
||||
|
@ -27,7 +27,7 @@ struct polyVert
|
||||
{
|
||||
float worldCoords[4]{}; // World space coordinates (X Y Z 1.0)
|
||||
|
||||
float texCoords[4]{}; // Texture coordinates (U V 0 1.0) -> OpenGL style...
|
||||
float texCoords[2]{}; // Texture coordinates (U V 0 1.0) -> OpenGL style...
|
||||
|
||||
float normal[4]{}; // Normal (X Y Z 1.0)
|
||||
float clipCoords[4]{}; // Homogeneous screen space coordinates (X Y Z W)
|
||||
@ -47,13 +47,12 @@ struct polygon
|
||||
bool flatShade = false; // Flat shaded polygon, no texture, no lighting
|
||||
|
||||
uint8_t texIndex = 0; // Which texture to draw from (0x00-0x0f)
|
||||
uint8_t texType = 0; // How to index into the texture
|
||||
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?
|
||||
|
||||
uint32_t palOffset = 0; // The base offset where this object's palette starts.
|
||||
uint32_t palPageSize = 0; // The size of the palette page that is being pointed to.
|
||||
|
||||
uint32_t debugColor = 0; // Will go away someday. Used to explicitly color polygons for debugging.
|
||||
};
|
||||
@ -82,13 +81,12 @@ typedef frustum_clip_vertex<float, 5> hng64_clip_vertex;
|
||||
|
||||
struct hng64_poly_data
|
||||
{
|
||||
uint8_t texType = 0;
|
||||
uint8_t tex4bpp = 0;
|
||||
uint8_t texIndex = 0;
|
||||
uint8_t texPageSmall = 0;
|
||||
uint8_t texPageHorizOffset = 0;
|
||||
uint8_t texPageVertOffset = 0;
|
||||
int palOffset = 0;
|
||||
int palPageSize = 0;
|
||||
int debugColor = 0;
|
||||
};
|
||||
|
||||
@ -167,7 +165,9 @@ public:
|
||||
m_in(*this, "IN%u", 0U),
|
||||
m_samsho64_3d_hack(0),
|
||||
m_roadedge_3d_hack(0)
|
||||
{ }
|
||||
{
|
||||
texlayout_xoffset_4_create();
|
||||
}
|
||||
|
||||
void hng64(machine_config &config);
|
||||
void hng64_default(machine_config &config);
|
||||
@ -182,6 +182,8 @@ public:
|
||||
void init_ss64();
|
||||
void init_hng64_fght();
|
||||
|
||||
static void texlayout_xoffset_4_create();
|
||||
|
||||
uint8_t *m_texturerom = nullptr;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
@ -457,7 +459,7 @@ private:
|
||||
std::vector<polygon> m_polys; // HNG64_MAX_POLYGONS
|
||||
|
||||
void clear3d();
|
||||
void hng64_command3d(const uint16_t* packet);
|
||||
bool hng64_command3d(const uint16_t* packet);
|
||||
void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
void transition_control(bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
void setCameraTransformation(const uint16_t* packet);
|
||||
|
@ -63,6 +63,8 @@ void hng64_state::dl_unk_w(offs_t offset, uint32_t data, uint32_t mem_mask)
|
||||
|
||||
void hng64_state::dl_upload_w(uint32_t data)
|
||||
{
|
||||
//m_paletteState3d = 0; // no, breaks fatfurwa characters
|
||||
|
||||
// Data is:
|
||||
// 00000b50 for the sams64 games
|
||||
// 00000f00 for everything else
|
||||
@ -75,7 +77,8 @@ g_profiler.start(PROFILER_USER1);
|
||||
for(int packetStart = 0; packetStart < 0x100; packetStart += 16)
|
||||
{
|
||||
// Send it off to the 3d subsystem.
|
||||
hng64_command3d(&m_dl[packetStart]);
|
||||
if (!hng64_command3d(&m_dl[packetStart]))
|
||||
break;
|
||||
}
|
||||
|
||||
// Schedule a small amount of time to let the 3d hardware rasterize the display buffer
|
||||
@ -106,7 +109,7 @@ void hng64_state::dl_control_w(uint32_t data)
|
||||
*/
|
||||
|
||||
/*
|
||||
printf("dl_control_w %08x %08x\n", data, mem_mask);
|
||||
logerror("dl_control_w %08x %08x\n", data, mem_mask);
|
||||
|
||||
if(data & 2) // swap buffers
|
||||
{
|
||||
@ -136,7 +139,7 @@ void hng64_state::printPacket(const uint16_t* packet, int hex)
|
||||
{
|
||||
if (hex)
|
||||
{
|
||||
printf("Packet : %04x %04x 2:%04x %04x 4:%04x %04x 6:%04x %04x 8:%04x %04x 10:%04x %04x 12:%04x %04x 14:%04x %04x\n",
|
||||
logerror("Packet : %04x %04x 2:%04x %04x 4:%04x %04x 6:%04x %04x 8:%04x %04x 10:%04x %04x 12:%04x %04x 14:%04x %04x\n",
|
||||
packet[0], packet[1],
|
||||
packet[2], packet[3],
|
||||
packet[4], packet[5],
|
||||
@ -148,7 +151,7 @@ void hng64_state::printPacket(const uint16_t* packet, int hex)
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Packet : %04x %3.4f 2:%3.4f %3.4f 4:%3.4f %3.4f 6:%3.4f %3.4f 8:%3.4f %3.4f 10:%3.4f %3.4f 12:%3.4f %3.4f 14:%3.4f %3.4f\n",
|
||||
logerror("Packet : %04x %3.4f 2:%3.4f %3.4f 4:%3.4f %3.4f 6:%3.4f %3.4f 8:%3.4f %3.4f 10:%3.4f %3.4f 12:%3.4f %3.4f 14:%3.4f %3.4f\n",
|
||||
packet[0], uToF(packet[1] )*128,
|
||||
uToF(packet[2] )*128, uToF(packet[3] )*128,
|
||||
uToF(packet[4] )*128, uToF(packet[5] )*128,
|
||||
@ -228,8 +231,8 @@ void hng64_state::setLighting(const uint16_t* packet)
|
||||
// [14] - ???? ... ? Used in fatfurwa
|
||||
// [15] - ???? ... ? Used in fatfurwa
|
||||
////////////*/
|
||||
if (packet[1] != 0x0000) printf("ZOMG! packet[1] in setLighting function is non-zero!\n");
|
||||
if (packet[2] != 0x0000) printf("ZOMG! packet[2] in setLighting function is non-zero!\n");
|
||||
if (packet[1] != 0x0000) logerror("packet[1] in setLighting function is non-zero!\n");
|
||||
if (packet[2] != 0x0000) logerror("packet[2] in setLighting function is non-zero!\n");
|
||||
|
||||
m_lightVector[0] = uToF(packet[3]);
|
||||
m_lightVector[1] = uToF(packet[4]);
|
||||
@ -331,22 +334,14 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
/*//////////////
|
||||
// PACKET FORMAT
|
||||
// [0] - 0100 ... ID
|
||||
// [1] - ?--- ... Flags [?000 = ???
|
||||
// 0?00 = ???
|
||||
// 00?0 = ???
|
||||
// 000? = ???]
|
||||
// [1] - -?-- ... Flags [?000 = ???
|
||||
// 0?00 = ???
|
||||
// 00?0 = ???
|
||||
// 000x = Dynamic palette bit]
|
||||
// [1] - --?- ... Flags [?000 = ???
|
||||
// 0?00 = ???
|
||||
// 00?0 = ???
|
||||
// 000? = ???]
|
||||
// [1] - ---? ... Flags [x000 = Apply lighting bit
|
||||
// 0?00 = ???
|
||||
// 00?0 = ???
|
||||
// 000? = ???]
|
||||
// [1] - --c- ---p ---b l---
|
||||
// l = use lighting
|
||||
// p = use dynamic palette (maybe not just this, wrong for roadedge car select where it isn't set but needs to be)
|
||||
// b = backface culling?
|
||||
// c = set on objects a certain distance away (maybe optimization to disable clipping against camera?)
|
||||
// none of these bits appear to be connected to texture size to solve the road/banner problem in xrally/roadedge
|
||||
//
|
||||
//
|
||||
// [2] - xxxx ... offset into ROM
|
||||
// [3] - xxxx ... offset into ROM
|
||||
// [4] - xxxx ... Transformation matrix
|
||||
@ -430,7 +425,11 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
|
||||
if (threeDOffset >= m_vertsrom_size)
|
||||
{
|
||||
printf("Strange geometry packet: (ignoring)\n");
|
||||
// bbust2 quite often spams this invalid pointer
|
||||
if ((packet[2] == 0x2347) && (packet[3] == 0x5056))
|
||||
return;
|
||||
|
||||
logerror("Strange geometry packet: (ignoring)\n");
|
||||
printPacket(packet, 1);
|
||||
return;
|
||||
}
|
||||
@ -453,11 +452,11 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
|
||||
address[2] = threeDPointer[3];
|
||||
address[3] = threeDPointer[4];
|
||||
if (threeDPointer[5] != 0x0000) printf("ZOMG! 3dPointer[5] is non-zero!\n");
|
||||
if (threeDPointer[5] != 0x0000) logerror("3dPointer[5] is non-zero!\n");
|
||||
|
||||
size[0] = threeDPointer[6];
|
||||
size[1] = threeDPointer[7];
|
||||
if (threeDPointer[8] != 0x0000) printf("ZOMG! 3dPointer[8] is non-zero!\n");
|
||||
if (threeDPointer[8] != 0x0000) logerror("3dPointer[8] is non-zero!\n");
|
||||
|
||||
size[2] = threeDPointer[9];
|
||||
size[3] = threeDPointer[10];
|
||||
@ -466,13 +465,13 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// ???? [13]; Used.
|
||||
// ???? [14]; Used.
|
||||
|
||||
if (threeDPointer[15] != 0x0000) printf("ZOMG! 3dPointer[15] is non-zero!\n");
|
||||
if (threeDPointer[16] != 0x0000) printf("ZOMG! 3dPointer[16] is non-zero!\n");
|
||||
if (threeDPointer[17] != 0x0000) printf("ZOMG! 3dPointer[17] is non-zero!\n");
|
||||
if (threeDPointer[15] != 0x0000) logerror("3dPointer[15] is non-zero!\n");
|
||||
if (threeDPointer[16] != 0x0000) logerror("3dPointer[16] is non-zero!\n");
|
||||
if (threeDPointer[17] != 0x0000) logerror("3dPointer[17] is non-zero!\n");
|
||||
|
||||
if (threeDPointer[18] != 0x0000) printf("ZOMG! 3dPointer[18] is non-zero!\n");
|
||||
if (threeDPointer[19] != 0x0000) printf("ZOMG! 3dPointer[19] is non-zero!\n");
|
||||
if (threeDPointer[20] != 0x0000) printf("ZOMG! 3dPointer[20] is non-zero!\n");
|
||||
if (threeDPointer[18] != 0x0000) logerror("3dPointer[18] is non-zero!\n");
|
||||
if (threeDPointer[19] != 0x0000) logerror("3dPointer[19] is non-zero!\n");
|
||||
if (threeDPointer[20] != 0x0000) logerror("3dPointer[20] is non-zero!\n");
|
||||
|
||||
// Concatenate the megaOffset with the addresses
|
||||
address[0] |= (megaOffset << 16);
|
||||
@ -497,10 +496,17 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
////////////////////////////////////////////
|
||||
// SINGLE POLY CHUNK FORMAT
|
||||
// [0] 0000 0000 cccc cccc 0 = always 0 | c = chunk type / format of data that follows (see below)
|
||||
// [1] t--l pppp pppp ssss t = texture, always on for most games, on for the backgrounds only on sams64
|
||||
// [1] tu-4 pppp pppp ssss t = texture, always on for most games, on for the backgrounds only on sams64
|
||||
// if not set, u,v fields of vertices are direct palette indices, used on roadedge hng64 logo animation shadows
|
||||
// l = low-res texture? p = palette? s = texture sheet (1024 x 1024 pages)
|
||||
// [2] S?XX *--- -YY# ---- S = use 4x4 sub-texture pages? ? = SNK logo roadedge / bbust2 / broken banners in xrally, XX = horizontal subtexture * = broken banners in xrally YY = vertical subtexture @ = broken banners in xrally
|
||||
// u = unknown, set on sams64 / buriki at times, never on racing games
|
||||
// 4 = 4bpp texture p = palette? s = texture sheet (1024 x 1024 pages)
|
||||
// [2] S?XX *uuu -YY# uuu- S = use 4x4 sub-texture pages?
|
||||
// ? = SNK logo roadedge / bbust2 / broken banners in xrally
|
||||
// X = horizontal subtexture
|
||||
// * = broken banners in xrally
|
||||
// Y = vertical subtexture
|
||||
// # = broken banners in xrally
|
||||
// u = unknown, set late on 2nd race+3rd race in xrally
|
||||
|
||||
// we currently use one of the palette bits to enable a different palette mode.. seems hacky...
|
||||
// looks like vertical / horizontal sub-pages might be 3 bits, not 2, ? could be enable bit for that..
|
||||
@ -508,13 +514,12 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// 'Welcome to South Africa' roadside banner on xrally | 000e 8c0d d870 or 0096 8c0d d870 (8c0d, d870 seems key 1000 1100 0000 1101
|
||||
// 1101 1000 0111 0000 )
|
||||
|
||||
|
||||
uint8_t chunkType = chunkOffset[0] & 0x00ff;
|
||||
|
||||
// Debug - ajg
|
||||
if (chunkOffset[0] & 0xff00)
|
||||
{
|
||||
printf("Weird! The top byte of the chunkType has a value %04x!\n", chunkOffset[0]);
|
||||
logerror("Weird! The top byte of the chunkType has a value %04x!\n", chunkOffset[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -526,13 +531,11 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
//currentPoly.debugColor = tdColor;
|
||||
|
||||
// Debug - ajg
|
||||
//printf("%d (%08x) : %04x %04x %04x\n", k, address[k]*3*2, chunkOffset[0], chunkOffset[1], chunkOffset[2]);
|
||||
//logerror("%d (%08x) : %04x %04x %04x\n", k, address[k]*3*2, chunkOffset[0], chunkOffset[1], chunkOffset[2]);
|
||||
//break;
|
||||
|
||||
// TEXTURE
|
||||
// There may be more than just high & low res texture types, so I'm keeping texType as a uint8_t. */
|
||||
if (chunkOffset[1] & 0x1000) currentPoly.texType = 0x1;
|
||||
else currentPoly.texType = 0x0;
|
||||
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;
|
||||
@ -548,7 +551,6 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
|
||||
// PALETTE
|
||||
currentPoly.palOffset = 0;
|
||||
currentPoly.palPageSize = 0x100;
|
||||
|
||||
// FIXME: This isn't correct.
|
||||
// Buriki & Xrally need this line. Roads Edge needs it removed.
|
||||
@ -560,20 +562,27 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
}
|
||||
|
||||
//uint16_t explicitPaletteValue0 = ((chunkOffset[?] & 0x????) >> ?) * 0x800;
|
||||
uint16_t explicitPaletteValue1 = ((chunkOffset[1] & 0x0f00) >> 8) * 0x080;
|
||||
uint16_t explicitPaletteValue2 = ((chunkOffset[1] & 0x00f0) >> 4) * 0x008;
|
||||
|
||||
// The presence of 0x00f0 *probably* sets 0x10-sized palette addressing.
|
||||
if (explicitPaletteValue2) currentPoly.palPageSize = 0x10;
|
||||
uint16_t explicitPaletteValue = ((chunkOffset[1] & 0x0ff0) >> 4);
|
||||
explicitPaletteValue = explicitPaletteValue << 3;
|
||||
|
||||
// HACK: this is not the enable, the cars in roadedge rely on this to switch palettes
|
||||
// on the select screen, where this bit is not enabled.
|
||||
// (to see the cars on the select screen disable sprite rendering, as there are
|
||||
// currently priority issues)
|
||||
//
|
||||
// however for sams64 this is enabled on the 2nd character, but not the 1st character
|
||||
// and the additional palette offset definitely only applies to the 2nd
|
||||
//
|
||||
// Apply the dynamic palette offset if its flag is set, otherwise stick with the fixed one
|
||||
if ((packet[1] & 0x0100))
|
||||
{
|
||||
explicitPaletteValue1 = m_paletteState3d * 0x80;
|
||||
explicitPaletteValue2 = 0; // This is probably hiding somewhere in operation 0011
|
||||
// bbust2 has m_paletteState3d & 0x40 set, which takes the palette out of range
|
||||
// used for 2nd car on roadedge, used for 2nd player on buriki
|
||||
// used for buildings in fatfurwa intro and characters
|
||||
explicitPaletteValue |= (m_paletteState3d & 0x3f) * 0x80;
|
||||
}
|
||||
|
||||
currentPoly.palOffset += (explicitPaletteValue1 + explicitPaletteValue2);
|
||||
currentPoly.palOffset += explicitPaletteValue;
|
||||
|
||||
#if 0
|
||||
if (((chunkOffset[2] & 0xc000) == 0x4000) && (m_screen->frame_number() & 1))
|
||||
@ -581,7 +590,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// if (chunkOffset[2] == 0xd870)
|
||||
{
|
||||
currentPoly.debugColor = 0xffff0000;
|
||||
printf("%d (%08x) : %04x %04x %04x\n", k, address[k] * 3 * 2, chunkOffset[0], chunkOffset[1], chunkOffset[2]);
|
||||
logerror("%d (%08x) : %04x %04x %04x\n", k, address[k] * 3 * 2, chunkOffset[0], chunkOffset[1], chunkOffset[2]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -599,6 +608,9 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// ---- -x-- - 1 = Has per-vert UVs
|
||||
// ---- --x- -
|
||||
// ---- ---x - 1 = Has per-vert normals
|
||||
//
|
||||
// none of these seem directly connected to texture size to solve texturing problem in the racing games
|
||||
// maybe some of the actual packet data is being used incorrectly?
|
||||
/////////////////////////*/
|
||||
|
||||
// 33 word chunk, 3 vertices, per-vertex UVs & normals, per-face normal
|
||||
@ -615,8 +627,6 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// 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].texCoords[2] = 0.0f;
|
||||
currentPoly.vert[m].texCoords[3] = 1.0f;
|
||||
|
||||
currentPoly.vert[m].normal[0] = uToF(chunkOffset[9 + (9*m)]);
|
||||
currentPoly.vert[m].normal[1] = uToF(chunkOffset[10 + (9*m)]);
|
||||
@ -653,9 +663,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// 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)]);
|
||||
currentPoly.vert[m].texCoords[2] = 0.0f;
|
||||
currentPoly.vert[m].texCoords[3] = 1.0f;
|
||||
|
||||
|
||||
if (currentPoly.flatShade)
|
||||
currentPoly.vert[m].colorIndex = chunkOffset[7 + (6*m)] >> 5;
|
||||
|
||||
@ -694,8 +702,6 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// 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]);
|
||||
currentPoly.vert[0].texCoords[2] = 0.0f;
|
||||
currentPoly.vert[0].texCoords[3] = 1.0f;
|
||||
|
||||
if (currentPoly.flatShade)
|
||||
currentPoly.vert[0].colorIndex = chunkOffset[7] >> 5;
|
||||
@ -733,8 +739,6 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// 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]);
|
||||
currentPoly.vert[0].texCoords[2] = 0.0f;
|
||||
currentPoly.vert[0].texCoords[3] = 1.0f;
|
||||
|
||||
if (currentPoly.flatShade)
|
||||
currentPoly.vert[0].colorIndex = chunkOffset[7] >> 5;
|
||||
@ -754,21 +758,21 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
|
||||
#if 0
|
||||
// DEBUG
|
||||
printf("0x?6 : %08x (%d/%d)\n", address[k]*3*2, l, size[k]-1);
|
||||
logerror("0x?6 : %08x (%d/%d)\n", address[k]*3*2, l, size[k]-1);
|
||||
for (int m = 0; m < 13; m++)
|
||||
printf("%04x ", chunkOffset[m]);
|
||||
printf("\n");
|
||||
logerror("%04x ", chunkOffset[m]);
|
||||
logerror("\n");
|
||||
|
||||
for (int m = 0; m < 13; m++)
|
||||
printf("%3.4f ", uToF(chunkOffset[m]));
|
||||
printf("\n\n");
|
||||
logerror("%3.4f ", uToF(chunkOffset[m]));
|
||||
logerror("\n\n");
|
||||
#endif
|
||||
|
||||
chunkLength = 12;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("UNKNOWN geometry CHUNK TYPE : %02x\n", chunkType);
|
||||
logerror("UNKNOWN geometry CHUNK TYPE : %02x\n", chunkType);
|
||||
chunkLength = 0;
|
||||
break;
|
||||
}
|
||||
@ -829,8 +833,7 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
}
|
||||
}
|
||||
|
||||
// BACKFACE CULL
|
||||
// roadedge has various one-way barriers that you can drive through, but need to be invisible from behind, so needs this culling
|
||||
|
||||
float cullRay[4];
|
||||
float cullNorm[4];
|
||||
|
||||
@ -841,11 +844,18 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
// Dot product that with the normal to see if you're negative...
|
||||
vecmatmul4(cullNorm, m_modelViewMatrix, currentPoly.faceNormal);
|
||||
|
||||
const float backfaceCullResult = vecDotProduct(cullRay, cullNorm);
|
||||
if (backfaceCullResult < 0.0f)
|
||||
currentPoly.visible = true;
|
||||
else
|
||||
currentPoly.visible = false;
|
||||
// BACKFACE CULL
|
||||
// roadedge has various one-way barriers that you can drive through, but need to be invisible from behind, so needs this culling
|
||||
// this bit IS set on the objects that roadedge needs to vanish if viewed from behind, but it is NOT set on the bbust2 school bus
|
||||
// which needs to be visible with backfacing polys. further test cases need to be found.
|
||||
if (packet[1] & 0x0010)
|
||||
{
|
||||
const float backfaceCullResult = vecDotProduct(cullRay, cullNorm);
|
||||
if (backfaceCullResult < 0.0f)
|
||||
currentPoly.visible = true;
|
||||
else
|
||||
currentPoly.visible = false;
|
||||
}
|
||||
|
||||
// BEHIND-THE-CAMERA CULL //
|
||||
vecmatmul4(cullRay, m_modelViewMatrix, currentPoly.vert[0].worldCoords);
|
||||
@ -934,25 +944,17 @@ void hng64_state::recoverPolygonBlock(const uint16_t* packet, int& numPolys)
|
||||
}
|
||||
}
|
||||
|
||||
// note 0x0102 packets are only 8 words, it appears they can be in either the upper or lower half of the 16 word packet.
|
||||
// We currently only draw 0x0102 packets where both halves contain 0x0102 (2 calls), but this causes graphics to vanish in
|
||||
// xrally because in some cases the 0x0102 packet only exists in the upper or lower half with another value (often 0x0000 - NOP) in the other.
|
||||
// If we also treat (0x0000 - NOP) as 8 word instead of 16 so that we can access a 0x0102 in the 2nd half of the 16 word packet
|
||||
// then we end up with other invalid packets in the 2nd half which should be ignored.
|
||||
// This would suggest our processing if flawed in other ways, or there is something else to indicate packet length.
|
||||
|
||||
void hng64_state::hng64_command3d(const uint16_t* packet)
|
||||
bool hng64_state::hng64_command3d(const uint16_t* packet)
|
||||
{
|
||||
int numPolys = 0;
|
||||
|
||||
//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]);
|
||||
//logerror("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]);
|
||||
|
||||
switch (packet[0])
|
||||
{
|
||||
case 0x0000: // NOP?
|
||||
/* Appears to be a NOP (or 'end of list for this frame, ignore everything after' doesn't stop stray 3d objects in game for xrally/roadedge
|
||||
although does stop a partial hng64 logo being displayed assuming that's meant to be kept onscreen by some other means without valid data) */
|
||||
break;
|
||||
case 0x0000: // NOP? / End current list (doesn't stop additional lists being sent this frame)
|
||||
return false;
|
||||
|
||||
case 0x0001: // Camera transformation.
|
||||
setCameraTransformation(packet);
|
||||
@ -970,12 +972,18 @@ void hng64_state::hng64_command3d(const uint16_t* packet)
|
||||
setCameraProjectionMatrix(packet);
|
||||
break;
|
||||
|
||||
case 0x0100:
|
||||
case 0x0101: // Geometry with full transformations
|
||||
case 0x0100: // Geometry with full transformations
|
||||
// xrally/roadedge cars (not track, that uses 102), buriki, fatfurwa
|
||||
recoverPolygonBlock(packet, numPolys);
|
||||
break;
|
||||
|
||||
case 0x0101: // Geometry with full transformations (same as 0x100?)
|
||||
// sams64, sams64_2, bbust2
|
||||
recoverPolygonBlock(packet, numPolys);
|
||||
break;
|
||||
|
||||
case 0x0102: // Geometry with only translation
|
||||
// 'world' in roadedge/xrally (track, trackside objects etc.)
|
||||
// Split the packet and call recoverPolygonBlock on each half.
|
||||
uint16_t miniPacket[16];
|
||||
memset(miniPacket, 0, sizeof(uint16_t)*16);
|
||||
@ -985,27 +993,31 @@ void hng64_state::hng64_command3d(const uint16_t* packet)
|
||||
miniPacket[15] = 0x7fff;
|
||||
recoverPolygonBlock(miniPacket, numPolys);
|
||||
|
||||
if (packet[7] == 1)
|
||||
{
|
||||
if (packet[8] == 0x0102)
|
||||
{
|
||||
memset(miniPacket, 0, sizeof(uint16_t) * 16);
|
||||
for (int i = 0; i < 7; i++) miniPacket[i] = packet[i + 8];
|
||||
miniPacket[7] = 0x7fff;
|
||||
miniPacket[11] = 0x7fff;
|
||||
miniPacket[15] = 0x7fff;
|
||||
recoverPolygonBlock(miniPacket, numPolys);
|
||||
|
||||
if (packet[8] == 0x0102)
|
||||
{
|
||||
memset(miniPacket, 0, sizeof(uint16_t) * 16);
|
||||
for (int i = 0; i < 7; i++) miniPacket[i] = packet[i + 8];
|
||||
miniPacket[7] = 0x7fff;
|
||||
miniPacket[11] = 0x7fff;
|
||||
miniPacket[15] = 0x7fff;
|
||||
recoverPolygonBlock(miniPacket, numPolys);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if the 2nd value isn't 0x0102 don't render it
|
||||
it could just be that the display list is corrupt at this point tho, see note above
|
||||
*/
|
||||
// packet[15] is always 1?
|
||||
}
|
||||
else
|
||||
{
|
||||
/* if the 2nd value isn't 0x0102 don't render it
|
||||
it could just be that the display list is corrupt at this point tho, see note above
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x1000: // Unknown: Some sort of global flags?
|
||||
//printPacket(packet, 1); printf("\n");
|
||||
//printPacket(packet, 1); logerror("\n");
|
||||
break;
|
||||
|
||||
case 0x1001: // Unknown: Some sort of global flags? Almost always comes in a group of 4 with an index [0,3].
|
||||
@ -1013,7 +1025,7 @@ void hng64_state::hng64_command3d(const uint16_t* packet)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("HNG64: Unknown 3d command %04x.\n", packet[0]);
|
||||
logerror("HNG64: Unknown 3d command %04x.\n", packet[0]);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1026,6 +1038,7 @@ void hng64_state::hng64_command3d(const uint16_t* packet)
|
||||
}
|
||||
}
|
||||
m_poly_renderer->wait();
|
||||
return true;
|
||||
}
|
||||
|
||||
void hng64_state::clear3d()
|
||||
@ -1040,6 +1053,8 @@ void hng64_state::clear3d()
|
||||
// Clear the 3d rasterizer buffer
|
||||
m_poly_renderer->colorBuffer3d().fill(0x00000000, m_screen->visible_area());
|
||||
|
||||
m_paletteState3d = 0;
|
||||
|
||||
// Set some matrices to the identity...
|
||||
setIdentity(m_projectionMatrix);
|
||||
setIdentity(m_modelViewMatrix);
|
||||
@ -1265,18 +1280,11 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent
|
||||
float textureS = 0.0f;
|
||||
float textureT = 0.0f;
|
||||
|
||||
// Standard & Half-Res textures
|
||||
if (renderData.texType == 0x0)
|
||||
{
|
||||
textureS = sCorrect * 1024.0f;
|
||||
textureT = tCorrect * 1024.0f;
|
||||
}
|
||||
else if (renderData.texType == 0x1)
|
||||
{
|
||||
textureS = sCorrect * 512.0f;
|
||||
textureT = tCorrect * 512.0f;
|
||||
}
|
||||
// sCorrect and tCorrect have range 0.0f - 1.0f, multiply by 1024 to get texture offset
|
||||
textureS = sCorrect * 1024.0f;
|
||||
textureT = tCorrect * 1024.0f;
|
||||
|
||||
#if 1
|
||||
// Small-Page textures
|
||||
if (renderData.texPageSmall == 2)
|
||||
{
|
||||
@ -1288,21 +1296,37 @@ void hng64_poly_renderer::render_texture_scanline(int32_t scanline, const extent
|
||||
}
|
||||
else if (renderData.texPageSmall == 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 * (renderData.texPageHorizOffset >> 0));
|
||||
textureS += (128.0f * (renderData.texPageVertOffset >> 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t paletteEntry = textureOffset[((int)textureS)*1024 + (int)textureT];
|
||||
uint8_t paletteEntry;
|
||||
int t = (int)textureT;
|
||||
if (renderData.tex4bpp)
|
||||
{
|
||||
paletteEntry = textureOffset[((int)textureS) * 512 + (t >> 1)];
|
||||
|
||||
if (t & 1)
|
||||
paletteEntry = (paletteEntry >> 4) & 0x0f;
|
||||
else
|
||||
paletteEntry &= 0x0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteEntry = textureOffset[((int)textureS) * 1024 + t];
|
||||
}
|
||||
|
||||
// Naive Alpha Implementation (?) - don't draw if you're at texture index 0...
|
||||
if (paletteEntry != 0)
|
||||
{
|
||||
// The color out of the texture
|
||||
paletteEntry %= renderData.palPageSize;
|
||||
rgb_t color = m_state.m_palette->pen(renderData.palOffset + paletteEntry);
|
||||
rgb_t color = m_state.m_palette->pen((renderData.palOffset + paletteEntry) & 0xfff);
|
||||
|
||||
// Apply the lighting
|
||||
float rIntensity = rCorrect / 255.0f;
|
||||
@ -1390,10 +1414,9 @@ void hng64_poly_renderer::drawShaded(polygon *p)
|
||||
{
|
||||
// Polygon information for the rasterizer
|
||||
hng64_poly_data rOptions;
|
||||
rOptions.texType = p->texType;
|
||||
rOptions.tex4bpp = p->tex4bpp;
|
||||
rOptions.texIndex = p->texIndex;
|
||||
rOptions.palOffset = p->palOffset;
|
||||
rOptions.palPageSize = p->palPageSize;
|
||||
rOptions.debugColor = p->debugColor;
|
||||
rOptions.texPageSmall = p->texPageSmall;
|
||||
rOptions.texPageHorizOffset = p->texPageHorizOffset;
|
||||
|
@ -281,11 +281,11 @@ void hng64_state::sound_comms_w(offs_t offset, uint16_t data, uint16_t mem_mask)
|
||||
/* correct? */
|
||||
m_audiocpu->set_input_line(5, CLEAR_LINE);
|
||||
//if(data)
|
||||
// printf("IRQ ACK %02x?\n",data);
|
||||
// logerror("IRQ ACK %02x?\n",data);
|
||||
return;
|
||||
}
|
||||
|
||||
//printf("SOUND W %02x %04x\n",offset*2,data);
|
||||
//logerror("SOUND W %02x %04x\n",offset*2,data);
|
||||
}
|
||||
|
||||
uint16_t hng64_state::sound_comms_r(offs_t offset)
|
||||
@ -297,7 +297,7 @@ uint16_t hng64_state::sound_comms_r(offs_t offset)
|
||||
case 0x06:
|
||||
return main_latch[1];
|
||||
}
|
||||
//printf("SOUND R %02x\n",offset*2);
|
||||
//logerror("SOUND R %02x\n",offset*2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -375,7 +375,7 @@ WRITE_LINE_MEMBER(hng64_state::tcu_tm2_cb)
|
||||
if(i > 7)
|
||||
i = 7;
|
||||
|
||||
//printf("trigger %02x %d\n",i,state);
|
||||
//logerror("trigger %02x %d\n",i,state);
|
||||
|
||||
//if(machine().input().code_pressed_once(KEYCODE_C))
|
||||
{
|
||||
|
@ -569,7 +569,7 @@ void hng64_state::hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
// floor mode
|
||||
// life would be easier if the roz we're talking about for complex zoom wasn't setting this as well
|
||||
|
||||
// fprintf(stderr, "Tilemap %d is a floor using :\n", tm);
|
||||
// logerror(stderr, "Tilemap %d is a floor using :\n", tm);
|
||||
// const uint32_t floorAddress = 0x40000 + (scrollbase << 4);
|
||||
|
||||
// TODO: The row count is correct, but how is this layer clipped? m_tcram?
|
||||
@ -587,7 +587,7 @@ void hng64_state::hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
//
|
||||
// lineCount++;
|
||||
//}
|
||||
//printf("lines %d\n", lineCount);
|
||||
//logerror("lines %d\n", lineCount);
|
||||
|
||||
// Buriki uses a 2x mosaic effect on its floor, so its line count is half
|
||||
// (but so does fatfurwa - maybe it overdraws a bunch of pixels?)
|
||||
@ -734,7 +734,7 @@ void hng64_state::hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
const int bmwidth = bm.width();
|
||||
pen_t const *const paldata = m_palette->pens();
|
||||
|
||||
//printf("start %08x end %08x start %08x end %08x\n", xtopleft, xmiddle, ytopleft, ymiddle);
|
||||
//logerror("start %08x end %08x start %08x end %08x\n", xtopleft, xmiddle, ytopleft, ymiddle);
|
||||
|
||||
for (int yy=0; yy<448; yy++)
|
||||
{
|
||||
@ -826,7 +826,7 @@ void hng64_state::hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap,
|
||||
|
||||
int tmp = xtopleft;
|
||||
|
||||
//printf("start %08x end %08x start %08x end %08x\n", xtopleft, xmiddle, ytopleft, ymiddle);
|
||||
//logerror("start %08x end %08x start %08x end %08x\n", xtopleft, xmiddle, ytopleft, ymiddle);
|
||||
|
||||
for (int yy=0; yy<448; yy++)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user