summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
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
commitd4b608c178371e223ef55382482c6bf686650a9d (patch)
tree3cff3c3815a09adb5cd6ea09a97c3347ad0d29c8
parente1b983d6588a190f57301382cb975e0c70e7fb6e (diff)
gticlub: Rewrote the 3D renderer. Implemented gouraud shading, lighting and fog. [Ville Linde]
-rw-r--r--src/mame/video/gticlub.c1144
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];