summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/video/m3raster.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/video/m3raster.c')
-rw-r--r--src/mame/video/m3raster.c283
1 files changed, 283 insertions, 0 deletions
diff --git a/src/mame/video/m3raster.c b/src/mame/video/m3raster.c
new file mode 100644
index 00000000000..e41b1e1a635
--- /dev/null
+++ b/src/mame/video/m3raster.c
@@ -0,0 +1,283 @@
+static void draw_scanline_normal(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
+{
+ const poly_extra_data *extra = extradata;
+ const cached_texture *texture = extra->texture;
+ mame_bitmap *destmap = dest;
+ UINT16 *p = BITMAP_ADDR16(destmap, scanline, 0);
+ UINT32 *d = BITMAP_ADDR32(zbuffer, scanline, 0);
+ float ooz = extent->param[0].start;
+ float uoz = extent->param[1].start;
+ float voz = extent->param[2].start;
+ float doozdx = extent->param[0].dpdx;
+ float duozdx = extent->param[1].dpdx;
+ float dvozdx = extent->param[2].dpdx;
+ UINT32 polyi = extra->polygon_intensity;
+ UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
+ UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
+ UINT32 width = 6 + texture->width;
+ int x;
+
+ for (x = extent->startx; x < extent->stopx; x++)
+ {
+ UINT32 iz = ooz * 256.0f;
+ if (iz > d[x])
+ {
+ float z = 1.0f / ooz;
+ UINT32 u = uoz * z;
+ UINT32 v = voz * z;
+ UINT32 u1 = (u >> 8) & umask;
+ UINT32 v1 = (v >> 8) & vmask;
+ UINT32 u2 = (u1 + 1) & umask;
+ UINT32 v2 = (v1 + 1) & vmask;
+ UINT32 pix00 = texture->data[(v1 << width) + u1];
+ UINT32 pix01 = texture->data[(v1 << width) + u2];
+ UINT32 pix10 = texture->data[(v2 << width) + u1];
+ UINT32 pix11 = texture->data[(v2 << width) + u2];
+ UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
+ UINT32 fr = ((texel & 0x00ff0000) * polyi) >> (8+9);
+ UINT32 fg = ((texel & 0x0000ff00) * polyi) >> (8+6);
+ UINT32 fb = ((texel & 0x000000ff) * polyi) >> (8+3);
+ p[x] = (fr & 0x7c00) | (fg & 0x3e0) | (fb & 0x1f);
+ d[x] = iz;
+ }
+
+ ooz += doozdx;
+ uoz += duozdx;
+ voz += dvozdx;
+ }
+}
+
+static void draw_scanline_trans(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
+{
+ const poly_extra_data *extra = extradata;
+ const cached_texture *texture = extra->texture;
+ mame_bitmap *destmap = dest;
+ UINT16 *p = BITMAP_ADDR16(destmap, scanline, 0);
+ UINT32 *d = BITMAP_ADDR32(zbuffer, scanline, 0);
+ float ooz = extent->param[0].start;
+ float uoz = extent->param[1].start;
+ float voz = extent->param[2].start;
+ float doozdx = extent->param[0].dpdx;
+ float duozdx = extent->param[1].dpdx;
+ float dvozdx = extent->param[2].dpdx;
+ UINT32 polyi = (extra->polygon_intensity * extra->polygon_transparency) >> 5;
+ int desttrans = 32 - extra->polygon_transparency;
+ UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
+ UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
+ UINT32 width = 6 + texture->width;
+ int x;
+
+ for (x = extent->startx; x < extent->stopx; x++)
+ {
+ UINT32 iz = ooz * 256.0f;
+ if (iz > d[x])
+ {
+ float z = 1.0f / ooz;
+ UINT32 u = uoz * z;
+ UINT32 v = voz * z;
+ UINT32 u1 = (u >> 8) & umask;
+ UINT32 v1 = (v >> 8) & vmask;
+ UINT32 u2 = (u1 + 1) & umask;
+ UINT32 v2 = (v1 + 1) & vmask;
+ UINT32 pix00 = texture->data[(v1 << width) + u1];
+ UINT32 pix01 = texture->data[(v1 << width) + u2];
+ UINT32 pix10 = texture->data[(v2 << width) + u1];
+ UINT32 pix11 = texture->data[(v2 << width) + u2];
+ UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
+ UINT32 fr = ((texel & 0x00ff0000) * polyi) >> (8+9);
+ UINT32 fg = ((texel & 0x0000ff00) * polyi) >> (8+6);
+ UINT32 fb = ((texel & 0x000000ff) * polyi) >> (8+3);
+ UINT16 orig = p[x];
+ fr += ((orig & 0x7c00) * desttrans) >> 5;
+ fg += ((orig & 0x03e0) * desttrans) >> 5;
+ fb += ((orig & 0x001f) * desttrans) >> 5;
+ p[x] = (fr & 0x7c00) | (fg & 0x3e0) | (fb & 0x1f);
+ d[x] = iz;
+ }
+
+ ooz += doozdx;
+ uoz += duozdx;
+ voz += dvozdx;
+ }
+}
+
+
+static void draw_scanline_alpha(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
+{
+ const poly_extra_data *extra = extradata;
+ const cached_texture *texture = extra->texture;
+ mame_bitmap *destmap = dest;
+ UINT16 *p = BITMAP_ADDR16(destmap, scanline, 0);
+ UINT32 *d = BITMAP_ADDR32(zbuffer, scanline, 0);
+ float ooz = extent->param[0].start;
+ float uoz = extent->param[1].start;
+ float voz = extent->param[2].start;
+ float doozdx = extent->param[0].dpdx;
+ float duozdx = extent->param[1].dpdx;
+ float dvozdx = extent->param[2].dpdx;
+ UINT32 polyi = (extra->polygon_intensity * extra->polygon_transparency) >> 5;
+ int desttrans = 32 - extra->polygon_transparency;
+ UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
+ UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
+ UINT32 width = 6 + texture->width;
+ int x;
+
+ for (x = extent->startx; x < extent->stopx; x++)
+ {
+ UINT32 iz = ooz * 256.0f;
+ if (iz > d[x])
+ {
+ float z = 1.0f / ooz;
+ UINT32 u = uoz * z;
+ UINT32 v = voz * z;
+ UINT32 u1 = (u >> 8) & umask;
+ UINT32 v1 = (v >> 8) & vmask;
+ UINT32 u2 = (u1 + 1) & umask;
+ UINT32 v2 = (v1 + 1) & vmask;
+ UINT32 pix00 = texture->data[(v1 << width) + u1];
+ UINT32 pix01 = texture->data[(v1 << width) + u2];
+ UINT32 pix10 = texture->data[(v2 << width) + u1];
+ UINT32 pix11 = texture->data[(v2 << width) + u2];
+ UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
+ UINT32 fa = texel >> 24;
+ UINT32 combined = ((fa + 1) * polyi) >> 8;
+ UINT32 fr = ((texel & 0x00ff0000) * combined) >> (8+9);
+ UINT32 fg = ((texel & 0x0000ff00) * combined) >> (8+6);
+ UINT32 fb = ((texel & 0x000000ff) * combined) >> (8+3);
+ UINT16 orig = p[x];
+ combined = ((255 - fa) * desttrans) >> 8;
+ fr += ((orig & 0x7c00) * combined) >> 5;
+ fg += ((orig & 0x03e0) * combined) >> 5;
+ fb += ((orig & 0x001f) * combined) >> 5;
+ p[x] = (fr & 0x7c00) | (fg & 0x3e0) | (fb & 0x1f);
+ d[x] = iz;
+ }
+
+ ooz += doozdx;
+ uoz += duozdx;
+ voz += dvozdx;
+ }
+}
+
+
+static void draw_scanline_alpha_test(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
+{
+ const poly_extra_data *extra = extradata;
+ const cached_texture *texture = extra->texture;
+ mame_bitmap *destmap = dest;
+ UINT16 *p = BITMAP_ADDR16(destmap, scanline, 0);
+ UINT32 *d = BITMAP_ADDR32(zbuffer, scanline, 0);
+ float ooz = extent->param[0].start;
+ float uoz = extent->param[1].start;
+ float voz = extent->param[2].start;
+ float doozdx = extent->param[0].dpdx;
+ float duozdx = extent->param[1].dpdx;
+ float dvozdx = extent->param[2].dpdx;
+ UINT32 polyi = (extra->polygon_intensity * extra->polygon_transparency) >> 5;
+ int desttrans = 32 - extra->polygon_transparency;
+ UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
+ UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
+ UINT32 width = 6 + texture->width;
+ int x;
+
+ for (x = extent->startx; x < extent->stopx; x++)
+ {
+ UINT32 iz = ooz * 256.0f;
+ if (iz > d[x])
+ {
+ float z = 1.0f / ooz;
+ UINT32 u = uoz * z;
+ UINT32 v = voz * z;
+ UINT32 u1 = (u >> 8) & umask;
+ UINT32 v1 = (v >> 8) & vmask;
+ UINT32 u2 = (u1 + 1) & umask;
+ UINT32 v2 = (v1 + 1) & vmask;
+ UINT32 pix00 = texture->data[(v1 << width) + u1];
+ UINT32 pix01 = texture->data[(v1 << width) + u2];
+ UINT32 pix10 = texture->data[(v2 << width) + u1];
+ UINT32 pix11 = texture->data[(v2 << width) + u2];
+ UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
+ UINT32 fa = texel >> 24;
+ if (fa >= 0xf8)
+ {
+ UINT32 combined = ((fa + 1) * polyi) >> 8;
+ UINT32 fr = ((texel & 0x00ff0000) * combined) >> (8+9);
+ UINT32 fg = ((texel & 0x0000ff00) * combined) >> (8+6);
+ UINT32 fb = ((texel & 0x000000ff) * combined) >> (8+3);
+ UINT16 orig = p[x];
+ combined = ((255 - fa) * desttrans) >> 8;
+ fr += ((orig & 0x7c00) * combined) >> 5;
+ fg += ((orig & 0x03e0) * combined) >> 5;
+ fb += ((orig & 0x001f) * combined) >> 5;
+ p[x] = (fr & 0x7c00) | (fg & 0x3e0) | (fb & 0x1f);
+ d[x] = iz;
+ }
+ }
+
+ ooz += doozdx;
+ uoz += duozdx;
+ voz += dvozdx;
+ }
+}
+
+static void draw_scanline_color(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
+{
+ const poly_extra_data *extra = extradata;
+ mame_bitmap *destmap = dest;
+ UINT16 *p = BITMAP_ADDR16(destmap, scanline, 0);
+ UINT32 *d = BITMAP_ADDR32(zbuffer, scanline, 0);
+ float ooz = extent->param[0].start;
+ float doozdx = extent->param[0].dpdx;
+ int fr = extra->color & 0x7c00;
+ int fg = extra->color & 0x03e0;
+ int fb = extra->color & 0x001f;
+ int x;
+
+ // apply intensity
+ fr = (fr * extra->polygon_intensity) >> 8;
+ fg = (fg * extra->polygon_intensity) >> 8;
+ fb = (fb * extra->polygon_intensity) >> 8;
+
+ /* simple case: no transluceny */
+ if (extra->polygon_transparency >= 32)
+ {
+ UINT32 color = (fr & 0x7c00) | (fg & 0x03e0) | (fb & 0x1f);
+ for (x = extent->startx; x < extent->stopx; x++)
+ {
+ UINT32 iz = ooz * 256.0f;
+ if (iz > d[x])
+ {
+ p[x] = color;
+ d[x] = iz;
+ }
+ ooz += doozdx;
+ }
+ }
+
+ /* translucency */
+ else
+ {
+ int polytrans = extra->polygon_transparency;
+
+ fr = (fr * polytrans) >> 5;
+ fg = (fg * polytrans) >> 5;
+ fb = (fb * polytrans) >> 5;
+ polytrans = 32 - polytrans;
+
+ for (x = extent->startx; x < extent->stopx; x++)
+ {
+ UINT32 iz = ooz * 256.0f;
+ if (iz > d[x])
+ {
+ UINT16 orig = p[x];
+ int r = fr + (((orig & 0x7c00) * polytrans) >> 5);
+ int g = fg + (((orig & 0x03e0) * polytrans) >> 5);
+ int b = fb + (((orig & 0x001f) * polytrans) >> 5);
+
+ p[x] = (r & 0x7c00) | (g & 0x3e0) | (b & 0x1f);
+ d[x] = iz;
+ }
+ ooz += doozdx;
+ }
+ }
+}