diff options
author | Ville Linde <villelin@mamedev.org> | 2012-02-25 15:31:26 +0000 |
---|---|---|
committer | Ville Linde <villelin@mamedev.org> | 2012-02-25 15:31:26 +0000 |
commit | d4b608c178371e223ef55382482c6bf686650a9d (patch) | |
tree | 3cff3c3815a09adb5cd6ea09a97c3347ad0d29c8 | |
parent | e1b983d6588a190f57301382cb975e0c70e7fb6e (diff) |
gticlub: Rewrote the 3D renderer. Implemented gouraud shading, lighting and fog. [Ville Linde]
-rw-r--r-- | src/mame/video/gticlub.c | 1144 |
1 files changed, 829 insertions, 315 deletions
diff --git a/src/mame/video/gticlub.c b/src/mame/video/gticlub.c index d359c8d4d4f..064481ff8d4 100644 --- a/src/mame/video/gticlub.c +++ b/src/mame/video/gticlub.c @@ -6,16 +6,44 @@ #include "video/konicdev.h" #include "video/gticlub.h" +/* + TODO: + - Fog equation and parameters are probably not accurate. + - Winding Heat (and maybe others) have slight Z-fighting problems. + - 3D isn't always turned off properly (during title screens for example). + Figure out what controls this. Video mixer, layer priority or some 3D register? + +*/ + +#define POLY_Z 0 +#define POLY_BRI 2 +#define POLY_FOG 1 +#define POLY_U 3 +#define POLY_V 4 +#define POLY_W 5 + +#define ZBUFFER_MAX 10000000000.0f + +#define LOG_POLY_FIFO 0 + +#if LOG_POLY_FIFO +static int count = 0; +#endif typedef struct _poly_extra_data poly_extra_data; struct _poly_extra_data { UINT32 color; int texture_x, texture_y; + int texture_width, texture_height; int texture_page; int texture_palette; int texture_mirror_x; int texture_mirror_y; + int light_r, light_g, light_b; + int ambient_r, ambient_g, ambient_b; + int fog_r, fog_g, fog_b; + UINT32 flags; }; static UINT8 gticlub_led_reg[2]; @@ -120,7 +148,7 @@ static void K001006_w(int chip, int offset, UINT32 data, UINT32 mem_mask) } default: { - mame_printf_debug("K001006_w: chip %d, device %02X, write %04X to %08X\n", chip, K001006_device_sel[chip], data & 0xffff, K001006_addr[0]++); + //mame_printf_debug("K001006_w: chip %d, device %02X, write %04X to %08X\n", chip, K001006_device_sel[chip], data & 0xffff, K001006_addr[0]++); } } } @@ -181,16 +209,22 @@ static int K001005_fifo_write_ptr = 0; static UINT32 *K001005_3d_fifo; static int K001005_3d_fifo_ptr = 0; -static int tex_mirror_table[4][128]; +static int *tex_mirror_table[2][8]; static int K001005_bitmap_page = 0; static poly_manager *poly; static poly_vertex prev_v[4]; -static int prev_poly_type; -static UINT8 *gfxrom; +static UINT32 fog_r, fog_g, fog_b; +static UINT32 ambient_r, ambient_g, ambient_b; +static UINT32 light_r, light_g, light_b; +static UINT32 reg_far_z; +static float far_z; +static float fog_density = 1.5f; + +static UINT8 *gfxrom; static void K001005_exit(running_machine &machine) { @@ -199,7 +233,7 @@ static void K001005_exit(running_machine &machine) void K001005_init(running_machine &machine) { - int i; + int i,k; int width = machine.primary_screen->width(); int height = machine.primary_screen->height(); @@ -219,15 +253,21 @@ void K001005_init(running_machine &machine) K001005_3d_fifo = auto_alloc_array(machine, UINT32, 0x10000); - poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS); + poly = poly_alloc(machine, 10000, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS); machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(K001005_exit), &machine)); - for (i=0; i < 128; i++) + for (k=0; k < 8; k++) { - tex_mirror_table[0][i] = i & 0x3f; - tex_mirror_table[1][i] = i & 0x3f; - tex_mirror_table[2][i] = ((i & 0x3f) >= 0x20) ? (0x1f - (i & 0x1f)) : i & 0x1f; - tex_mirror_table[3][i] = ((i & 0x7f) >= 0x40) ? (0x3f - (i & 0x3f)) : i & 0x3f; + tex_mirror_table[0][k] = auto_alloc_array(machine, int, 128); + tex_mirror_table[1][k] = auto_alloc_array(machine, int, 128); + + int size = (k+1)*8; + + for (i=0; i < 128; i++) + { + tex_mirror_table[0][k][i] = i % size; + tex_mirror_table[1][k][i] = (i % (size*2)) >= size ? ((size - 1) - (i % size)) : i % size; + } } K001005_status = 0; @@ -237,8 +277,7 @@ void K001005_init(running_machine &machine) K001005_3d_fifo_ptr = 0; K001005_bitmap_page = 0; - memset(prev_v, 0, sizeof(prev_v)); - prev_poly_type = 0; + memset(prev_v, 0, sizeof(poly_vertex)*4); } // rearranges the texture data to a more practical order @@ -386,8 +425,25 @@ WRITE32_HANDLER( K001005_w ) K001005_fifo_write_ptr++; K001005_fifo_write_ptr &= 0x7ff; + // process the current vertex data if a sync command is being sent (usually means the global registers are being changed) + if (data == 0x80000000) + { + render_polygons(space->machine()); + K001005_3d_fifo_ptr = 0; + } + K001005_3d_fifo[K001005_3d_fifo_ptr++] = data; +#if LOG_POLY_FIFO + printf("0x%08X, ", data); + count++; + if (count >= 8) + { + count = 0; + printf("\n"); + } +#endif + // !!! HACK to get past the FIFO B test (GTI Club & Thunder Hurricane) !!! if (cpu_get_pc(&space->device()) == 0x201ee) { @@ -404,11 +460,47 @@ WRITE32_HANDLER( K001005_w ) break; } - case 0x100: break; + case 0x100: break; + + case 0x101: break; // viewport x and width? + case 0x102: break; // viewport y and height? + + case 0x104: break; // viewport center x? (usually 0xff) + case 0x105: break; // viewport center y? (usually 0xbf) + + case 0x108: // far Z value, 4 exponent bits? + { + // this register seems to hold the 4 missing exponent bits... + reg_far_z = (reg_far_z & 0x0000ffff) | ((data & 0xf) << 16); + UINT32 fz = reg_far_z << 11; + far_z = *(float*)&fz; + if (far_z == 0.0f) // just in case... + far_z = 1.0f; + break; + } + + case 0x109: // far Z value + { + // the SHARC code throws away the bottom 11 bits of mantissa and the top 5 bits (to fit in a 16-bit register?) + reg_far_z = (reg_far_z & 0xffff0000) | (data & 0xffff); + UINT32 fz = reg_far_z << 11; + far_z = *(float*)&fz; + if (far_z == 0.0f) // just in case... + far_z = 1.0f; + break; + } - // case 0x10a: poly_r = data & 0xff; break; - // case 0x10b: poly_g = data & 0xff; break; - // case 0x10c: poly_b = data & 0xff; break; + case 0x10a: light_r = data & 0xff; break; + case 0x10b: light_g = data & 0xff; break; + case 0x10c: light_b = data & 0xff; break; + + case 0x10d: ambient_r = data & 0xff; break; + case 0x10e: ambient_g = data & 0xff; break; + case 0x10f: ambient_b = data & 0xff; break; + + case 0x110: fog_r = data & 0xff; break; + case 0x111: fog_g = data & 0xff; break; + case 0x112: fog_b = data & 0xff; break; case 0x11a: K001005_status = data; @@ -417,10 +509,17 @@ WRITE32_HANDLER( K001005_w ) if (data == 2 && K001005_3d_fifo_ptr > 0) { - K001005_swap_buffers(space->machine()); render_polygons(space->machine()); poly_wait(poly, "render_polygons"); + +#if LOG_POLY_FIFO + count = 0; + printf("\nrender %d\n", K001005_3d_fifo_ptr); + printf("------------------------------------\n"); +#endif + K001005_3d_fifo_ptr = 0; + K001005_swap_buffers(space->machine()); } break; @@ -451,31 +550,130 @@ WRITE32_HANDLER( K001005_w ) } +static void draw_scanline_2d(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid) +{ + const poly_extra_data *extra = (const poly_extra_data *)extradata; + bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest; + UINT32 *fb = &destmap->pix32(scanline); + float *zb = (float*)&K001005_zbuffer->pix32(scanline); + UINT32 color = extra->color; + int x; + + for (x = extent->startx; x < extent->stopx; x++) + { + if (color & 0xff000000) + { + fb[x] = color; + zb[x] = 0x7fffffff; // FIXME + } + } +} + +static void draw_scanline_2d_tex(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid) +{ + const poly_extra_data *extra = (const poly_extra_data *)extradata; + bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest; + UINT8 *texrom = gfxrom + (extra->texture_page * 0x40000); + int pal_chip = (extra->texture_palette & 0x8) ? 1 : 0; + int palette_index = (extra->texture_palette & 0x7) * 256; + float u = extent->param[POLY_U].start; + float v = extent->param[POLY_V].start; + float du = extent->param[POLY_U].dpdx; + float dv = extent->param[POLY_V].dpdx; + UINT32 *fb = &destmap->pix32(scanline); + float *zb = (float*)&K001005_zbuffer->pix32(scanline); + UINT32 color = extra->color; + int texture_mirror_x = extra->texture_mirror_x; + int texture_mirror_y = extra->texture_mirror_y; + int texture_x = extra->texture_x; + int texture_y = extra->texture_y; + int texture_width = extra->texture_width; + int texture_height = extra->texture_height; + int x; + + int *x_mirror_table = tex_mirror_table[texture_mirror_x][texture_width]; + int *y_mirror_table = tex_mirror_table[texture_mirror_y][texture_height]; + + for (x = extent->startx; x < extent->stopx; x++) + { + int iu = (int)(u); + int iv = (int)(v); + int iiv, iiu, texel; + + iiu = texture_x + x_mirror_table[(iu >> 4) & 0x7f]; + iiv = texture_y + y_mirror_table[(iv >> 4) & 0x7f]; + + texel = texrom[((iiv & 0x1ff) * 512) + (iiu & 0x1ff)]; + color = K001006_palette[pal_chip][palette_index + texel]; + + if (color & 0xff000000) + { + fb[x] = color; + zb[x] = 0x7fffffff; // FIXME + } + + u += du; + v += dv; + } +} + static void draw_scanline(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid) { const poly_extra_data *extra = (const poly_extra_data *)extradata; bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest; - float z = extent->param[0].start; - float dz = extent->param[0].dpdx; + float z = extent->param[POLY_Z].start; + float dz = extent->param[POLY_Z].dpdx; + float bri = extent->param[POLY_BRI].start; + float dbri = extent->param[POLY_BRI].dpdx; + float fog = extent->param[POLY_FOG].start; + float dfog = extent->param[POLY_FOG].dpdx; UINT32 *fb = &destmap->pix32(scanline); - UINT32 *zb = &K001005_zbuffer->pix32(scanline); + float *zb = (float*)&K001005_zbuffer->pix32(scanline); UINT32 color = extra->color; int x; + int poly_light_r = extra->light_r + extra->ambient_r; + int poly_light_g = extra->light_g + extra->ambient_g; + int poly_light_b = extra->light_b + extra->ambient_b; + if (poly_light_r > 255) poly_light_r = 255; + if (poly_light_g > 255) poly_light_g = 255; + if (poly_light_b > 255) poly_light_b = 255; + int poly_fog_r = extra->fog_r; + int poly_fog_g = extra->fog_g; + int poly_fog_b = extra->fog_b; + for (x = extent->startx; x < extent->stopx; x++) { - UINT32 iz = (UINT32)z >> 16; + int ibri = (int)(bri); + int ifog = (int)(fog); - if (iz <= zb[x]) + if (ibri < 0) ibri = 0; if (ibri > 255) ibri = 255; + if (ifog < 0) ifog = 0; if (ifog > 65536) ifog = 65536; + + if (z <= zb[x]) { if (color & 0xff000000) { - fb[x] = color; - zb[x] = iz; + int r = (color >> 16) & 0xff; + int g = (color >> 8) & 0xff; + int b = color & 0xff; + + r = ((((r * poly_light_r * ibri) >> 16) * ifog) + (poly_fog_r * (65536 - ifog))) >> 16; + g = ((((g * poly_light_g * ibri) >> 16) * ifog) + (poly_fog_g * (65536 - ifog))) >> 16; + b = ((((b * poly_light_b * ibri) >> 16) * ifog) + (poly_fog_b * (65536 - ifog))) >> 16; + + if (r < 0) r = 0; if (r > 255) r = 255; + if (g < 0) g = 0; if (g > 255) g = 255; + if (b < 0) b = 0; if (b > 255) b = 255; + + fb[x] = (color & 0xff000000) | (r << 16) | (g << 8) | b; + zb[x] = z; } } z += dz; + bri += dbri; + fog += dfog; } } @@ -486,30 +684,50 @@ static void draw_scanline_tex(void *dest, INT32 scanline, const poly_extent *ext UINT8 *texrom = gfxrom + (extra->texture_page * 0x40000); int pal_chip = (extra->texture_palette & 0x8) ? 1 : 0; int palette_index = (extra->texture_palette & 0x7) * 256; - float z = extent->param[0].start; - float u = extent->param[1].start; - float v = extent->param[2].start; - float w = extent->param[3].start; - float dz = extent->param[0].dpdx; - float du = extent->param[1].dpdx; - float dv = extent->param[2].dpdx; - float dw = extent->param[3].dpdx; + float z = extent->param[POLY_Z].start; + float u = extent->param[POLY_U].start; + float v = extent->param[POLY_V].start; + float w = extent->param[POLY_W].start; + float dz = extent->param[POLY_Z].dpdx; + float du = extent->param[POLY_U].dpdx; + float dv = extent->param[POLY_V].dpdx; + float dw = extent->param[POLY_W].dpdx; + float bri = extent->param[POLY_BRI].start; + float dbri = extent->param[POLY_BRI].dpdx; + float fog = extent->param[POLY_FOG].start; + float dfog = extent->param[POLY_FOG].dpdx; int texture_mirror_x = extra->texture_mirror_x; int texture_mirror_y = extra->texture_mirror_y; int texture_x = extra->texture_x; int texture_y = extra->texture_y; + int texture_width = extra->texture_width; + int texture_height = extra->texture_height; int x; + int poly_light_r = extra->light_r + extra->ambient_r; + int poly_light_g = extra->light_g + extra->ambient_g; + int poly_light_b = extra->light_b + extra->ambient_b; + if (poly_light_r > 255) poly_light_r = 255; + if (poly_light_g > 255) poly_light_g = 255; + if (poly_light_b > 255) poly_light_b = 255; + int poly_fog_r = extra->fog_r; + int poly_fog_g = extra->fog_g; + int poly_fog_b = extra->fog_b; + UINT32 *fb = &destmap->pix32(scanline); - UINT32 *zb = &K001005_zbuffer->pix32(scanline); + float *zb = (float*)&K001005_zbuffer->pix32(scanline); + int *x_mirror_table = tex_mirror_table[texture_mirror_x][texture_width]; + int *y_mirror_table = tex_mirror_table[texture_mirror_y][texture_height]; for (x = extent->startx; x < extent->stopx; x++) { - UINT32 iz = (UINT32)z >> 16; - //int iu = u >> 16; - //int iv = v >> 16; + int ibri = (int)(bri); + int ifog = (int)(fog); - if (iz < zb[x]) + if (ibri < 0) ibri = 0; if (ibri > 255) ibri = 255; + if (ifog < 0) ifog = 0; if (ifog > 65536) ifog = 65536; + + if (z <= zb[x]) { float oow = 1.0f / w; UINT32 color; @@ -519,15 +737,28 @@ static void draw_scanline_tex(void *dest, INT32 scanline, const poly_extent *ext iu = u * oow; iv = v * oow; - iiu = texture_x + tex_mirror_table[texture_mirror_x][(iu >> 4) & 0x7f]; - iiv = texture_y + tex_mirror_table[texture_mirror_y][(iv >> 4) & 0x7f]; + iiu = texture_x + x_mirror_table[(iu >> 4) & 0x7f]; + iiv = texture_y + y_mirror_table[(iv >> 4) & 0x7f]; + texel = texrom[((iiv & 0x1ff) * 512) + (iiu & 0x1ff)]; color = K001006_palette[pal_chip][palette_index + texel]; if (color & 0xff000000) { - fb[x] = color; - zb[x] = iz; + int r = (color >> 16) & 0xff; + int g = (color >> 8) & 0xff; + int b = color & 0xff; + + r = ((((r * poly_light_r * ibri) >> 16) * ifog) + (poly_fog_r * (65536 - ifog))) >> 16; + g = ((((g * poly_light_g * ibri) >> 16) * ifog) + (poly_fog_g * (65536 - ifog))) >> 16; + b = ((((b * poly_light_b * ibri) >> 16) * ifog) + (poly_fog_b * (65536 - ifog))) >> 16; + + if (r < 0) r = 0; if (r > 255) r = 255; + if (g < 0) g = 0; if (g > 255) g = 255; + if (b < 0) b = 0; if (b > 255) b = 255; + + fb[x] = 0xff000000 | (r << 16) | (g << 8) | b; + zb[x] = z; } } @@ -535,405 +766,683 @@ static void draw_scanline_tex(void *dest, INT32 scanline, const poly_extent *ext v += dv; z += dz; w += dw; + bri += dbri; + fog += dfog; } } static void render_polygons(running_machine &machine) { - int i, j; const rectangle visarea = machine.primary_screen->visible_area(); + poly_vertex v[4]; + int poly_type; + int brightness; -// mame_printf_debug("K001005_fifo_ptr = %08X\n", K001005_3d_fifo_ptr); + poly_vertex *vertex1; + poly_vertex *vertex2; + poly_vertex *vertex3; + poly_vertex *vertex4; - for (i=0; i < K001005_3d_fifo_ptr; i++) - { - if (K001005_3d_fifo[i] == 0x80000003) - { - poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); - poly_vertex v[4]; - int r, g, b, a; - UINT32 color; - int index = i; - - ++index; - - for (j=0; j < 4; j++) - { - int x, y; + UINT32 *fifo = K001005_3d_fifo; - x = ((K001005_3d_fifo[index] >> 0) & 0x3fff); - y = ((K001005_3d_fifo[index] >> 16) & 0x1fff); - x |= ((x & 0x2000) ? 0xffffc000 : 0); - y |= ((y & 0x1000) ? 0xffffe000 : 0); - ++index; - - v[j].x = ((float)(x) / 16.0f) + 256.0f; - v[j].y = ((float)(-y) / 16.0f) + 192.0f; - v[j].p[0] = 0; /* ??? */ - } - - ++index; - - r = (K001005_3d_fifo[index] >> 0) & 0xff; - g = (K001005_3d_fifo[index] >> 8) & 0xff; - b = (K001005_3d_fifo[index] >> 16) & 0xff; - a = (K001005_3d_fifo[index] >> 24) & 0xff; - color = (a << 24) | (r << 16) | (g << 8) | (b); - ++index; - - extra->color = color; - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, &v[0], &v[1], &v[2]); - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, &v[0], &v[2], &v[3]); -// poly_render_polygon(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, 4, v); + int index = 0; - i = index - 1; - } - else if (K001005_3d_fifo[i] == 0x800000ae || K001005_3d_fifo[i] == 0x8000008e || - K001005_3d_fifo[i] == 0x80000096 || K001005_3d_fifo[i] == 0x800000b6 || - K001005_3d_fifo[i] == 0x8000002e || K001005_3d_fifo[i] == 0x8000000e || - K001005_3d_fifo[i] == 0x80000016 || K001005_3d_fifo[i] == 0x80000036 || - K001005_3d_fifo[i] == 0x800000aa || K001005_3d_fifo[i] == 0x800000a8 || - K001005_3d_fifo[i] == 0x800000b2) + do + { + UINT32 cmd = fifo[index++]; + + // Current guesswork on the command word bits: + // 0x01: Z-buffer disable? + // 0x02: Almost always set (only exception is 0x80000020 in Thunder Hurricane attract mode) + // 0x04: + // 0x08: + // 0x10: Texture mirror enable + // 0x20: Gouraud shading enable? + // 0x40: Unused? + // 0x80: Used by textured polygons. + + if (cmd == 0x800000ae || cmd == 0x8000008e || cmd == 0x80000096 || cmd == 0x800000b6 || + cmd == 0x8000002e || cmd == 0x8000000e || cmd == 0x80000016 || cmd == 0x80000036 || + cmd == 0x800000aa || cmd == 0x800000a8 || cmd == 0x800000b2 || cmd == 0x8000009e || + cmd == 0x80000092 || cmd == 0x8000008a || cmd == 0x80000094 || cmd == 0x8000009a || + cmd == 0x8000009c || cmd == 0x8000008c || cmd == 0x800000ac || cmd == 0x800000b4) { // 0x00: xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx Command // // 0x01: xxxx---- -------- -------- -------- Texture palette + // 0x01: ----xx-- -------- -------- -------- Unknown flags, set by commands 0x7b...0x7e + // 0x01: ------xx x------- -------- -------- Texture width / 8 - 1 + // 0x01: -------- -xxx---- -------- -------- Texture height / 8 - 1 // 0x01: -------- -------x xxxx---- -------- Texture page // 0x01: -------- -------- ----x-x- x-x-x-x- Texture X / 8 // 0x01: -------- -------- -----x-x -x-x-x-x Texture Y / 8 - poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); - poly_vertex v[4]; - int tx, ty; + // texture, Z + + int tex_x, tex_y; UINT32 color = 0; - UINT32 header; - UINT32 command; - int num_verts = 0; - int index = i; - int poly_type = 0; + poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); - command = K001005_3d_fifo[index++]; - header = K001005_3d_fifo[index++]; + UINT32 header = fifo[index++]; - for (j=0; j < 4; j++) + int last_vertex = 0; + int vert_num = 0; + do { - INT16 u2, v2; int x, y, z; - int end = 0; + INT16 tu, tv; - x = ((K001005_3d_fifo[index] >> 0) & 0x3fff); - y = ((K001005_3d_fifo[index] >> 16) & 0x1fff); + x = (fifo[index] >> 0) & 0x3fff; + y = (fifo[index] >> 16) & 0x1fff; x |= ((x & 0x2000) ? 0xffffc000 : 0); y |= ((y & 0x1000) ? 0xffffe000 : 0); - poly_type = K001005_3d_fifo[index] & 0x4000; - end = K001005_3d_fifo[index] & 0x8000; - ++index; - - z = K001005_3d_fifo[index]; - ++index; + poly_type = fifo[index] & 0x4000; // 0 = triangle, 1 = quad + last_vertex = fifo[index] & 0x8000; + index++; - if (end) - { - color = K001005_3d_fifo[index]; - ++index; + z = fifo[index] & 0xffffff00; + brightness = fifo[index] & 0xff; + index++; - u2 = (K001005_3d_fifo[index] >> 16) & 0xffff; - v2 = (K001005_3d_fifo[index] >> 0) & 0xffff; - ++index; - } - else + if (last_vertex) { - u2 = (K001005_3d_fifo[index] >> 16) & 0xffff; - v2 = (K001005_3d_fifo[index] >> 0) & 0xffff; - ++index; + color = fifo[index++]; } - v[j].x = ((float)(x) / 16.0f) + 256.0f; - v[j].y = ((float)(-y) / 16.0f) + 192.0f; - v[j].p[0] = *(float*)(&z); - v[j].p[3] = 1.0f / v[j].p[0]; - v[j].p[1] = u2 * v[j].p[3]; - v[j].p[2] = v2 * v[j].p[3]; - - ++num_verts; + tu = (fifo[index] >> 16) & 0xffff; + tv = (fifo[index] & 0xffff); + index++; - if (end) - break; + v[vert_num].x = ((float)(x) / 16.0f) + 256.0f; + v[vert_num].y = ((float)(-y) / 16.0f) + 192.0f + 8; + v[vert_num].p[POLY_Z] = *(float*)(&z); + v[vert_num].p[POLY_W] = 1.0f / v[vert_num].p[POLY_Z]; + v[vert_num].p[POLY_U] = tu * v[vert_num].p[POLY_W]; + v[vert_num].p[POLY_V] = tv * v[vert_num].p[POLY_W]; + v[vert_num].p[POLY_BRI] = brightness; + v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) * ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + //v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + if (v[vert_num].p[POLY_FOG] < 0.0f) v[vert_num].p[POLY_FOG] = 0.0f; + if (v[vert_num].p[POLY_FOG] > 65536.0f) v[vert_num].p[POLY_FOG] = 65536.0f; + vert_num++; } - - ty = ((header & 0x400) >> 5) | - ((header & 0x100) >> 4) | - ((header & 0x040) >> 3) | - ((header & 0x010) >> 2) | - ((header & 0x004) >> 1) | - ((header & 0x001) >> 0); - - tx = ((header & 0x800) >> 6) | - ((header & 0x200) >> 5) | - ((header & 0x080) >> 4) | - ((header & 0x020) >> 3) | - ((header & 0x008) >> 2) | - ((header & 0x002) >> 1); - - extra->texture_x = tx * 8; - extra->texture_y = ty * 8; - + while (!last_vertex); + + tex_y = ((header & 0x400) >> 5) | + ((header & 0x100) >> 4) | + ((header & 0x040) >> 3) | + ((header & 0x010) >> 2) | + ((header & 0x004) >> 1) | + ((header & 0x001) >> 0); + + tex_x = ((header & 0x800) >> 6) | + ((header & 0x200) >> 5) | + ((header & 0x080) >> 4) | + ((header & 0x020) >> 3) | + ((header & 0x008) >> 2) | + ((header & 0x002) >> 1); + + extra->texture_x = tex_x * 8; + extra->texture_y = tex_y * 8; + extra->texture_width = (header >> 23) & 0x7; + extra->texture_height = (header >> 20) & 0x7; extra->texture_page = (header >> 12) & 0x1f; extra->texture_palette = (header >> 28) & 0xf; - - extra->texture_mirror_x = ((command & 0x10) ? 0x2 : 0) | ((header & 0x00400000) ? 0x1 : 0); - extra->texture_mirror_y = ((command & 0x10) ? 0x2 : 0) | ((header & 0x00400000) ? 0x1 : 0); - + extra->texture_mirror_x = ((cmd & 0x10) ? 0x1 : 0); + extra->texture_mirror_y = ((cmd & 0x10) ? 0x1 : 0); extra->color = color; + extra->light_r = light_r; extra->light_g = light_r; extra->light_b = light_b; + extra->ambient_r = ambient_r; extra->ambient_g = ambient_g; extra->ambient_b = ambient_b; + extra->fog_r = fog_r; extra->fog_g = fog_g; extra->fog_b = fog_b; + extra->flags = cmd; - if (num_verts < 3) + if ((cmd & 0x20) == 0) // possibly enable flag for gouraud shading (fixes some shading errors) { - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &prev_v[2], &v[0], &v[1]); - if (prev_poly_type) - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &prev_v[2], &prev_v[3], &v[0]); -// if (prev_poly_type) -// poly_render_quad(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &prev_v[2], &prev_v[3], &v[0], &v[1]); -// else -// poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &prev_v[2], &v[0], &v[1]); - - memcpy(&prev_v[0], &prev_v[2], sizeof(poly_vertex)); - memcpy(&prev_v[1], &prev_v[3], sizeof(poly_vertex)); - memcpy(&prev_v[2], &v[0], sizeof(poly_vertex)); - memcpy(&prev_v[3], &v[1], sizeof(poly_vertex)); + v[0].p[POLY_BRI] = brightness; + v[1].p[POLY_BRI] = brightness; } - else - { - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &v[0], &v[1], &v[2]); - if (num_verts > 3) - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &v[2], &v[3], &v[0]); -// poly_render_polygon(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, num_verts, v); - memcpy(prev_v, v, sizeof(poly_vertex) * 4); - } + if (poly_type == 0) // triangle + { + if (vert_num == 1) + { + vertex1 = &prev_v[2]; + vertex2 = &prev_v[3]; + vertex3 = &v[0]; + } + else if (vert_num == 2) + { + vertex1 = &prev_v[3]; + vertex2 = &v[0]; + vertex3 = &v[1]; + } + else + { + vertex1 = &v[0]; + vertex2 = &v[1]; + vertex3 = &v[2]; + } - prev_poly_type = poly_type; + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 6, vertex1, vertex2, vertex3); - while ((K001005_3d_fifo[index] & 0xffffff00) != 0x80000000 && index < K001005_3d_fifo_ptr) + memcpy(&prev_v[1], vertex1, sizeof(poly_vertex)); + memcpy(&prev_v[2], vertex2, sizeof(poly_vertex)); + memcpy(&prev_v[3], vertex3, sizeof(poly_vertex)); + } + else // quad { - poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); - int new_verts = 0; - - if (poly_type) + if (vert_num == 1) + { + vertex1 = &prev_v[1]; + vertex2 = &prev_v[2]; + vertex3 = &prev_v[3]; + vertex4 = &v[0]; + } + else if (vert_num == 2) { - memcpy(&v[0], &prev_v[2], sizeof(poly_vertex)); - memcpy(&v[1], &prev_v[3], sizeof(poly_vertex)); + vertex1 = &prev_v[2]; + vertex2 = &prev_v[3]; + vertex3 = &v[0]; + vertex4 = &v[1]; + } + else if (vert_num == 3) + { + vertex1 = &prev_v[3]; + vertex2 = &v[0]; + vertex3 = &v[1]; + vertex4 = &v[2]; } else { - memcpy(&v[0], &prev_v[1], sizeof(poly_vertex)); - memcpy(&v[1], &prev_v[2], sizeof(poly_vertex)); + vertex1 = &v[0]; + vertex2 = &v[1]; + vertex3 = &v[2]; + vertex4 = &v[3]; } - for (j=2; j < 4; j++) - { - INT16 u2, v2; + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 6, vertex1, vertex2, vertex3); + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 6, vertex3, vertex4, vertex1); + + memcpy(&prev_v[0], vertex1, sizeof(poly_vertex)); + memcpy(&prev_v[1], vertex2, sizeof(poly_vertex)); + memcpy(&prev_v[2], vertex3, sizeof(poly_vertex)); + memcpy(&prev_v[3], vertex4, sizeof(poly_vertex)); + } + + while ((fifo[index] & 0xffffff00) != 0x80000000 && index < K001005_3d_fifo_ptr) + { + poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); + int new_verts = 0; + + memcpy(&v[0], &prev_v[2], sizeof(poly_vertex)); + memcpy(&v[1], &prev_v[3], sizeof(poly_vertex)); + + last_vertex = 0; + vert_num = 2; + do + { int x, y, z; - int end = 0; + INT16 tu, tv; x = ((K001005_3d_fifo[index] >> 0) & 0x3fff); y = ((K001005_3d_fifo[index] >> 16) & 0x1fff); x |= ((x & 0x2000) ? 0xffffc000 : 0); y |= ((y & 0x1000) ? 0xffffe000 : 0); - poly_type = K001005_3d_fifo[index] & 0x4000; - end = K001005_3d_fifo[index] & 0x8000; - ++index; - - z = K001005_3d_fifo[index]; - ++index; + poly_type = fifo[index] & 0x4000; + last_vertex = fifo[index] & 0x8000; + index++; - if (end) - { - color = K001005_3d_fifo[index]; - ++index; - - u2 = (K001005_3d_fifo[index] >> 16) & 0xffff; - v2 = (K001005_3d_fifo[index] >> 0) & 0xffff; - ++index; - } - else + z = fifo[index] & 0xffffff00; + brightness = fifo[index] & 0xff; + index++; + + if (last_vertex) { - u2 = (K001005_3d_fifo[index] >> 16) & 0xffff; - v2 = (K001005_3d_fifo[index] >> 0) & 0xffff; - ++index; + color = fifo[index++]; } - v[j].x = ((float)(x) / 16.0f) + 256.0f; - v[j].y = ((float)(-y) / 16.0f) + 192.0f; - v[j].p[0] = *(float*)(&z); - v[j].p[3] = 1.0f / v[j].p[0]; - v[j].p[1] = u2 * v[j].p[3]; - v[j].p[2] = v2 * v[j].p[3]; - - ++new_verts; - - if (end) - break; + tu = (K001005_3d_fifo[index] >> 16) & 0xffff; + tv = (K001005_3d_fifo[index] >> 0) & 0xffff; + index++; + + v[vert_num].x = ((float)(x) / 16.0f) + 256.0f; + v[vert_num].y = ((float)(-y) / 16.0f) + 192.0f + 8; + v[vert_num].p[POLY_Z] = *(float*)(&z); + v[vert_num].p[POLY_W] = 1.0f / v[vert_num].p[POLY_Z]; + v[vert_num].p[POLY_U] = tu * v[vert_num].p[POLY_W]; + v[vert_num].p[POLY_V] = tv * v[vert_num].p[POLY_W]; + v[vert_num].p[POLY_BRI] = brightness; + v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) * ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + //v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + if (v[vert_num].p[POLY_FOG] < 0.0f) v[vert_num].p[POLY_FOG] = 0.0f; + if (v[vert_num].p[POLY_FOG] > 65536.0f) v[vert_num].p[POLY_FOG] = 65536.0f; + + vert_num++; + new_verts++; } + while (!last_vertex); - extra->texture_x = tx * 8; - extra->texture_y = ty * 8; + extra->texture_x = tex_x * 8; + extra->texture_y = tex_y * 8; + extra->texture_width = (header >> 23) & 0x7; + extra->texture_height = (header >> 20) & 0x7; extra->texture_page = (header >> 12) & 0x1f; extra->texture_palette = (header >> 28) & 0xf; - extra->texture_mirror_x = ((command & 0x10) ? 0x2 : 0) | ((header & 0x00400000) ? 0x1 : 0); - extra->texture_mirror_y = ((command & 0x10) ? 0x2 : 0) | ((header & 0x00400000) ? 0x1 : 0); + extra->texture_mirror_x = ((cmd & 0x10) ? 0x1 : 0);// & ((header & 0x00400000) ? 0x1 : 0); + extra->texture_mirror_y = ((cmd & 0x10) ? 0x1 : 0);// & ((header & 0x00400000) ? 0x1 : 0); extra->color = color; + extra->light_r = light_r; extra->light_g = light_r; extra->light_b = light_b; + extra->ambient_r = ambient_r; extra->ambient_g = ambient_g; extra->ambient_b = ambient_b; + extra->fog_r = fog_r; extra->fog_g = fog_g; extra->fog_b = fog_b; + extra->flags = cmd; - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &v[0], &v[1], &v[2]); - if (new_verts > 1) - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, &v[2], &v[3], &v[0]); -// poly_render_polygon(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 4, new_verts + 2, v); + if ((cmd & 0x20) == 0) // possibly enable flag for gouraud shading (fixes some shading errors) + { + v[0].p[POLY_BRI] = brightness; + v[1].p[POLY_BRI] = brightness; + } - memcpy(prev_v, v, sizeof(poly_vertex) * 4); - }; + if (new_verts == 1) + { + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 6, &v[0], &v[1], &v[2]); + + memcpy(&prev_v[1], &v[0], sizeof(poly_vertex)); + memcpy(&prev_v[2], &v[1], sizeof(poly_vertex)); + memcpy(&prev_v[3], &v[2], sizeof(poly_vertex)); + } + else if (new_verts == 2) + { + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 6, &v[0], &v[1], &v[2]); + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_tex, 6, &v[2], &v[3], &v[0]); - i = index - 1; + memcpy(&prev_v[0], &v[0], sizeof(poly_vertex)); + memcpy(&prev_v[1], &v[1], sizeof(poly_vertex)); + memcpy(&prev_v[2], &v[2], sizeof(poly_vertex)); + memcpy(&prev_v[3], &v[3], sizeof(poly_vertex)); + } + }; } - else if (K001005_3d_fifo[i] == 0x80000006 || K001005_3d_fifo[i] == 0x80000026 || - K001005_3d_fifo[i] == 0x80000020 || K001005_3d_fifo[i] == 0x80000022) + else if (cmd == 0x80000006 || cmd == 0x80000026 || cmd == 0x80000002 || cmd == 0x80000020 || cmd == 0x80000022) { + // no texture, Z + poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); - poly_vertex v[4]; - int r, g, b, a; UINT32 color; - int num_verts = 0; - int index = i; - int poly_type = 0; - - ++index; + int r, g, b, a; - for (j=0; j < 4; j++) + int last_vertex = 0; + int vert_num = 0; + do { int x, y, z; - int end = 0; - x = ((K001005_3d_fifo[index] >> 0) & 0x3fff); - y = ((K001005_3d_fifo[index] >> 16) & 0x1fff); + x = (fifo[index] >> 0) & 0x3fff; + y = (fifo[index] >> 16) & 0x1fff; x |= ((x & 0x2000) ? 0xffffc000 : 0); y |= ((y & 0x1000) ? 0xffffe000 : 0); - poly_type = K001005_3d_fifo[index] & 0x4000; - end = K001005_3d_fifo[index] & 0x8000; - ++index; - - z = K001005_3d_fifo[index]; - ++index; - - v[j].x = ((float)(x) / 16.0f) + 256.0f; - v[j].y = ((float)(-y) / 16.0f) + 192.0f; - v[j].p[0] = *(float*)(&z); + poly_type = fifo[index] & 0x4000; // 0 = triangle, 1 = quad + last_vertex = fifo[index] & 0x8000; + index++; - ++num_verts; + z = fifo[index] & 0xffffff00; + brightness = fifo[index] & 0xff; + index++; - if (end) - break; + v[vert_num].x = ((float)(x) / 16.0f) + 256.0f; + v[vert_num].y = ((float)(-y) / 16.0f) + 192.0f + 8; + v[vert_num].p[POLY_Z] = *(float*)(&z); + v[vert_num].p[POLY_BRI] = brightness; + v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) * ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + //v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + if (v[vert_num].p[POLY_FOG] < 0.0f) v[vert_num].p[POLY_FOG] = 0.0f; + if (v[vert_num].p[POLY_FOG] > 65536.0f) v[vert_num].p[POLY_FOG] = 65536.0f; + vert_num++; } + while (!last_vertex); - r = (K001005_3d_fifo[index] >> 0) & 0xff; - g = (K001005_3d_fifo[index] >> 8) & 0xff; - b = (K001005_3d_fifo[index] >> 16) & 0xff; - a = (K001005_3d_fifo[index] >> 24) & 0xff; + r = (fifo[index] >> 0) & 0xff; + g = (fifo[index] >> 8) & 0xff; + b = (fifo[index] >> 16) & 0xff; + a = (fifo[index] >> 24) & 0xff; color = (a << 24) | (r << 16) | (g << 8) | (b); index++; extra->color = color; + extra->light_r = light_r; extra->light_g = light_r; extra->light_b = light_b; + extra->ambient_r = ambient_r; extra->ambient_g = ambient_g; extra->ambient_b = ambient_b; + extra->fog_r = fog_r; extra->fog_g = fog_g; extra->fog_b = fog_b; + extra->flags = cmd; - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, &v[0], &v[1], &v[2]); - if (num_verts > 3) - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, &v[2], &v[3], &v[0]); -// poly_render_polygon(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, num_verts, v); - - memcpy(prev_v, v, sizeof(poly_vertex) * 4); + if ((cmd & 0x20) == 0) // possibly enable flag for gouraud shading (fixes some shading errors) + { + v[0].p[POLY_BRI] = brightness; + v[1].p[POLY_BRI] = brightness; + } - while ((K001005_3d_fifo[index] & 0xffffff00) != 0x80000000 && index < K001005_3d_fifo_ptr) + if (poly_type == 0) // triangle { - poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); - int new_verts = 0; + if (vert_num == 1) + { + vertex1 = &prev_v[2]; + vertex2 = &prev_v[3]; + vertex3 = &v[0]; + } + else if (vert_num == 2) + { + vertex1 = &prev_v[3]; + vertex2 = &v[0]; + vertex3 = &v[1]; + } + else + { + vertex1 = &v[0]; + vertex2 = &v[1]; + vertex3 = &v[2]; + } - if (poly_type) + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 3, vertex1, vertex2, vertex3); + + memcpy(&prev_v[1], vertex1, sizeof(poly_vertex)); + memcpy(&prev_v[2], vertex2, sizeof(poly_vertex)); + memcpy(&prev_v[3], vertex3, sizeof(poly_vertex)); + } + else // quad + { + if (vert_num == 1) + { + vertex1 = &prev_v[1]; + vertex2 = &prev_v[2]; + vertex3 = &prev_v[3]; + vertex4 = &v[0]; + } + else if (vert_num == 2) + { + vertex1 = &prev_v[2]; + vertex2 = &prev_v[3]; + vertex3 = &v[0]; + vertex4 = &v[1]; + } + else if (vert_num == 3) { - memcpy(&v[0], &prev_v[2], sizeof(poly_vertex)); - memcpy(&v[1], &prev_v[3], sizeof(poly_vertex)); + vertex1 = &prev_v[3]; + vertex2 = &v[0]; + vertex3 = &v[1]; + vertex4 = &v[2]; } else { - memcpy(&v[0], &prev_v[1], sizeof(poly_vertex)); - memcpy(&v[1], &prev_v[2], sizeof(poly_vertex)); + vertex1 = &v[0]; + vertex2 = &v[1]; + vertex3 = &v[2]; + vertex4 = &v[3]; } - for (j=2; j < 4; j++) + poly_render_quad(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 3, vertex1, vertex2, vertex3, vertex4); + + memcpy(&prev_v[0], vertex1, sizeof(poly_vertex)); + memcpy(&prev_v[1], vertex2, sizeof(poly_vertex)); + memcpy(&prev_v[2], vertex3, sizeof(poly_vertex)); + memcpy(&prev_v[3], vertex4, sizeof(poly_vertex)); + } + + while ((fifo[index] & 0xffffff00) != 0x80000000 && index < K001005_3d_fifo_ptr) + { + int new_verts = 0; + + memcpy(&v[0], &prev_v[2], sizeof(poly_vertex)); + memcpy(&v[1], &prev_v[3], sizeof(poly_vertex)); + + last_vertex = 0; + vert_num = 2; + do { int x, y, z; - int end = 0; - x = ((K001005_3d_fifo[index] >> 0) & 0x3fff); - y = ((K001005_3d_fifo[index] >> 16) & 0x1fff); + x = ((fifo[index] >> 0) & 0x3fff); + y = ((fifo[index] >> 16) & 0x1fff); x |= ((x & 0x2000) ? 0xffffc000 : 0); y |= ((y & 0x1000) ? 0xffffe000 : 0); - poly_type = K001005_3d_fifo[index] & 0x4000; - end = K001005_3d_fifo[index] & 0x8000; - ++index; + poly_type = fifo[index] & 0x4000; + last_vertex = fifo[index] & 0x8000; + index++; + + z = fifo[index] & 0xffffff00; + brightness = fifo[index] & 0xff; + index++; + + v[vert_num].x = ((float)(x) / 16.0f) + 256.0f; + v[vert_num].y = ((float)(-y) / 16.0f) + 192.0f + 8; + v[vert_num].p[POLY_Z] = *(float*)(&z); + v[vert_num].p[POLY_BRI] = brightness; + v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) * ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + //v[vert_num].p[POLY_FOG] = (1.0f / (exp( ((v[vert_num].p[POLY_Z] * fog_density) / far_z) ))) * 65536.0f; + if (v[vert_num].p[POLY_FOG] < 0.0f) v[vert_num].p[POLY_FOG] = 0.0f; + if (v[vert_num].p[POLY_FOG] > 65536.0f) v[vert_num].p[POLY_FOG] = 65536.0f; + + vert_num++; + new_verts++; + } + while (!last_vertex); - z = K001005_3d_fifo[index]; - ++index; + r = (fifo[index] >> 0) & 0xff; + g = (fifo[index] >> 8) & 0xff; + b = (fifo[index] >> 16) & 0xff; + a = (fifo[index] >> 24) & 0xff; + color = (a << 24) | (r << 16) | (g << 8) | (b); + index++; - v[j].x = ((float)(x) / 16.0f) + 256.0f; - v[j].y = ((float)(-y) / 16.0f) + 192.0f; - v[j].p[0] = *(float*)(&z); + extra->color = color; + extra->light_r = light_r; extra->light_g = light_r; extra->light_b = light_b; + extra->ambient_r = ambient_r; extra->ambient_g = ambient_g; extra->ambient_b = ambient_b; + extra->fog_r = fog_r; extra->fog_g = fog_g; extra->fog_b = fog_b; + extra->flags = cmd; - ++new_verts; + if ((cmd & 0x20) == 0) // possibly enable flag for gouraud shading (fixes some shading errors) + { + v[0].p[POLY_BRI] = brightness; + v[1].p[POLY_BRI] = brightness; + } - if (end) - break; + if (new_verts == 1) + { + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 3, &v[0], &v[1], &v[2]); + + memcpy(&prev_v[1], &v[0], sizeof(poly_vertex)); + memcpy(&prev_v[2], &v[1], sizeof(poly_vertex)); + memcpy(&prev_v[3], &v[2], sizeof(poly_vertex)); } + else if (new_verts == 2) + { + poly_render_quad(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 3, &v[0], &v[1], &v[2], &v[3]); - r = (K001005_3d_fifo[index] >> 0) & 0xff; - g = (K001005_3d_fifo[index] >> 8) & 0xff; - b = (K001005_3d_fifo[index] >> 16) & 0xff; - a = (K001005_3d_fifo[index] >> 24) & 0xff; - color = (a << 24) | (r << 16) | (g << 8) | (b); + memcpy(&prev_v[0], &v[0], sizeof(poly_vertex)); + memcpy(&prev_v[1], &v[1], sizeof(poly_vertex)); + memcpy(&prev_v[2], &v[2], sizeof(poly_vertex)); + memcpy(&prev_v[3], &v[3], sizeof(poly_vertex)); + } + } + } + else if (cmd == 0x80000003 || cmd == 0x80000001) + { + // no texture, no Z + + poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); + int r, g, b, a; + UINT32 color; + + int last_vertex = 0; + int vert_num = 0; + do + { + int x, y; + + x = ((fifo[index] >> 0) & 0x3fff); + y = ((fifo[index] >> 16) & 0x1fff); + x |= ((x & 0x2000) ? 0xffffc000 : 0); + y |= ((y & 0x1000) ? 0xffffe000 : 0); + + poly_type = fifo[index] & 0x4000; + last_vertex = fifo[index] & 0x8000; index++; - extra->color = color; + v[vert_num].x = ((float)(x) / 16.0f) + 256.0f; + v[vert_num].y = ((float)(-y) / 16.0f) + 192.0f + 8; + vert_num++; + } + while (!last_vertex); - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, &v[0], &v[1], &v[2]); - if (new_verts > 1) - poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, &v[0], &v[2], &v[3]); -// poly_render_polygon(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline, 1, new_verts + 2, v); + // unknown word + index++; - memcpy(prev_v, v, sizeof(poly_vertex) * 4); - }; + r = (fifo[index] >> 0) & 0xff; + g = (fifo[index] >> 8) & 0xff; + b = (fifo[index] >> 16) & 0xff; + a = (fifo[index] >> 24) & 0xff; + color = (a << 24) | (r << 16) | (g << 8) | (b); + index++; + + extra->color = color; + extra->flags = cmd; - i = index - 1; + if (poly_type == 0) + { + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_2d, 0, &v[0], &v[1], &v[2]); + } + else + { + poly_render_quad(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_2d, 0, &v[0], &v[1], &v[2], &v[3]); + } } - else if (K001005_3d_fifo[i] == 0x80000000) + else if (cmd == 0x8000008b) + { + // texture, no Z + + int tex_x, tex_y; + poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly); + int r, g, b, a; + UINT32 color = 0; + + UINT32 header = fifo[index++]; + + int last_vertex = 0; + int vert_num = 0; + do + { + int x, y; + INT16 tu, tv; + + x = ((fifo[index] >> 0) & 0x3fff); + y = ((fifo[index] >> 16) & 0x1fff); + x |= ((x & 0x2000) ? 0xffffc000 : 0); + y |= ((y & 0x1000) ? 0xffffe000 : 0); + + poly_type = fifo[index] & 0x4000; + last_vertex = fifo[index] & 0x8000; + index++; + + if (last_vertex) + { + // unknown word + index++; + + color = fifo[index++]; + } + + tu = (fifo[index] >> 16) & 0xffff; + tv = (fifo[index] & 0xffff); + index++; + + v[vert_num].x = ((float)(x) / 16.0f) + 256.0f; + v[vert_num].y = ((float)(-y) / 16.0f) + 192.0f + 8; + v[vert_num].p[POLY_U] = tu; + v[vert_num].p[POLY_V] = tv; + vert_num++; + } + while (!last_vertex); + + r = (color >> 0) & 0xff; + g = (color >> 8) & 0xff; + b = (color >> 16) & 0xff; + a = (color >> 24) & 0xff; + extra->color = (a << 24) | (r << 16) | (g << 8) | (b); + extra->flags = cmd; + + tex_y = ((header & 0x400) >> 5) | + ((header & 0x100) >> 4) | + ((header & 0x040) >> 3) | + ((header & 0x010) >> 2) | + ((header & 0x004) >> 1) | + ((header & 0x001) >> 0); + + tex_x = ((header & 0x800) >> 6) | + ((header & 0x200) >> 5) | + ((header & 0x080) >> 4) | + ((header & 0x020) >> 3) | + ((header & 0x008) >> 2) | + ((header & 0x002) >> 1); + + extra->texture_x = tex_x * 8; + extra->texture_y = tex_y * 8; + extra->texture_width = (header >> 23) & 0x7; + extra->texture_height = (header >> 20) & 0x7; + + extra->texture_page = (header >> 12) & 0x1f; + extra->texture_palette = (header >> 28) & 0xf; + + extra->texture_mirror_x = ((cmd & 0x10) ? 0x1 : 0); + extra->texture_mirror_y = ((cmd & 0x10) ? 0x1 : 0); + + if (poly_type == 0) + { + poly_render_triangle(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_2d_tex, 5, &v[0], &v[1], &v[2]); + } + else + { + poly_render_quad(poly, K001005_bitmap[K001005_bitmap_page], visarea, draw_scanline_2d_tex, 5, &v[0], &v[1], &v[2], &v[3]); + } + } + else if (cmd == 0x80000000) + { + + } + else if (cmd == 0x80000018) { } - else if ((K001005_3d_fifo[i] & 0xffffff00) == 0x80000000) + else if ((cmd & 0xffffff00) == 0x80000000) { /* - mame_printf_debug("Unknown polygon type %08X:\n", K001005_3d_fifo[i]); - for (j=0; j < 0x20; j++) - { - mame_printf_debug(" %02X: %08X\n", j, K001005_3d_fifo[i+1+j]); - } - mame_printf_debug("\n"); - */ + mame_printf_debug("Unknown polygon type %08X:\n", fifo[index-1]); + for (int i=0; i < 0x20; i++) + { + mame_printf_debug(" %02X: %08X\n", i, fifo[index+i]); + } + mame_printf_debug("\n"); + */ + + printf("Unknown polygon type %08X:\n", fifo[index-1]); + for (int i=0; i < 0x20; i++) + { + printf(" %02X: %08X\n", i, fifo[index+i]); + } + printf("\n"); + } + else + { + } } + while (index < K001005_3d_fifo_ptr); } + void K001005_draw(bitmap_rgb32 &bitmap, const rectangle &cliprect) { int i, j; @@ -961,21 +1470,26 @@ void K001005_swap_buffers(running_machine &machine) //if (K001005_status == 2) { + float zvalue = ZBUFFER_MAX; K001005_bitmap[K001005_bitmap_page]->fill(machine.pens[0]&0x00ffffff, K001005_cliprect); - K001005_zbuffer->fill(0xffffffff, K001005_cliprect); + K001005_zbuffer->fill(*(int*)&zvalue, K001005_cliprect); } } +/* static int tick = 0; static int debug_tex_page = 0; static int debug_tex_palette = 0; +*/ VIDEO_START( gticlub ) { gticlub_led_reg[0] = gticlub_led_reg[1] = 0x7f; + /* tick = 0; debug_tex_page = 0; debug_tex_palette = 0; + */ K001006_init(machine); K001005_init(machine); @@ -991,6 +1505,7 @@ SCREEN_UPDATE_RGB32( gticlub ) k001604_draw_front_layer(k001604, bitmap, cliprect); +#if 0 tick++; if( tick >= 5 ) { tick = 0; @@ -1017,7 +1532,6 @@ SCREEN_UPDATE_RGB32( gticlub ) debug_tex_palette = 0; } -#if 0 if (debug_tex_page > 0) { char string[200]; |