summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Andrew Gardner <andrew-gardner@users.noreply.github.com>2009-12-23 06:56:15 +0000
committer Andrew Gardner <andrew-gardner@users.noreply.github.com>2009-12-23 06:56:15 +0000
commit06bdbdbe52dfc5cdab6825d8fdc7f25de69ac57e (patch)
treec01c44f7b8f07a68d70753511f32ee8cb5b19789
parent7eace0d29ebaf850e563d15441b524fef9b613c3 (diff)
Reworked the polygon chunk recovery code to be more crash-proof.
Documented what's known about the 3d data much better. Fixed vertex ROM loading for fatfurwa and buriki. (No games should segfault anymore, but they all appear to use the hardware in different ways, so this could be fun.)
-rw-r--r--src/mame/drivers/hng64.c11
-rw-r--r--src/mame/video/hng64.c583
2 files changed, 378 insertions, 216 deletions
diff --git a/src/mame/drivers/hng64.c b/src/mame/drivers/hng64.c
index 79aca88a3dc..f4bfd8a374e 100644
--- a/src/mame/drivers/hng64.c
+++ b/src/mame/drivers/hng64.c
@@ -621,9 +621,9 @@ static READ32_HANDLER( hng64_sysregs_r )
/* preliminary dma code, dma is used to copy program code -> ram */
static INT32 hng_dma_start,hng_dma_dst,hng_dma_len;
-static void hng64_do_dma (const address_space *space)
+static void hng64_do_dma(const address_space *space)
{
- printf("Performing DMA Start %08x Len %08x Dst %08x\n",hng_dma_start, hng_dma_len, hng_dma_dst);
+ //printf("Performing DMA Start %08x Len %08x Dst %08x\n",hng_dma_start, hng_dma_len, hng_dma_dst);
while (hng_dma_len>=0)
{
@@ -920,6 +920,7 @@ static READ32_HANDLER( dl_r )
// Some kind of buffering of the display lists, or 'render current buffer' write?
static WRITE32_HANDLER( dl_control_w )
{
+ //printf("\n"); // Debug - ajg
// TODO: put this back in.
/*
if (activeBuffer==0 || activeBuffer==1)
@@ -1744,6 +1745,7 @@ static DRIVER_INIT(hng64_fght)
static DRIVER_INIT( fatfurwa )
{
+ /* FILE* fp = fopen("/tmp/test.bin", "wb"); fwrite(memory_region(machine, "verts"), 1, 0x0c00000*2, fp); fclose(fp); */
DRIVER_INIT_CALL(hng64_fght);
hng64_mcu_type = FIGHT_MCU;
}
@@ -2013,7 +2015,6 @@ ROM_START( sams64 )
ROM_LOAD( "002-tx03a.15", 0x0800000, 0x400000, CRC(68c313f7) SHA1(90ce8d0d19a994647c7167e3b256ff31647e575a) )
ROM_LOAD( "002-tx04a.16", 0x0c00000, 0x400000, CRC(f7dac24f) SHA1(1215354f28cbeb9fc38f6a7acae450ad5f34bb6a) )
-
/* X,Y,Z Vertex ROMs */
ROM_REGION( 0x1800000, "verts", 0 )
ROMX_LOAD( "002-vt01a.17", 0x0000000, 0x400000, CRC(403fd7fd) SHA1(9bdadbeb4cd13c4c4e89a1c233af9eaaa46f8fdf), ROM_GROUPWORD | ROM_SKIP(4) )
@@ -2268,7 +2269,7 @@ ROM_START( fatfurwa )
ROM_LOAD( "006tx04a.16",0x0c00000, 0x400000, CRC(82d61652) SHA1(28303ae9e2545a4cb0b5843f9e73407754f41e9e) )
/* X,Y,Z Vertex ROMs */
- ROM_REGION16_BE( 0x0c00000, "verts", 0 )
+ ROM_REGION( 0x0c00000, "verts", 0 )
ROMX_LOAD( "006vt01a.17", 0x0000000, 0x400000, CRC(5c20ed4c) SHA1(df679f518292d70b9f23d2bddabf975d56b96910), ROM_GROUPWORD | ROM_SKIP(4) )
ROMX_LOAD( "006vt02a.18", 0x0000002, 0x400000, CRC(150eb717) SHA1(9acb067346eb386256047c0f1d24dc8fcc2118ca), ROM_GROUPWORD | ROM_SKIP(4) )
ROMX_LOAD( "006vt03a.19", 0x0000004, 0x400000, CRC(021cfcaf) SHA1(fb8b5f50d3490b31f0a4c3e6d3ae1b98bae41c97), ROM_GROUPWORD | ROM_SKIP(4) )
@@ -2340,7 +2341,7 @@ ROM_START( buriki )
ROM_LOAD( "007tx04a.16",0x0c00000, 0x400000, CRC(02aa3f46) SHA1(1fca89c70586f8ebcdf669ecac121afa5cdf623f) )
/* X,Y,Z Vertex ROMs */
- ROM_REGION16_BE( 0x0c00000, "verts", 0 )
+ ROM_REGION( 0x0c00000, "verts", 0 )
ROMX_LOAD( "007vt01a.17", 0x0000000, 0x400000, CRC(f78a0376) SHA1(fde4ddd4bf326ae5f1ed10311c237b13b62e060c), ROM_GROUPWORD | ROM_SKIP(4) )
ROMX_LOAD( "007vt02a.18", 0x0000002, 0x400000, CRC(f365f608) SHA1(035fd9b829b7720c4aee6fdf204c080e6157994f), ROM_GROUPWORD | ROM_SKIP(4) )
ROMX_LOAD( "007vt03a.19", 0x0000004, 0x400000, CRC(ba05654d) SHA1(b7fe532732c0af7860c8eded3c5abd304d74e08e), ROM_GROUPWORD | ROM_SKIP(4) )
diff --git a/src/mame/video/hng64.c b/src/mame/video/hng64.c
index e274262d633..667c01c62a6 100644
--- a/src/mame/video/hng64.c
+++ b/src/mame/video/hng64.c
@@ -1510,8 +1510,8 @@ VIDEO_UPDATE( hng64 )
src++;
}
}
- //printf("\n"); /* DEBUG */
- clear3d(screen->machine); /* TODO: Inline */
+ //printf("\n"); /* Debug - ajg */
+ clear3d(screen->machine);
}
if(0)
@@ -1636,7 +1636,7 @@ VIDEO_START( hng64 )
tilemap_set_transparent_pen(hng64_tilemap3_16x16,0);
tilemap_set_transparent_pen(hng64_tilemap3_16x16_alt,0);
- // debug switch, turn on / off additive blending on a per-tilemap basis
+ // Debug switch, turn on / off additive blending on a per-tilemap basis
additive_tilemap_debug = 0;
// 3d Buffer Allocation
@@ -1694,7 +1694,6 @@ static void drawShaded(running_machine *machine, struct polygon *p);
//static void DrawWireframe(struct polygon *p, bitmap_t *bitmap);
static float uToF(UINT16 input);
-#define WORD_AT(BUFFER,OFFSET) ((BUFFER[OFFSET] << 8) | BUFFER[OFFSET+1])
////////////////////
@@ -1846,6 +1845,7 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
// 0118|0108 for fatfurwa fighters infight,
// 0108->0118 for fatfurwa globe (transitions when players are selected,
// 00d8 for segfaulting geo in xrally & roadedge)
+ // (00!0 is thought to be for lighting maybe?)
// [2] - xxxx ... offset into ROM
// [3] - xxxx ... offset into ROM
// [4] - xxxx ... Transformation matrix
@@ -1863,10 +1863,11 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
////////////*/
int k, l, m;
- UINT8 *threeDRoms;
- UINT8 *threeDPointer;
- UINT32 dword1;
- UINT32 threeDOffset;
+ UINT32 tempDWord;
+ UINT32 threeDOffset;
+ UINT16* threeDRoms;
+ UINT16* threeDPointer;
+
UINT32 size[4];
UINT32 address[4];
UINT32 megaOffset;
@@ -1884,36 +1885,40 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
// GEOMETRY
setIdentity(objectMatrix);
- threeDRoms = memory_region(machine, "verts");
-
- /////////////////////////
- // GET THE HEADER INFO //
- /////////////////////////
+ /////////////////
+ // HEADER INFO //
+ /////////////////
// 3d ROM Offset
- // FIXME: This decoding works for buriki and fatfurwa, but not for xrally.
- dword1 = (((UINT32)packet[2]) << 16) | ((UINT32)packet[3]);
- threeDOffset = dword1 & 0x000fffff;
- threeDOffset = (threeDOffset << 1) * 3;
-
- threeDPointer = &threeDRoms[threeDOffset];
-
- // I think this packet entry has something to do with lighting.
- // It's 0 for the 66-byte lit globe in the character select and 0 for something in terry's hand.
- // if (packet[1] & 0x0010)
-
- //////////////////////////////////////////
- // GET THE OBJECT TRANSFORMATION MATRIX //
- //////////////////////////////////////////
- objectMatrix[8 ] = uToF(packet[7]);
- objectMatrix[4 ] = uToF(packet[8]);
- objectMatrix[0 ] = uToF(packet[9]);
- objectMatrix[3] = 0.0f;
-
- objectMatrix[9 ] = uToF(packet[10]);
- objectMatrix[5 ] = uToF(packet[11]);
- objectMatrix[1 ] = uToF(packet[12]);
- objectMatrix[7] = 0.0f;
+ tempDWord = (((UINT32)packet[2]) << 16) | ((UINT32)packet[3]);
+ threeDOffset = tempDWord & 0xffffffff;
+
+ threeDRoms = (UINT16*)(memory_region(machine, "verts"));
+ threeDPointer = &threeDRoms[threeDOffset * 3];
+
+ // Debug - ajg
+ /*
+ printf("%08x : ", tempDWord*3*2);
+ for (k = 0; k < 7*3; k++)
+ {
+ printf("%04x ", threeDPointer[k]);
+ if ((k % 3) == 2) printf(" ");
+ }
+ printf("\n");
+ */
+
+ //////////////////////////////////////
+ // THE OBJECT TRANSFORMATION MATRIX //
+ //////////////////////////////////////
+ objectMatrix[8] = uToF(packet[7]);
+ objectMatrix[4] = uToF(packet[8]);
+ objectMatrix[0] = uToF(packet[9]);
+ objectMatrix[3] = 0.0f;
+
+ objectMatrix[9] = uToF(packet[10]);
+ objectMatrix[5] = uToF(packet[11]);
+ objectMatrix[1] = uToF(packet[12]);
+ objectMatrix[7] = 0.0f;
objectMatrix[10] = uToF(packet[13]);
objectMatrix[6 ] = uToF(packet[14]);
@@ -1929,224 +1934,383 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
//////////////////////////////////////////////////////////
// EXTRACT DATA FROM THE ADDRESS POINTED TO IN THE FILE //
//////////////////////////////////////////////////////////
-
- // Okay, there are 4 hunks per address. They all seem good too...
-
- // First tell me how many 'chunks' are at each address...
- size[0] = WORD_AT(threeDPointer, ( 6<<1));
- size[1] = WORD_AT(threeDPointer, ( 7<<1));
- size[2] = WORD_AT(threeDPointer, ( 9<<1));
- size[3] = WORD_AT(threeDPointer, (10<<1));
-
- megaOffset = ( WORD_AT(threeDRoms, (threeDOffset + 4)) ) << 16;
- address[0] = megaOffset | WORD_AT(threeDPointer, (0<<1));
- address[1] = megaOffset | WORD_AT(threeDPointer, (1<<1));
- address[2] = megaOffset | WORD_AT(threeDPointer, (3<<1));
- address[3] = megaOffset | WORD_AT(threeDPointer, (4<<1));
-
- // DEBUG
- // mame_printf_debug("%.5x %.3x %.5x %.3x %.5x %.3x %.5x %.3x\n", address[0], size[0], address[1], size[1], address[2], size[2], address[3], size[3]);
- // !! END DEBUG !!
-
- for (k = 0; k < 4; k++) // For all 4 chunks
+ /*//////////////////////////////////////////////
+ // DIRECTLY-POINTED-TO FORMAT (7 words x 3 ROMs)
+ // [0] - lower word of sub-address 1
+ // [1] - lower word of sub-address 2
+ // [2] - upper word of all sub-addresses
+ // [3] - lower word of sub-address 3
+ // [4] - lower word of sub-address 4
+ // [5] - ???? always 0 ????
+ // [6] - number of triangles in sub-address 1 block
+ // [7] - number of triangles in sub-address 2 block
+ // [8] - ???? always 0 ????
+ // [9] - number of triangles in sub-address 3 block
+ // [10] - number of triangles in sub-address 4 block
+ // [11] - ? definitely used.
+ // [12] - ? definitely used.
+ // [13] - ? definitely used.
+ // [14] - ? definitely used.
+ // [15] - ???? always 0 ????
+ // [16] - ???? always 0 ????
+ // [17] - ???? always 0 ????
+ // [18] - ???? always 0 ????
+ // [19] - ???? always 0 ????
+ // [20] - ???? always 0 ????
+ //////////////////////////////////////////////*/
+
+ // There are 4 hunks per address.
+ address[0] = threeDPointer[0];
+ address[1] = threeDPointer[1];
+ megaOffset = threeDPointer[2];
+
+ address[2] = threeDPointer[3];
+ address[3] = threeDPointer[4];
+ if (threeDPointer[5] != 0x0000) printf("ZOMG! 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");
+
+ size[2] = threeDPointer[9];
+ size[3] = threeDPointer[10];
+ /* ???? [11]; Used. */
+
+ /* ???? [12]; Used. */
+ /* ???? [13]; Used. */
+ /* ???? [14]; Used. */
+
+ /* ???? [15]; Used? */
+ /* ???? [16]; Used? */
+ /* ???? [17]; Used? */
+
+ /* ???? [18]; Used? */
+ /* ???? [19]; Used? */
+ /* ???? [20]; Used? */
+
+ /* Concatenate the megaOffset with the addresses */
+ address[0] |= (megaOffset << 16);
+ address[1] |= (megaOffset << 16);
+ address[2] |= (megaOffset << 16);
+ address[3] |= (megaOffset << 16);
+
+ /* For all 4 polygon chunks */
+ for (k = 0; k < 4; k++)
{
- threeDPointer = &threeDRoms[(address[k]<<1) * 3];
-
+ threeDPointer = &threeDRoms[address[k] * 3];
for (l = 0; l < size[k]; l++)
{
////////////////////////////////////////////
// GATHER A SINGLE TRIANGLE'S INFORMATION //
////////////////////////////////////////////
- UINT8 triangleType = threeDPointer[1];
-
- UINT8 numVertices = 3;
+ /*/////////////////////////
+ // SINGLE POLY CHUNK FORMAT
+ // [0] ??-- - ???? unused ????
+ // [0] --xx - chunk type
+ // [1] x--- - 'texture type' (or UV-mapping style)?
+ // [1] -??- - ???? '18' for untextured buildings in fatfurwa ????
+ // [1] ---x - texture index
+ // [2] ???? - used in fatfurwa 'hng64' & everywhere in roadedge
+ /////////////////////////*/
UINT8 chunkLength = 0;
+ UINT8 chunkType = threeDPointer[0] & 0x00ff;
+
+ // Debug - ajg
+ //printf("%d (%08x) : %04x %04x %04x ", k, address[k]*3*2, threeDPointer[0], threeDPointer[1], threeDPointer[2]);
+ //break;
- // Some chunks only have 1 vertex (they act as a vertex fan)
- if (triangleType == 0x97 ||
- triangleType == 0x87 ||
- triangleType == 0xd7 ||
- triangleType == 0x96)
- numVertices = 1;
+ // Debug - ajg
+ //if ((threeDPointer[0] & 0xff00) != 0x0000)
+ //{
+ // printf("!!! Doesn't appear to be a valid chunk !!!\n");
+ // continue;
+ //}
// Get which texture this polygon refers to...
- // In fatfur it's 0xc for the smooth-shaded earth - maybe this is for all things with alpha - check the hair at some point...
+ // In fatfur it's 0xc for the smooth-shaded earth - maybe this is for all things with alpha - check the hair at some point.
// 0x9 for the untextured buildings
// 0xd for the 'explosion' of the HNG64
// and 0x8 everywhere else...
// they're 0x8 in the buriki intro too (those are 66-byte chunks!)
- polys[*numPolys].texType = ((threeDPointer[2] & 0xf0) >> 4);
+ polys[*numPolys].texType = ((threeDPointer[1] & 0xf000) >> 4 >> 8);
if (polys[*numPolys].texType == 0x8 || polys[*numPolys].texType == 0xc) // || polys[*numPolys].texType == 0x9
- polys[*numPolys].texIndex = threeDPointer[3] & 0x0f;
+ {
+ polys[*numPolys].texIndex = threeDPointer[1] & 0x000f;
+ }
else
+ {
polys[*numPolys].texIndex = -1;
+ }
// Set the polygon's palette
polys[*numPolys].palIndex = paletteState3d;
- for (m = 0; m < numVertices; m++) // For all vertices of the chunk
+ switch(chunkType)
{
- switch(triangleType)
+ /*/////////////////////////
+ // CHUNK TYPE BITS - These are very likely incorrect.
+ // x--- ---- - 1 = Has only 1 vertex (part of a triangle fan/strip)
+ // -x-- ---- -
+ // --x- ---- -
+ // ---x ---- -
+ // ---- x--- -
+ // ---- -x-- - 1 = Has per-vert UVs
+ // ---- --x- -
+ // ---- ---x - 1 = Has per-vert normals
+ /////////////////////////*/
+
+ // 33 word chunk, 3 vertices, per-vertex UVs & normals
+ case 0x05: // 0000 0101
+ case 0x0f: // 0000 1111
+ for (m = 0; m < 3; m++)
{
- // 42 byte chunk
- case 0x04:
- case 0x0e:
- polys[*numPolys].vert[m].worldCoords[0] = uToF(WORD_AT(threeDPointer, ((3<<1) + (6<<1)*m)) );
- polys[*numPolys].vert[m].worldCoords[1] = uToF(WORD_AT(threeDPointer, ((4<<1) + (6<<1)*m)) );
- polys[*numPolys].vert[m].worldCoords[2] = uToF(WORD_AT(threeDPointer, ((5<<1) + (6<<1)*m)) );
+ polys[*numPolys].vert[m].worldCoords[0] = uToF(threeDPointer[3 + (9*m)]);
+ polys[*numPolys].vert[m].worldCoords[1] = uToF(threeDPointer[4 + (9*m)]);
+ polys[*numPolys].vert[m].worldCoords[2] = uToF(threeDPointer[5 + (9*m)]);
polys[*numPolys].vert[m].worldCoords[3] = 1.0f;
polys[*numPolys].n = 3;
- // !! What is the first coordinate here (6) - maybe denotes size of chunk? !!
- polys[*numPolys].vert[m].texCoords[0] = uToF(WORD_AT(threeDPointer, ((7<<1) + (6<<1)*m)) );
- polys[*numPolys].vert[m].texCoords[1] = uToF(WORD_AT(threeDPointer, ((8<<1) + (6<<1)*m)) );
+ // threeDPointer[6 + (9*m)] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select
+ polys[*numPolys].vert[m].texCoords[0] = uToF(threeDPointer[7 + (9*m)]);
+ polys[*numPolys].vert[m].texCoords[1] = uToF(threeDPointer[8 + (9*m)]);
polys[*numPolys].vert[m].texCoords[2] = 0.0f;
polys[*numPolys].vert[m].texCoords[3] = 1.0f;
- polys[*numPolys].vert[m].normal[0] = uToF(WORD_AT(threeDPointer, (21<<1) ));
- polys[*numPolys].vert[m].normal[1] = uToF(WORD_AT(threeDPointer, (22<<1) ));
- polys[*numPolys].vert[m].normal[2] = uToF(WORD_AT(threeDPointer, (23<<1) ));
+ polys[*numPolys].vert[m].normal[0] = uToF(threeDPointer[9 + (9*m)]);
+ polys[*numPolys].vert[m].normal[1] = uToF(threeDPointer[10 + (9*m)] );
+ polys[*numPolys].vert[m].normal[2] = uToF(threeDPointer[11 + (9*m)] );
polys[*numPolys].vert[m].normal[3] = 0.0f;
// !!! DUMB !!!
polys[*numPolys].vert[m].light[0] = polys[*numPolys].vert[m].texCoords[0] * 255.0f;
polys[*numPolys].vert[m].light[1] = polys[*numPolys].vert[m].texCoords[1] * 255.0f;
polys[*numPolys].vert[m].light[2] = polys[*numPolys].vert[m].texCoords[2] * 255.0f;
+ }
- // Redundantly called, but it works...
- polys[*numPolys].faceNormal[0] = polys[*numPolys].vert[m].normal[0];
- polys[*numPolys].faceNormal[1] = polys[*numPolys].vert[m].normal[1];
- polys[*numPolys].faceNormal[2] = polys[*numPolys].vert[m].normal[2];
- polys[*numPolys].faceNormal[3] = 0.0f;
-
- chunkLength = (24<<1);
- break;
-
- // 66 byte chunk
- case 0x05:
- case 0x0f:
- polys[*numPolys].vert[m].worldCoords[0] = uToF(WORD_AT(threeDPointer, ((3<<1) + (9<<1)*m)) );
- polys[*numPolys].vert[m].worldCoords[1] = uToF(WORD_AT(threeDPointer, ((4<<1) + (9<<1)*m)) );
- polys[*numPolys].vert[m].worldCoords[2] = uToF(WORD_AT(threeDPointer, ((5<<1) + (9<<1)*m)) );
+ // Redundantly called, but it works...
+ polys[*numPolys].faceNormal[0] = uToF(threeDPointer[30]);
+ polys[*numPolys].faceNormal[1] = uToF(threeDPointer[31]);
+ polys[*numPolys].faceNormal[2] = uToF(threeDPointer[32]);
+ polys[*numPolys].faceNormal[3] = 0.0f;
+
+ chunkLength = 33;
+ break;
+
+
+ // 24 word chunk, 3 vertices, per-vertex UVs
+ case 0x04: // 0000 0100
+ case 0x0e: // 0000 1110
+ for (m = 0; m < 3; m++)
+ {
+ polys[*numPolys].vert[m].worldCoords[0] = uToF(threeDPointer[3 + (6*m)]);
+ polys[*numPolys].vert[m].worldCoords[1] = uToF(threeDPointer[4 + (6*m)]);
+ polys[*numPolys].vert[m].worldCoords[2] = uToF(threeDPointer[5 + (6*m)]);
polys[*numPolys].vert[m].worldCoords[3] = 1.0f;
polys[*numPolys].n = 3;
- // !! See above - (6) - why? !!
- polys[*numPolys].vert[m].texCoords[0] = uToF(WORD_AT(threeDPointer, ((7<<1) + (9<<1)*m)) );
- polys[*numPolys].vert[m].texCoords[1] = uToF(WORD_AT(threeDPointer, ((8<<1) + (9<<1)*m)) );
+ // threeDPointer[6 + (6*m)] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select
+ polys[*numPolys].vert[m].texCoords[0] = uToF(threeDPointer[7 + (6*m)]);
+ polys[*numPolys].vert[m].texCoords[1] = uToF(threeDPointer[8 + (6*m)]);
polys[*numPolys].vert[m].texCoords[2] = 0.0f;
polys[*numPolys].vert[m].texCoords[3] = 1.0f;
- polys[*numPolys].vert[m].normal[0] = uToF(WORD_AT(threeDPointer, ((9<<1) + (9<<1)*m)) );
- polys[*numPolys].vert[m].normal[1] = uToF(WORD_AT(threeDPointer, ((10<<1) + (9<<1)*m)) );
- polys[*numPolys].vert[m].normal[2] = uToF(WORD_AT(threeDPointer, ((11<<1) + (9<<1)*m)) );
+ polys[*numPolys].vert[m].normal[0] = uToF(threeDPointer[21]);
+ polys[*numPolys].vert[m].normal[1] = uToF(threeDPointer[22]);
+ polys[*numPolys].vert[m].normal[2] = uToF(threeDPointer[23]);
polys[*numPolys].vert[m].normal[3] = 0.0f;
// !!! DUMB !!!
polys[*numPolys].vert[m].light[0] = polys[*numPolys].vert[m].texCoords[0] * 255.0f;
polys[*numPolys].vert[m].light[1] = polys[*numPolys].vert[m].texCoords[1] * 255.0f;
polys[*numPolys].vert[m].light[2] = polys[*numPolys].vert[m].texCoords[2] * 255.0f;
-
- // Redundantly called, but it works...
- polys[*numPolys].faceNormal[0] = uToF(WORD_AT(threeDPointer, (30<<1) ));
- polys[*numPolys].faceNormal[1] = uToF(WORD_AT(threeDPointer, (31<<1) ));
- polys[*numPolys].faceNormal[2] = uToF(WORD_AT(threeDPointer, (32<<1) ));
- polys[*numPolys].faceNormal[3] = 0.0f;
-
- chunkLength = (33<<1);
- break;
-
- // 30 byte chunk
- case 0x97:
- case 0x87:
- case 0xd7:
-
- // Copy over the proper vertices from the previous triangle...
- memcpy(&polys[*numPolys].vert[1], &lastPoly.vert[0], sizeof(struct polyVert));
- memcpy(&polys[*numPolys].vert[2], &lastPoly.vert[2], sizeof(struct polyVert));
-
- // Fill in the appropriate data...
- polys[*numPolys].vert[0].worldCoords[0] = uToF(WORD_AT(threeDPointer, (3<<1) ));
- polys[*numPolys].vert[0].worldCoords[1] = uToF(WORD_AT(threeDPointer, (4<<1) ));
- polys[*numPolys].vert[0].worldCoords[2] = uToF(WORD_AT(threeDPointer, (5<<1) ));
- polys[*numPolys].vert[0].worldCoords[3] = 1.0f;
- polys[*numPolys].n = 3;
-
- // !! See above - (6) - why? !!
- polys[*numPolys].vert[0].texCoords[0] = uToF(WORD_AT(threeDPointer, (7<<1) ));
- polys[*numPolys].vert[0].texCoords[1] = uToF(WORD_AT(threeDPointer, (8<<1) ));
- polys[*numPolys].vert[0].texCoords[2] = 0.0f;
- polys[*numPolys].vert[0].texCoords[3] = 1.0f;
-
- polys[*numPolys].vert[0].normal[0] = uToF(WORD_AT(threeDPointer, (9<<1) ));
- polys[*numPolys].vert[0].normal[1] = uToF(WORD_AT(threeDPointer, (10<<1) ));
- polys[*numPolys].vert[0].normal[2] = uToF(WORD_AT(threeDPointer, (11<<1) ));
- polys[*numPolys].vert[0].normal[3] = 0.0f;
-
- polys[*numPolys].vert[0].light[0] = polys[*numPolys].vert[0].texCoords[0] * 255.0f;
- polys[*numPolys].vert[0].light[1] = polys[*numPolys].vert[0].texCoords[1] * 255.0f;
- polys[*numPolys].vert[0].light[2] = polys[*numPolys].vert[0].texCoords[2] * 255.0f;
-
- polys[*numPolys].faceNormal[0] = uToF(WORD_AT(threeDPointer, (12<<1) ));
- polys[*numPolys].faceNormal[1] = uToF(WORD_AT(threeDPointer, (13<<1) ));
- polys[*numPolys].faceNormal[2] = uToF(WORD_AT(threeDPointer, (14<<1) ));
- polys[*numPolys].faceNormal[3] = 0.0f;
-
- chunkLength = (15<<1);
- break;
-
- // 18 byte chunk
- case 0x96:
-
- // Copy over the proper vertices from the previous triangle...
- memcpy(&polys[*numPolys].vert[1], &lastPoly.vert[0], sizeof(struct polyVert));
- memcpy(&polys[*numPolys].vert[2], &lastPoly.vert[2], sizeof(struct polyVert));
-
- // !!! Too lazy to have finished this yet !!!
-
- polys[*numPolys].vert[0].worldCoords[0] = uToF(WORD_AT(threeDPointer, (3<<1)));
- polys[*numPolys].vert[0].worldCoords[1] = uToF(WORD_AT(threeDPointer, (4<<1)));
- polys[*numPolys].vert[0].worldCoords[2] = uToF(WORD_AT(threeDPointer, (5<<1)));
- polys[*numPolys].vert[0].worldCoords[3] = 1.0f;
- polys[*numPolys].n = 3;
-
- // !! See above - (6) - why? !!
- polys[*numPolys].vert[0].texCoords[0] = uToF(WORD_AT(threeDPointer, (7<<1)));
- polys[*numPolys].vert[0].texCoords[1] = uToF(WORD_AT(threeDPointer, (8<<1)));
- polys[*numPolys].vert[0].texCoords[2] = 0.0f;
- polys[*numPolys].vert[0].texCoords[3] = 1.0f;
-
- // !!! DUMB !!!
- polys[*numPolys].vert[0].light[0] = polys[*numPolys].vert[0].texCoords[0] * 255.0f;
- polys[*numPolys].vert[0].light[1] = polys[*numPolys].vert[0].texCoords[1] * 255.0f;
- polys[*numPolys].vert[0].light[2] = polys[*numPolys].vert[0].texCoords[2] * 255.0f;
-
- // This normal could be right, but I'm not entirely sure - there is no normal in the 18 bytes!
- polys[*numPolys].vert[0].normal[0] = lastPoly.faceNormal[0];
- polys[*numPolys].vert[0].normal[1] = lastPoly.faceNormal[1];
- polys[*numPolys].vert[0].normal[2] = lastPoly.faceNormal[2];
- polys[*numPolys].vert[0].normal[3] = lastPoly.faceNormal[3];
-
- polys[*numPolys].faceNormal[0] = lastPoly.faceNormal[0];
- polys[*numPolys].faceNormal[1] = lastPoly.faceNormal[1];
- polys[*numPolys].faceNormal[2] = lastPoly.faceNormal[2];
- polys[*numPolys].faceNormal[3] = lastPoly.faceNormal[3];
-
- chunkLength = (9<<1);
- break;
-
- default:
- mame_printf_debug("UNKNOWN geometry CHUNK TYPE : %x\n", triangleType);
- break;
}
+
+ // Redundantly called, but it works...
+ polys[*numPolys].faceNormal[0] = polys[*numPolys].vert[m].normal[0];
+ polys[*numPolys].faceNormal[1] = polys[*numPolys].vert[m].normal[1];
+ polys[*numPolys].faceNormal[2] = polys[*numPolys].vert[m].normal[2];
+ polys[*numPolys].faceNormal[3] = 0.0f;
+
+ chunkLength = 24;
+ break;
+
+
+ // 15 word chunk, 1 vertex, per-vertex UVs & normals
+ case 0x97: // 1001 0111
+ case 0x87: // 1000 0111
+ case 0xd7: // 1101 0111
+ // Copy over the proper vertices from the previous triangle...
+ memcpy(&polys[*numPolys].vert[1], &lastPoly.vert[0], sizeof(struct polyVert));
+ memcpy(&polys[*numPolys].vert[2], &lastPoly.vert[2], sizeof(struct polyVert));
+
+ // Fill in the appropriate data...
+ polys[*numPolys].vert[0].worldCoords[0] = uToF(threeDPointer[3]);
+ polys[*numPolys].vert[0].worldCoords[1] = uToF(threeDPointer[4]);
+ polys[*numPolys].vert[0].worldCoords[2] = uToF(threeDPointer[5]);
+ polys[*numPolys].vert[0].worldCoords[3] = 1.0f;
+ polys[*numPolys].n = 3;
+
+ // threeDPointer[6] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select
+ polys[*numPolys].vert[0].texCoords[0] = uToF(threeDPointer[7]);
+ polys[*numPolys].vert[0].texCoords[1] = uToF(threeDPointer[8]);
+ polys[*numPolys].vert[0].texCoords[2] = 0.0f;
+ polys[*numPolys].vert[0].texCoords[3] = 1.0f;
+
+ polys[*numPolys].vert[0].normal[0] = uToF(threeDPointer[9]);
+ polys[*numPolys].vert[0].normal[1] = uToF(threeDPointer[10]);
+ polys[*numPolys].vert[0].normal[2] = uToF(threeDPointer[11]);
+ polys[*numPolys].vert[0].normal[3] = 0.0f;
+
+ polys[*numPolys].vert[0].light[0] = polys[*numPolys].vert[0].texCoords[0] * 255.0f;
+ polys[*numPolys].vert[0].light[1] = polys[*numPolys].vert[0].texCoords[1] * 255.0f;
+ polys[*numPolys].vert[0].light[2] = polys[*numPolys].vert[0].texCoords[2] * 255.0f;
+
+ polys[*numPolys].faceNormal[0] = uToF(threeDPointer[12]);
+ polys[*numPolys].faceNormal[1] = uToF(threeDPointer[13]);
+ polys[*numPolys].faceNormal[2] = uToF(threeDPointer[14]);
+ polys[*numPolys].faceNormal[3] = 0.0f;
+
+ chunkLength = 15;
+ break;
+
+
+ // 12 word chunk, 1 vertex, per-vertex UVs
+ case 0x96: // 1001 0110
+ // Copy over the proper vertices from the previous triangle...
+ memcpy(&polys[*numPolys].vert[1], &lastPoly.vert[0], sizeof(struct polyVert));
+ memcpy(&polys[*numPolys].vert[2], &lastPoly.vert[2], sizeof(struct polyVert));
+
+ polys[*numPolys].vert[0].worldCoords[0] = uToF(threeDPointer[3]);
+ polys[*numPolys].vert[0].worldCoords[1] = uToF(threeDPointer[4]);
+ polys[*numPolys].vert[0].worldCoords[2] = uToF(threeDPointer[5]);
+ polys[*numPolys].vert[0].worldCoords[3] = 1.0f;
+ polys[*numPolys].n = 3;
+
+ // threeDPointer[6] is almost always 0080, but it's 0070 for the translucent globe in fatfurwa player select
+ polys[*numPolys].vert[0].texCoords[0] = uToF(threeDPointer[7]);
+ polys[*numPolys].vert[0].texCoords[1] = uToF(threeDPointer[8]);
+ polys[*numPolys].vert[0].texCoords[2] = 0.0f;
+ polys[*numPolys].vert[0].texCoords[3] = 1.0f;
+
+ // !!! DUMB !!!
+ polys[*numPolys].vert[0].light[0] = polys[*numPolys].vert[0].texCoords[0] * 255.0f;
+ polys[*numPolys].vert[0].light[1] = polys[*numPolys].vert[0].texCoords[1] * 255.0f;
+ polys[*numPolys].vert[0].light[2] = polys[*numPolys].vert[0].texCoords[2] * 255.0f;
+
+ // This normal could be right, but I'm not entirely sure - there is no normal in the 18 bytes!
+ polys[*numPolys].vert[0].normal[0] = lastPoly.faceNormal[0];
+ polys[*numPolys].vert[0].normal[1] = lastPoly.faceNormal[1];
+ polys[*numPolys].vert[0].normal[2] = lastPoly.faceNormal[2];
+ polys[*numPolys].vert[0].normal[3] = lastPoly.faceNormal[3];
+
+ polys[*numPolys].faceNormal[0] = lastPoly.faceNormal[0];
+ polys[*numPolys].faceNormal[1] = lastPoly.faceNormal[1];
+ polys[*numPolys].faceNormal[2] = lastPoly.faceNormal[2];
+ polys[*numPolys].faceNormal[3] = lastPoly.faceNormal[3];
+
+ // TODO: I'm not reading 3 necessary words here (maybe face normal) !!!
+
+ chunkLength = 12;
+ break;
+
+#if 0
+ // TODO: DECODE THESE GUYS //
+ case 0x2e: // 0010 1110
+ /* There's something fishy about this guy - see 0x7a below. Very likely not fixed-length */
+ /*
+ printf("0x2e : %08x\n", address[k]*3*2);
+ for (m = 0; m < 37; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 36;
+ break;
+
+ /* This shouldn't exist. */
+ /* There's something funky going on with 0x2e - it's often well-behaved, except for
+ when it "ends" with e67a. Maybe this chunkLength thing isn't where it's at?
+ Luckily the 0x7a is always at the end of a series of 2 chunks (2e,7a) so ignoring
+ it won't kill us for now. */
+ case 0x7a: // 0111 1010
+ /*
+ printf("0x7a : %08x (%d/%d)\n", mame_rand(machine), l, size[k]);
+ for (m = 0; m < 100; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 0;
+ break;
+
+ case 0x24: // 0010 0100
+ /*
+ printf("0x24 : %08x\n", address[k]*3*2);
+ for (m = 0; m < 49; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 48;
+ break;
+
+ case 0xb6: // 1011 0110
+ /*
+ printf("0xb6 : %08x\n", address[k]*3*2);
+ for (m = 0; m < 13; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 12;
+ break;
+
+ case 0x86: // 1000 0110
+ /* Very likely not fixed-length since it leads into c6 & d6 */
+ /*
+ printf("0x86 : %08x\n", address[k]*3*2);
+ for (m = 0; m < 13; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 12;
+ break;
+
+ /* Are c6 and d6 just insanely long? They aren't at the end of the numTris like 0x7a */
+ case 0xc6: // 1100 0110
+ /*
+ printf("0xc6 : %08x (%d/%d)\n", address[k]*3*2, l, size[k]);
+ for (m = 0; m < 100; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 0;
+ break;
+
+ /* Are c6 and d6 just insanely long? They aren't at the end of numTris like 0x7a */
+ case 0xd6: // 1101 0110
+ /*
+ printf("0xd6 : %08x (%d/%d)\n", address[k]*3*2, l, size[k]);
+ for (m = 0; m < 100; m++)
+ printf("%04x ", threeDPointer[m]);
+ printf("\n\n");
+ */
+ chunkLength = 0;
+ break;
+#endif
+
+ default:
+ logerror("UNKNOWN geometry CHUNK TYPE : %02x\n", chunkType);
+ chunkLength = 0;
+ break;
}
+ // Debug - ajg
+ //printf("(chunkLength %d)\n", chunkLength);
+
polys[*numPolys].visible = 1;
- // Backup the last polygon (for tri strips)
+ // Backup the last polygon (for triangle fans [strips?])
memcpy(&lastPoly, &polys[*numPolys], sizeof(struct polygon));
+
////////////////////////////////////
// Project and clip //
////////////////////////////////////
@@ -2156,7 +2320,6 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
matmul4(modelViewMatrix, modelViewMatrix, cameraMatrix);
matmul4(modelViewMatrix, modelViewMatrix, objectMatrix);
-
// BACKFACE CULL //
// EMPIRICAL EVIDENCE SEEMS TO SHOW THE HNG64 HARDWARE DOES NOT BACKFACE CULL //
/*
@@ -2179,7 +2342,6 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
// BEHIND-THE-CAMERA CULL //
vecmatmul4(cullRay, modelViewMatrix, polys[*numPolys].vert[0].worldCoords);
-
if (cullRay[2] > 0.0f) // Camera is pointing down -Z
{
polys[*numPolys].visible = 0;
@@ -2230,8 +2392,8 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
if (chunkLength == (9 << 1))
{
mame_printf_debug("Chunk : ");
- for (int ajg = 0; ajg < chunkLength; ajg+=2)
- mame_printf_debug("%.2x%.2x ", threeDPointer[ajg], threeDPointer[ajg+1]);
+ for (int a = 0; a < chunkLength; a+=2)
+ mame_printf_debug("%.2x%.2x ", threeDPointer[a], threeDPointer[a+1]);
mame_printf_debug("\n");
}
// END DEBUG
@@ -2240,7 +2402,7 @@ void recoverPolygonBlock(running_machine* machine, const UINT16* packet, struct
// Advance to the next polygon chunk...
threeDPointer += chunkLength;
- (*numPolys)++; // Add one more to the display list...
+ (*numPolys)++;
}
}
}
@@ -2279,10 +2441,11 @@ void hng64_command3d(running_machine* machine, const UINT16* packet)
{
int i;
- // A temporary place to put some polygons.
+ /* A temporary place to put some polygons. This will optimize away if the compiler's any good. */
int numPolys = 0;
- struct polygon* polys = malloc(sizeof(struct polygon) * (1024*5)); /* This will optimize globally if the compiler's any good */
+ struct polygon* polys = malloc(sizeof(struct polygon) * (1024*5));
+ //printf("packet type : %04x\n", packet[0]);
switch (packet[0])
{
case 0x0000: // Appears to be a NOP.
@@ -2292,7 +2455,8 @@ void hng64_command3d(running_machine* machine, const UINT16* packet)
setCameraTransformation(packet);
break;
- case 0x0010: // Unknown (called twice for fatfurwa 'howto' frame)
+ case 0x0010: // Unknown
+ // Called very interestingly per-frame in every game. Floats for sure. Light-related?
break;
case 0x0011: // Palette / Model flags?
@@ -2304,7 +2468,6 @@ void hng64_command3d(running_machine* machine, const UINT16* packet)
break;
case 0x0100: // Geometry
- //printPacket(packet, 1);
recoverPolygonBlock(machine, packet, polys, &numPolys);
/* Immeditately rasterize the chunk's polygons into the display buffer */
@@ -2327,15 +2490,13 @@ void hng64_command3d(running_machine* machine, const UINT16* packet)
break;
case 0x1000: // Unknown: Some sort of global flags?
- //printPacket(packet, 1);
break;
- case 0x1001: // Unknown: Some sort of global flags?
- //printPacket(packet, 1);
+ case 0x1001: // Unknown: Some sort of global flags (a group of 4, actually)?
break;
default:
- logerror("HNG64: Unknown 3d command %04x.\n", packet[0]);
+ printf("HNG64: Unknown 3d command %04x.\n", packet[0]);
break;
}