Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

konami/mystwarr_v.cpp, k053246_k053247_k055673.cpp: improve sprite blending #13328

Merged
merged 11 commits into from
Feb 10, 2025
214 changes: 94 additions & 120 deletions src/mame/konami/k053246_k053247_k055673.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,46 +441,20 @@ void k053247_device::k053247_sprites_draw(bitmap_rgb32 &bitmap, const rectangle

void k053247_device::zdrawgfxzoom32GP(
bitmap_rgb32 &bitmap, const rectangle &cliprect,
u32 code, u32 color, int flipx, int flipy, int sx, int sy,
u32 code, u32 color, bool flipx, bool flipy, int sx, int sy,
int scalex, int scaley, int alpha, int drawmode, int zcode, int pri, u8* gx_objzbuf, u8* gx_shdzbuf)
{
#define FP 19
#define FPONE (1<<FP)
#define FPHALF (1<<(FP-1))
#define FPENT 0
happppp marked this conversation as resolved.
Show resolved Hide resolved

// inner loop
const u8 *src_ptr;
int src_x;
int eax, ecx;
int src_fx, src_fdx;
int shdpen;
u8 z8 = 0, p8 = 0;
u8 *ozbuf_ptr;
u8 *szbuf_ptr;
const pen_t *pal_base;
const pen_t *shd_base;
u32 *dst_ptr;

// outter loop
int src_fby, src_fdy, src_fbx;
const u8 *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 = m_gfx->granularity();
shdpen--;
const u16 granularity = m_gfx->granularity();
int shdpen = granularity - 1;

if (zcode >= 0)
{
Expand All @@ -496,30 +470,28 @@ void k053247_device::zdrawgfxzoom32GP(
if (alpha >= 255) drawmode &= ~2;
}

// cull off-screen objects
if (sx > cliprect.max_x || sy > cliprect.max_y) return;

// 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 = m_gfx->get_data(code % m_gfx->elements());

pal_base = palette().pens() + m_gfx->colorbase() + (color % m_gfx->colors()) * granularity;
shd_base = palette().shadow_table();

dst_ptr = &bitmap.pix(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;
u8 *ozbuf_ptr = gx_objzbuf;
u8 *szbuf_ptr = gx_shdzbuf;

// cull off-screen objects
if (dst_x > dst_maxx || dst_y > dst_maxy) return;
nozoom = (scalex == 0x10000 && scaley == 0x10000);
const u8 *src_base = m_gfx->get_data(code % m_gfx->elements());

const pen_t *pal_base = palette().pens() + m_gfx->colorbase() + (color % m_gfx->colors()) * granularity;
const pen_t *shd_base = palette().shadow_table();

u32 *dst_ptr = &bitmap.pix(0);
const int dst_pitch = bitmap.rowpixels();
int dst_x = sx;
int dst_y = sy;

int dst_w, dst_h;
int src_fdx, src_fdy;
int src_pitch = 16, src_fw = 16, src_fh = 16;

const bool nozoom = (scalex == 0x10000 && scaley == 0x10000);
if (nozoom)
{
dst_h = dst_w = 16;
Expand All @@ -536,18 +508,31 @@ void k053247_device::zdrawgfxzoom32GP(
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;

const int dst_lastx = dst_x + dst_w - 1;
const int dst_lasty = dst_y + dst_h - 1;
if (dst_lastx < cliprect.min_x || dst_lasty < cliprect.min_y) 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;
int dst_skipx = 0;
if (int delta_min_x = cliprect.min_x - dst_x; delta_min_x > 0)
{
dst_skipx = delta_min_x;
dst_w -= delta_min_x;
dst_x = cliprect.min_x;
}
if (int delta_max_x = dst_lastx - cliprect.max_x; delta_max_x > 0) dst_w -= delta_max_x;

int dst_skipy = 0;
if (int delta_min_y = cliprect.min_y - dst_y; delta_min_y > 0)
{
dst_skipy = delta_min_y;
dst_h -= delta_min_y;
dst_y = cliprect.min_y;
}
if (int delta_max_y = dst_lasty - cliprect.max_y; delta_max_y > 0) dst_h -= delta_max_y;

int src_fby, src_fbx;

// calculate zoom factors and clip source
if (nozoom)
Expand All @@ -564,14 +549,17 @@ void k053247_device::zdrawgfxzoom32GP(
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 = (u8)zcode;
p8 = (u8)pri;
ozbuf_ptr += eax;
szbuf_ptr += eax << 1;
const int offset = (dst_y - cliprect.min_y) * GX_ZBUFW + (dst_x - cliprect.min_x) + dst_w;
ozbuf_ptr += offset;
szbuf_ptr += offset << 1;
const u8 z8 = (u8)zcode;
const u8 p8 = (u8)pri;
dst_ptr += dst_y * dst_pitch + dst_x + dst_w;
dst_w = -dst_w;

int src_fx, src_x, ecx;
const u8 *src_ptr;

if (!nozoom)
{
ecx = src_fby; src_fby += src_fdy;
Expand All @@ -585,12 +573,11 @@ void k053247_device::zdrawgfxzoom32GP(
{
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
const u8 pal_idx = src_ptr[src_x];
src_x = src_fx >> FP;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen) continue;
dst_ptr [ecx] = pal_base[eax];
if (!pal_idx || pal_idx >= shdpen) continue;
dst_ptr[ecx] = pal_base[pal_idx];
}
while (++ecx);

Expand All @@ -611,14 +598,12 @@ void k053247_device::zdrawgfxzoom32GP(
case 0: // all pens solid
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
const u8 pal_idx = src_ptr[src_x];
src_x = src_fx >> FP;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
if (!pal_idx || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr [ecx] = eax;
dst_ptr[ecx] = pal_base[pal_idx];
}
while (++ecx);

Expand All @@ -637,14 +622,12 @@ void k053247_device::zdrawgfxzoom32GP(
case 1: // solid pens only
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
const u8 pal_idx = src_ptr[src_x];
src_x = src_fx >> FP;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
if (!pal_idx || pal_idx >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr [ecx] = eax;
dst_ptr[ecx] = pal_base[pal_idx];
}
while (++ecx);

Expand All @@ -663,14 +646,12 @@ void k053247_device::zdrawgfxzoom32GP(
case 2: // all pens solid with alpha blending
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
const u8 pal_idx = src_ptr[src_x];
src_x = src_fx >> FP;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
if (!pal_idx || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;

dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
dst_ptr[ecx] = alpha_blend_r32(dst_ptr[ecx], pal_base[pal_idx], alpha);
}
while (++ecx);

Expand All @@ -689,14 +670,12 @@ void k053247_device::zdrawgfxzoom32GP(
case 3: // solid pens only with alpha blending
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
const u8 pal_idx = src_ptr[src_x];
src_x = src_fx >> FP;
src_fx += src_fdx;
src_x >>= FP;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
if (!pal_idx || pal_idx >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;

dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
dst_ptr[ecx] = alpha_blend_r32(dst_ptr[ecx], pal_base[pal_idx], alpha);
}
while (++ecx);

Expand All @@ -715,11 +694,10 @@ void k053247_device::zdrawgfxzoom32GP(
case 4: // shadow pens only
do {
do {
eax = src_ptr[src_x];
src_x = src_fx;
const u8 pal_idx = src_ptr[src_x];
src_x = src_fx >> FP;
src_fx += src_fdx;
src_x >>= FP;
if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
if (pal_idx < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
rgb_t pix = dst_ptr[ecx];
szbuf_ptr[ecx*2] = z8;
szbuf_ptr[ecx*2+1] = p8;
Expand Down Expand Up @@ -754,10 +732,10 @@ void k053247_device::zdrawgfxzoom32GP(
{
do {
do {
eax = *src_ptr;
const u8 pal_idx = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen) continue;
dst_ptr[ecx] = pal_base[eax];
if (!pal_idx || pal_idx >= shdpen) continue;
dst_ptr[ecx] = pal_base[pal_idx];
}
while (++ecx);

Expand All @@ -774,12 +752,11 @@ void k053247_device::zdrawgfxzoom32GP(
case 0: // all pens solid
do {
do {
eax = *src_ptr;
const u8 pal_idx = *src_ptr;
src_ptr += src_fdx;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
if (!pal_idx || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = eax;
dst_ptr[ecx] = pal_base[pal_idx];
}
while (++ecx);

Expand All @@ -794,12 +771,11 @@ void k053247_device::zdrawgfxzoom32GP(
case 1: // solid pens only
do {
do {
eax = *src_ptr;
const u8 pal_idx = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
eax = pal_base[eax];
if (!pal_idx || pal_idx >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;
dst_ptr[ecx] = eax;
dst_ptr[ecx] = pal_base[pal_idx];
}
while (++ecx);

Expand All @@ -814,12 +790,11 @@ void k053247_device::zdrawgfxzoom32GP(
case 2: // all pens solid with alpha blending
do {
do {
eax = *src_ptr;
const u8 pal_idx = *src_ptr;
src_ptr += src_fdx;
if (!eax || ozbuf_ptr[ecx] < z8) continue;
if (!pal_idx || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;

dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
dst_ptr[ecx] = alpha_blend_r32(dst_ptr[ecx], pal_base[pal_idx], alpha);
}
while (++ecx);

Expand All @@ -834,12 +809,11 @@ void k053247_device::zdrawgfxzoom32GP(
case 3: // solid pens only with alpha blending
do {
do {
eax = *src_ptr;
const u8 pal_idx = *src_ptr;
src_ptr += src_fdx;
if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
if (!pal_idx || pal_idx >= shdpen || ozbuf_ptr[ecx] < z8) continue;
ozbuf_ptr[ecx] = z8;

dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
dst_ptr[ecx] = alpha_blend_r32(dst_ptr[ecx], pal_base[pal_idx], alpha);
}
while (++ecx);

Expand All @@ -854,9 +828,9 @@ void k053247_device::zdrawgfxzoom32GP(
case 4: // shadow pens only
do {
do {
eax = *src_ptr;
const u8 pal_idx = *src_ptr;
src_ptr += src_fdx;
if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
if (pal_idx < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
rgb_t pix = dst_ptr[ecx];
szbuf_ptr[ecx*2] = z8;
szbuf_ptr[ecx*2+1] = p8;
Expand Down
2 changes: 1 addition & 1 deletion src/mame/konami/k053246_k053247_k055673.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class k053247_device : public device_t,
/* alt implementation - to be collapsed */
void zdrawgfxzoom32GP(
bitmap_rgb32 &bitmap, const rectangle &cliprect,
u32 code, u32 color, int flipx, int flipy, int sx, int sy,
u32 code, u32 color, bool flipx, bool flipy, int sx, int sy,
int scalex, int scaley, int alpha, int drawmode, int zcode, int pri, u8* gx_objzbuf, u8* gx_shdzbuf);

void zdrawgfxzoom32GP(
Expand Down
2 changes: 1 addition & 1 deletion src/mame/konami/mystwarr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1125,7 +1125,7 @@ void mystwarr_state::dadandrn(machine_config &config)

m_k056832->set_tile_callback(FUNC(mystwarr_state::game5bpp_tile_callback));

m_k055673->set_sprite_callback(FUNC(mystwarr_state::gaiapols_sprite_callback));
m_k055673->set_sprite_callback(FUNC(mystwarr_state::mystwarr_sprite_callback));
m_k055673->set_config(K055673_LAYOUT_GX, -42, -22);
}

Expand Down
Loading
Loading