move some sprite code around... (nw)

This commit is contained in:
David Haywood 2013-07-15 19:32:46 +00:00
parent 873d0f9c56
commit 2ee1fc4422
3 changed files with 629 additions and 607 deletions

View File

@ -747,6 +747,614 @@ void k053247_device::k053247_sprites_draw( bitmap_rgb32 &bitmap, const rectangle
{ k053247_sprites_draw_common( bitmap, cliprect); }
/*
Parameter Notes
---------------
clip : *caller must supply a pointer to target clip rectangle
alpha : 0 = invisible, 255 = solid
drawmode:
0 = all pens solid
1 = solid pens only
2 = all pens solid with alpha blending
3 = solid pens only with alpha blending
4 = shadow pens only
5 = all pens shadow
zcode : 0 = closest, 255 = furthest (pixel z-depth), -1 = disable depth buffers and shadows
pri : 0 = topmost, 255 = backmost (pixel priority)
*/
INLINE void zdrawgfxzoom32GP(
bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy,
int scalex, int scaley, int alpha, int drawmode, int zcode, int pri, UINT8* gx_objzbuf, UINT8* gx_shdzbuf)
{
#define FP 19
#define FPONE (1<<FP)
#define FPHALF (1<<(FP-1))
#define FPENT 0
// inner loop
const UINT8 *src_ptr;
int src_x;
int eax, ecx;
int src_fx, src_fdx;
int shdpen;
UINT8 z8 = 0, p8 = 0;
UINT8 *ozbuf_ptr;
UINT8 *szbuf_ptr;
const pen_t *pal_base;
const pen_t *shd_base;
UINT32 *dst_ptr;
// outter loop
int src_fby, src_fdy, src_fbx;
const UINT8 *src_base;
int dst_w, dst_h;
// one-time
int nozoom, granularity;
int src_fw, src_fh;
int dst_minx, dst_maxx, dst_miny, dst_maxy;
int dst_skipx, dst_skipy, dst_x, dst_y, dst_lastx, dst_lasty;
int src_pitch, dst_pitch;
// cull illegal and transparent objects
if (!scalex || !scaley) return;
// find shadow pens and cull invisible shadows
granularity = shdpen = gfx->granularity();
shdpen--;
if (zcode >= 0)
{
if (drawmode == 5) { drawmode = 4; shdpen = 1; }
}
else
if (drawmode >= 4) return;
// alpha blend necessary?
if (drawmode & 2)
{
if (alpha <= 0) return;
if (alpha >= 255) drawmode &= ~2;
}
// fill internal data structure with default values
ozbuf_ptr = gx_objzbuf;
szbuf_ptr = gx_shdzbuf;
src_pitch = 16;
src_fw = 16;
src_fh = 16;
src_base = gfx->get_data(code % gfx->elements());
pal_base = gfx->machine().pens + gfx->colorbase() + (color % gfx->colors()) * granularity;
shd_base = gfx->machine().shadow_table;
dst_ptr = &bitmap.pix32(0);
dst_pitch = bitmap.rowpixels();
dst_minx = cliprect.min_x;
dst_maxx = cliprect.max_x;
dst_miny = cliprect.min_y;
dst_maxy = cliprect.max_y;
dst_x = sx;
dst_y = sy;
// cull off-screen objects
if (dst_x > dst_maxx || dst_y > dst_maxy) return;
nozoom = (scalex == 0x10000 && scaley == 0x10000);
if (nozoom)
{
dst_h = dst_w = 16;
src_fdy = src_fdx = 1;
}
else
{
dst_w = ((scalex<<4)+0x8000)>>16;
dst_h = ((scaley<<4)+0x8000)>>16;
if (!dst_w || !dst_h) return;
src_fw <<= FP;
src_fh <<= FP;
src_fdx = src_fw / dst_w;
src_fdy = src_fh / dst_h;
}
dst_lastx = dst_x + dst_w - 1;
if (dst_lastx < dst_minx) return;
dst_lasty = dst_y + dst_h - 1;
if (dst_lasty < dst_miny) return;
// clip destination
dst_skipx = 0;
eax = dst_minx; if ((eax -= dst_x) > 0) { dst_skipx = eax; dst_w -= eax; dst_x = dst_minx; }
eax = dst_lastx; if ((eax -= dst_maxx) > 0) dst_w -= eax;
dst_skipy = 0;
eax = dst_miny; if ((eax -= dst_y) > 0) { dst_skipy = eax; dst_h -= eax; dst_y = dst_miny; }
eax = dst_lasty; if ((eax -= dst_maxy) > 0) dst_h -= eax;
// calculate zoom factors and clip source
if (nozoom)
{
if (!flipx) src_fbx = 0; else { src_fbx = src_fw - 1; src_fdx = -src_fdx; }
if (!flipy) src_fby = 0; else { src_fby = src_fh - 1; src_fdy = -src_fdy; src_pitch = -src_pitch; }
}
else
{
if (!flipx) src_fbx = FPENT; else { src_fbx = src_fw - FPENT - 1; src_fdx = -src_fdx; }
if (!flipy) src_fby = FPENT; else { src_fby = src_fh - FPENT - 1; src_fdy = -src_fdy; }
}
src_fbx += dst_skipx * src_fdx;
src_fby += dst_skipy * src_fdy;
// adjust insertion points and pre-entry constants
eax = (dst_y - dst_miny) * GX_ZBUFW + (dst_x - dst_minx) + dst_w;
z8 = (UINT8)zcode;
p8 = (UINT8)pri;
ozbuf_ptr += eax;
szbuf_ptr += eax << 1;
dst_ptr += dst_y * dst_pitch + dst_x + dst_w;
dst_w = -dst_w;
if (!nozoom)
{
ecx = src_fby; src_fby += src_fdy;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
if (zcode < 0) // no shadow and z-buffering
{
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen) continue;
dst_ptr [ecx] = pal_base[eax];
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
}
else
{
switch (drawmode)
{
case 0: // all pens solid
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr [ecx] = eax;
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 1: // solid pens only
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr [ecx] = eax;
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 2: // all pens solid with alpha blending
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 3: // solid pens only with alpha blending
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 4: // shadow pens only
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
eax = dst_ptr[ecx];
szbuf_ptr[ecx*2] = z8;
szbuf_ptr[ecx*2+1] = p8;
// the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck!
dst_ptr[ecx] = shd_base[rgb_to_rgb15(eax)];
//dst_ptr[ecx] =(eax>>3&0x001f);lend_r32( eax, 0x00000000, 128);
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
szbuf_ptr += (GX_ZBUFW<<1);
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
} // switch (drawmode)
} // if (zcode < 0)
} // if (!nozoom)
else
{
src_ptr = src_base + (src_fby<<4) + src_fbx;
src_fdy = src_fdx * dst_w + src_pitch;
ecx = dst_w;
if (zcode < 0) // no shadow and z-buffering
{
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen) continue;
dst_ptr[ecx] = pal_base[eax];
}
while (++ecx);
src_ptr += src_fdy;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
}
else
{
switch (drawmode)
{
case 0: // all pens solid
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = eax;
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 1: // solid pens only
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = eax;
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 2: // all pens solid with alpha blending
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 3: // solid pens only with alpha blending
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 4: // shadow pens only
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
eax = dst_ptr[ecx];
szbuf_ptr[ecx*2] = z8;
szbuf_ptr[ecx*2+1] = p8;
// the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck!
dst_ptr[ecx] = shd_base[rgb_to_rgb15(eax)];
}
while (++ecx);
src_ptr += src_fdy;
szbuf_ptr += (GX_ZBUFW<<1);
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
}
}
}
#undef FP
#undef FPONE
#undef FPHALF
#undef FPENT
}
void k053247_device::k053247_draw_single_sprite_gxcore( bitmap_rgb32 &bitmap, const rectangle &cliprect,
UINT8* gx_objzbuf, UINT8* gx_shdzbuf, int code, UINT16 *gx_spriteram, int offs, int k053246_objset1, int flipscreenx, int flipscreeny, int screenwidth, int wrapsize, int xwraplim, int ywraplim, int k053247_dx, int k053247_dy, int offx, int offy,
gfx_element* k053247_gfx, int color, int alpha, int drawmode, int zcode, int pri )
{
static const int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
static const int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
int xa,ya,ox,oy,zw,zh,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,scalex,scaley,nozoom;
int temp, temp1, temp2, temp3, temp4;
xa = ya = 0;
if (code & 0x01) xa += 1;
if (code & 0x02) ya += 1;
if (code & 0x04) xa += 2;
if (code & 0x08) ya += 2;
if (code & 0x10) xa += 4;
if (code & 0x20) ya += 4;
code &= ~0x3f;
temp4 = gx_spriteram[offs];
// mask off the upper 6 bits of coordinate and zoom registers
oy = gx_spriteram[offs+2] & 0x3ff;
ox = gx_spriteram[offs+3] & 0x3ff;
scaley = zoomy = gx_spriteram[offs+4] & 0x3ff;
if (zoomy) zoomy = (0x400000+(zoomy>>1)) / zoomy;
else zoomy = 0x800000;
if (!(temp4 & 0x4000))
{
scalex = zoomx = gx_spriteram[offs+5] & 0x3ff;
if (zoomx) zoomx = (0x400000+(zoomx>>1)) / zoomx;
else zoomx = 0x800000;
}
else { zoomx = zoomy; scalex = scaley; }
nozoom = (scalex == 0x40 && scaley == 0x40);
flipx = temp4 & 0x1000;
flipy = temp4 & 0x2000;
temp = gx_spriteram[offs+6];
mirrorx = temp & 0x4000;
if (mirrorx) flipx = 0; // only applies to x mirror, proven
mirrory = temp & 0x8000;
// for Escape Kids (GX975)
if ( k053246_objset1 & 8 ) // Check only "Bit #3 is '1'?"
{
zoomx = zoomx>>1; // Fix sprite width to HALF size
ox = (ox>>1) + 1; // Fix sprite draw position
if (flipscreenx) ox += screenwidth;
}
if (flipscreenx) { ox = -ox; if (!mirrorx) flipx = !flipx; }
if (flipscreeny) { oy = -oy; if (!mirrory) flipy = !flipy; }
// apply wrapping and global offsets
temp = wrapsize-1;
ox += k053247_dx;
oy -= k053247_dy;
ox = ( ox - offx) & temp;
oy = (-oy - offy) & temp;
if (ox >= xwraplim) ox -= wrapsize;
if (oy >= ywraplim) oy -= wrapsize;
temp = temp4>>8 & 0x0f;
int k = 1 << (temp & 3);
int l = 1 << (temp>>2 & 3);
ox -= (zoomx * k) >> 13;
oy -= (zoomy * l) >> 13;
// substitutes: i=x, j=y, k=w, l=h, temp=code, temp1=fx, temp2=fy, temp3=sx, temp4=sy;
for (int j=0; j<l; j++)
{
temp4 = oy + ((zoomy * j + (1<<11)) >> 12);
zh = (oy + ((zoomy * (j+1) + (1<<11)) >> 12)) - temp4;
for (int i=0; i<k; i++)
{
temp3 = ox + ((zoomx * i + (1<<11)) >> 12);
zw = (ox + ((zoomx * (i+1) + (1<<11)) >> 12)) - temp3;
temp = code;
if (mirrorx)
{
if ((!flipx)^((i<<1)<k))
{
/* mirror left/right */
temp += xoffset[(k-1-i+xa)&7];
temp1 = 1;
}
else
{
temp += xoffset[(i+xa)&7];
temp1 = 0;
}
}
else
{
if (flipx) temp += xoffset[(k-1-i+xa)&7];
else temp += xoffset[(i+xa)&7];
temp1 = flipx;
}
if (mirrory)
{
if ((!flipy)^((j<<1)>=l))
{
/* mirror top/bottom */
temp += yoffset[(l-1-j+ya)&7];
temp2 = 1;
}
else
{
temp += yoffset[(j+ya)&7];
temp2 = 0;
}
}
else
{
if (flipy) temp += yoffset[(l-1-j+ya)&7];
else temp += yoffset[(j+ya)&7];
temp2 = flipy;
}
if (nozoom) { scaley = scalex = 0x10000; } else { scalex = zw << 12; scaley = zh << 12; };
zdrawgfxzoom32GP(
bitmap, cliprect, k053247_gfx,
temp,
color,
temp1,temp2,
temp3,temp4,
scalex, scaley, alpha, drawmode, zcode, pri,
gx_objzbuf, gx_shdzbuf
);
}
}
}
/*****************************************************************************
DEVICE INTERFACE
*****************************************************************************/

View File

@ -27,6 +27,18 @@ Callback procedures for non-standard shadows:
#define K053247_CUSTOMSHADOW 0x20000000
#define K053247_SHDSHIFT 20
#ifdef GX_DEBUG
#define GX_ZBUFW 512
#define GX_ZBUFH 384
#define GX_ZPAGESIZE 0x300000
#define GX_ZBUFSIZE 0x600000
#else
#define GX_ZBUFW 576
#define GX_ZBUFH 224
#define GX_ZPAGESIZE (GX_ZBUFW*GX_ZBUFH)
#define GX_ZBUFSIZE ((GX_ZBUFW*GX_ZBUFH)*2)
#endif
struct k053247_interface
{
@ -113,6 +125,11 @@ public:
template<class _BitmapClass>
void k053247_sprites_draw_common( _BitmapClass &bitmap, const rectangle &cliprect );
void k053247_draw_single_sprite_gxcore( bitmap_rgb32 &bitmap, const rectangle &cliprect,
UINT8* gx_objzbuf, UINT8* gx_shdzbuf, int code, UINT16 *gx_spriteram, int offs, int k053246_objset1, int flipscreenx, int flipscreeny, int screenwidth, int wrapsize, int xwraplim, int ywraplim, int k053247_dx, int k053247_dy, int offx, int offy,
gfx_element* k053247_gfx, int color, int alpha, int drawmode, int zcode, int pri );
protected:
// device-level overrides
virtual void device_config_complete();

View File

@ -8,7 +8,7 @@
#include "includes/konamigx.h"
#define GX_DEBUG 0
//#define GX_DEBUG
#define VERBOSE 0
/***************************************************************************/
@ -17,17 +17,6 @@
/* */
/***************************************************************************/
#if GX_DEBUG
#define GX_ZBUFW 512
#define GX_ZBUFH 384
#define GX_ZPAGESIZE 0x300000
#define GX_ZBUFSIZE 0x600000
#else
#define GX_ZBUFW 576
#define GX_ZBUFH 224
#define GX_ZPAGESIZE (GX_ZBUFW*GX_ZBUFH)
#define GX_ZBUFSIZE ((GX_ZBUFW*GX_ZBUFH)*2)
#endif
static UINT8 *gx_objzbuf, *gx_shdzbuf;
@ -75,467 +64,6 @@ static rectangle gxtype1_roz_dstbitmapclip;
static void (*game_tile_callback)(running_machine &machine, int layer, int *code, int *color, int *flags);
/*
Parameter Notes
---------------
clip : *caller must supply a pointer to target clip rectangle
alpha : 0 = invisible, 255 = solid
drawmode:
0 = all pens solid
1 = solid pens only
2 = all pens solid with alpha blending
3 = solid pens only with alpha blending
4 = shadow pens only
5 = all pens shadow
zcode : 0 = closest, 255 = furthest (pixel z-depth), -1 = disable depth buffers and shadows
pri : 0 = topmost, 255 = backmost (pixel priority)
*/
INLINE void zdrawgfxzoom32GP(
bitmap_rgb32 &bitmap, const rectangle &cliprect, gfx_element *gfx,
UINT32 code, UINT32 color, int flipx, int flipy, int sx, int sy,
int scalex, int scaley, int alpha, int drawmode, int zcode, int pri)
{
#define FP 19
#define FPONE (1<<FP)
#define FPHALF (1<<(FP-1))
#define FPENT 0
// inner loop
const UINT8 *src_ptr;
int src_x;
int eax, ecx;
int src_fx, src_fdx;
int shdpen;
UINT8 z8 = 0, p8 = 0;
UINT8 *ozbuf_ptr;
UINT8 *szbuf_ptr;
const pen_t *pal_base;
const pen_t *shd_base;
UINT32 *dst_ptr;
// outter loop
int src_fby, src_fdy, src_fbx;
const UINT8 *src_base;
int dst_w, dst_h;
// one-time
int nozoom, granularity;
int src_fw, src_fh;
int dst_minx, dst_maxx, dst_miny, dst_maxy;
int dst_skipx, dst_skipy, dst_x, dst_y, dst_lastx, dst_lasty;
int src_pitch, dst_pitch;
// cull illegal and transparent objects
if (!scalex || !scaley) return;
// find shadow pens and cull invisible shadows
granularity = shdpen = gfx->granularity();
shdpen--;
if (zcode >= 0)
{
if (drawmode == 5) { drawmode = 4; shdpen = 1; }
}
else
if (drawmode >= 4) return;
// alpha blend necessary?
if (drawmode & 2)
{
if (alpha <= 0) return;
if (alpha >= 255) drawmode &= ~2;
}
// fill internal data structure with default values
ozbuf_ptr = gx_objzbuf;
szbuf_ptr = gx_shdzbuf;
src_pitch = 16;
src_fw = 16;
src_fh = 16;
src_base = gfx->get_data(code % gfx->elements());
pal_base = gfx->machine().pens + gfx->colorbase() + (color % gfx->colors()) * granularity;
shd_base = gfx->machine().shadow_table;
dst_ptr = &bitmap.pix32(0);
dst_pitch = bitmap.rowpixels();
dst_minx = cliprect.min_x;
dst_maxx = cliprect.max_x;
dst_miny = cliprect.min_y;
dst_maxy = cliprect.max_y;
dst_x = sx;
dst_y = sy;
// cull off-screen objects
if (dst_x > dst_maxx || dst_y > dst_maxy) return;
nozoom = (scalex == 0x10000 && scaley == 0x10000);
if (nozoom)
{
dst_h = dst_w = 16;
src_fdy = src_fdx = 1;
}
else
{
dst_w = ((scalex<<4)+0x8000)>>16;
dst_h = ((scaley<<4)+0x8000)>>16;
if (!dst_w || !dst_h) return;
src_fw <<= FP;
src_fh <<= FP;
src_fdx = src_fw / dst_w;
src_fdy = src_fh / dst_h;
}
dst_lastx = dst_x + dst_w - 1;
if (dst_lastx < dst_minx) return;
dst_lasty = dst_y + dst_h - 1;
if (dst_lasty < dst_miny) return;
// clip destination
dst_skipx = 0;
eax = dst_minx; if ((eax -= dst_x) > 0) { dst_skipx = eax; dst_w -= eax; dst_x = dst_minx; }
eax = dst_lastx; if ((eax -= dst_maxx) > 0) dst_w -= eax;
dst_skipy = 0;
eax = dst_miny; if ((eax -= dst_y) > 0) { dst_skipy = eax; dst_h -= eax; dst_y = dst_miny; }
eax = dst_lasty; if ((eax -= dst_maxy) > 0) dst_h -= eax;
// calculate zoom factors and clip source
if (nozoom)
{
if (!flipx) src_fbx = 0; else { src_fbx = src_fw - 1; src_fdx = -src_fdx; }
if (!flipy) src_fby = 0; else { src_fby = src_fh - 1; src_fdy = -src_fdy; src_pitch = -src_pitch; }
}
else
{
if (!flipx) src_fbx = FPENT; else { src_fbx = src_fw - FPENT - 1; src_fdx = -src_fdx; }
if (!flipy) src_fby = FPENT; else { src_fby = src_fh - FPENT - 1; src_fdy = -src_fdy; }
}
src_fbx += dst_skipx * src_fdx;
src_fby += dst_skipy * src_fdy;
// adjust insertion points and pre-entry constants
eax = (dst_y - dst_miny) * GX_ZBUFW + (dst_x - dst_minx) + dst_w;
z8 = (UINT8)zcode;
p8 = (UINT8)pri;
ozbuf_ptr += eax;
szbuf_ptr += eax << 1;
dst_ptr += dst_y * dst_pitch + dst_x + dst_w;
dst_w = -dst_w;
if (!nozoom)
{
ecx = src_fby; src_fby += src_fdy;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
if (zcode < 0) // no shadow and z-buffering
{
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen) continue;
dst_ptr [ecx] = pal_base[eax];
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
}
else
{
switch (drawmode)
{
case 0: // all pens solid
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr [ecx] = eax;
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 1: // solid pens only
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr [ecx] = eax;
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 2: // all pens solid with alpha blending
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 3: // solid pens only with alpha blending
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
case 4: // shadow pens only
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
src_fx += src_fdx;
src_x >>= FP;
if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
eax = dst_ptr[ecx];
szbuf_ptr[ecx*2] = z8;
szbuf_ptr[ecx*2+1] = p8;
// the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck!
dst_ptr[ecx] = shd_base[rgb_to_rgb15(eax)];
//dst_ptr[ecx] =(eax>>3&0x001f);lend_r32( eax, 0x00000000, 128);
}
while (++ecx);
ecx = src_fby; src_fby += src_fdy;
szbuf_ptr += (GX_ZBUFW<<1);
dst_ptr += dst_pitch;
ecx >>= FP; src_fx = src_fbx;
src_x = src_fbx; src_fx += src_fdx;
ecx <<= 4; src_ptr = src_base;
src_x >>= FP; src_ptr += ecx;
ecx = dst_w;
}
while (--dst_h);
break;
} // switch (drawmode)
} // if (zcode < 0)
} // if (!nozoom)
else
{
src_ptr = src_base + (src_fby<<4) + src_fbx;
src_fdy = src_fdx * dst_w + src_pitch;
ecx = dst_w;
if (zcode < 0) // no shadow and z-buffering
{
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen) continue;
dst_ptr[ecx] = pal_base[eax];
}
while (++ecx);
src_ptr += src_fdy;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
}
else
{
switch (drawmode)
{
case 0: // all pens solid
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = eax;
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 1: // solid pens only
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = eax;
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 2: // all pens solid with alpha blending
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 3: // solid pens only with alpha blending
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
}
while (++ecx);
src_ptr += src_fdy;
ozbuf_ptr += GX_ZBUFW;
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
case 4: // shadow pens only
do {
do {
eax = *src_ptr;
src_ptr += src_fdx;
if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
eax = dst_ptr[ecx];
szbuf_ptr[ecx*2] = z8;
szbuf_ptr[ecx*2+1] = p8;
// the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck!
dst_ptr[ecx] = shd_base[rgb_to_rgb15(eax)];
}
while (++ecx);
src_ptr += src_fdy;
szbuf_ptr += (GX_ZBUFW<<1);
dst_ptr += dst_pitch;
ecx = dst_w;
}
while (--dst_h);
break;
}
}
}
#undef FP
#undef FPONE
#undef FPHALF
#undef FPENT
}
/***************************************************************************/
/* */
@ -1242,11 +770,8 @@ void konamigx_state::konamigx_mixer_draw(running_machine &machine, bitmap_rgb32
parity ^= 1;
static const int xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
static const int yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
int xa,ya,ox,oy,zw,zh,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,scalex,scaley,nozoom;
int temp, temp1, temp2, temp3, temp4;
int order, offs, code, color, zcode, pri = 0, alpha, drawmode;
int temp1, temp2, temp3, temp4;
// traverse draw list
@ -1432,137 +957,9 @@ void konamigx_state::konamigx_mixer_draw(running_machine &machine, bitmap_rgb32
else
zcode = -1; // negative zcode values turn off z-buffering
xa = ya = 0;
if (code & 0x01) xa += 1;
if (code & 0x02) ya += 1;
if (code & 0x04) xa += 2;
if (code & 0x08) ya += 2;
if (code & 0x10) xa += 4;
if (code & 0x20) ya += 4;
code &= ~0x3f;
m_k055673->k053247_draw_single_sprite_gxcore( bitmap, cliprect, gx_objzbuf, gx_shdzbuf, code, gx_spriteram, offs, k053246_objset1, flipscreenx, flipscreeny, screenwidth, wrapsize, xwraplim, ywraplim, k053247_dx, k053247_dy, offx, offy,
k053247_gfx, color, alpha, drawmode, zcode, pri );
temp4 = gx_spriteram[offs];
// mask off the upper 6 bits of coordinate and zoom registers
oy = gx_spriteram[offs+2] & 0x3ff;
ox = gx_spriteram[offs+3] & 0x3ff;
scaley = zoomy = gx_spriteram[offs+4] & 0x3ff;
if (zoomy) zoomy = (0x400000+(zoomy>>1)) / zoomy;
else zoomy = 0x800000;
if (!(temp4 & 0x4000))
{
scalex = zoomx = gx_spriteram[offs+5] & 0x3ff;
if (zoomx) zoomx = (0x400000+(zoomx>>1)) / zoomx;
else zoomx = 0x800000;
}
else { zoomx = zoomy; scalex = scaley; }
nozoom = (scalex == 0x40 && scaley == 0x40);
flipx = temp4 & 0x1000;
flipy = temp4 & 0x2000;
temp = gx_spriteram[offs+6];
mirrorx = temp & 0x4000;
if (mirrorx) flipx = 0; // only applies to x mirror, proven
mirrory = temp & 0x8000;
// for Escape Kids (GX975)
if ( k053246_objset1 & 8 ) // Check only "Bit #3 is '1'?"
{
zoomx = zoomx>>1; // Fix sprite width to HALF size
ox = (ox>>1) + 1; // Fix sprite draw position
if (flipscreenx) ox += screenwidth;
}
if (flipscreenx) { ox = -ox; if (!mirrorx) flipx = !flipx; }
if (flipscreeny) { oy = -oy; if (!mirrory) flipy = !flipy; }
// apply wrapping and global offsets
temp = wrapsize-1;
ox += k053247_dx;
oy -= k053247_dy;
ox = ( ox - offx) & temp;
oy = (-oy - offy) & temp;
if (ox >= xwraplim) ox -= wrapsize;
if (oy >= ywraplim) oy -= wrapsize;
temp = temp4>>8 & 0x0f;
int k = 1 << (temp & 3);
int l = 1 << (temp>>2 & 3);
ox -= (zoomx * k) >> 13;
oy -= (zoomy * l) >> 13;
// substitutes: i=x, j=y, k=w, l=h, temp=code, temp1=fx, temp2=fy, temp3=sx, temp4=sy;
for (int j=0; j<l; j++)
{
temp4 = oy + ((zoomy * j + (1<<11)) >> 12);
zh = (oy + ((zoomy * (j+1) + (1<<11)) >> 12)) - temp4;
for (int i=0; i<k; i++)
{
temp3 = ox + ((zoomx * i + (1<<11)) >> 12);
zw = (ox + ((zoomx * (i+1) + (1<<11)) >> 12)) - temp3;
temp = code;
if (mirrorx)
{
if ((!flipx)^((i<<1)<k))
{
/* mirror left/right */
temp += xoffset[(k-1-i+xa)&7];
temp1 = 1;
}
else
{
temp += xoffset[(i+xa)&7];
temp1 = 0;
}
}
else
{
if (flipx) temp += xoffset[(k-1-i+xa)&7];
else temp += xoffset[(i+xa)&7];
temp1 = flipx;
}
if (mirrory)
{
if ((!flipy)^((j<<1)>=l))
{
/* mirror top/bottom */
temp += yoffset[(l-1-j+ya)&7];
temp2 = 1;
}
else
{
temp += yoffset[(j+ya)&7];
temp2 = 0;
}
}
else
{
if (flipy) temp += yoffset[(l-1-j+ya)&7];
else temp += yoffset[(j+ya)&7];
temp2 = flipy;
}
if (nozoom) { scaley = scalex = 0x10000; } else { scalex = zw << 12; scaley = zh << 12; };
zdrawgfxzoom32GP(
bitmap, cliprect, k053247_gfx,
temp,
color,
temp1,temp2,
temp3,temp4,
scalex, scaley, alpha, drawmode, zcode, pri);
}
}
}
}