diff --git a/src/mame/konami/k053246_k053247_k055673.cpp b/src/mame/konami/k053246_k053247_k055673.cpp index a070f1ecdab..b8e7dcb5add 100644 --- a/src/mame/konami/k053246_k053247_k055673.cpp +++ b/src/mame/konami/k053246_k053247_k055673.cpp @@ -439,12 +439,11 @@ 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, 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) + int scalex, int scaley, int alpha, int drawmode, int zcode, u8 pri, u8* gx_objzbuf, u8* gx_shdzbuf) { - constexpr int FP = 19; - constexpr int FPENT = 0; + constexpr u8 FP = 19; // 13.19 fixed point - // cull illegal and transparent objects + // cull objects with invalid scale if (!scalex || !scaley) return; // find shadow pens and cull invisible shadows @@ -453,267 +452,145 @@ void k053247_device::zdrawgfxzoom32GP( if (zcode >= 0) { - if (drawmode == 5) { drawmode = 4; shdpen = 1; } + if (drawmode == 5) + { + drawmode = 4; + shdpen = 1; + } } - else - if (drawmode >= 4) return; + else if (drawmode >= 4) return; - // alpha blend necessary? + // alpha blend check: cull if 0% opaque, or skip alpha blending if 100% opaque if (drawmode & 2) { - if (alpha <= 0) return; - if (alpha >= 255) drawmode &= ~2; + if (!alpha) return; + if (alpha == 255) drawmode &= ~2; } - // cull off-screen objects - if (sx > cliprect.max_x || sy > cliprect.max_y) return; + rectangle dst_rect = rectangle {sx, 0, sy, 0}; + dst_rect.set_size(((scalex << 4) + 0x8000) >> 16, ((scaley << 4) + 0x8000) >> 16); - // fill internal data structure with default values - u8 *ozbuf_ptr = gx_objzbuf; - u8 *szbuf_ptr = gx_shdzbuf; + // cull off-screen and zero height/width objects + if (dst_rect.left() > cliprect.right() || dst_rect.right() < cliprect.left()) return; + if (dst_rect.top() > cliprect.bottom() || dst_rect.bottom() < cliprect.top()) return; + if (!dst_rect.width() || !dst_rect.height()) return; + + constexpr u8 src_size = 16; + const int src_stride_x = (src_size << FP) / dst_rect.width(); + const int src_stride_y = (src_size << FP) / dst_rect.height(); + + const int src_offset_x = std::max(cliprect.left() - dst_rect.left(), 0); + const int src_offset_y = std::max(cliprect.top() - dst_rect.top(), 0); + + const int src_base_x = src_offset_x * src_stride_x; + const int src_base_y = src_offset_y * src_stride_y; + + // exclude dst_rect area outside cliprect + dst_rect &= cliprect; + + // invert src x/y offsets if flip enabled + u8 flip_mask = 0; + if (flipx) flip_mask |= src_size - 1; + if (flipy) flip_mask |= (src_size - 1) << 4; + + const int dst_pitch = bitmap.rowpixels(); + u32 *dst_ptr = &bitmap.pix(0) + dst_rect.left() + dst_rect.top() * dst_pitch; 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; + const int z_buffer_offset = (dst_rect.top() - cliprect.top()) * GX_ZBUFW + (dst_rect.left() - cliprect.left()); + u8 *ozbuf_ptr = gx_objzbuf + z_buffer_offset; - 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; - 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; - } - - 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 - 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) - { - 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 - 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) + if (zcode < 0) { - 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; + // no shadow and z-buffering - if (zcode < 0) // no shadow and z-buffering + for (int y = 0; y < dst_rect.height(); ++y) { - do { - do { - const u8 pal_idx = src_ptr[src_x]; - src_x = src_fx >> FP; - src_fx += src_fdx; - if (!pal_idx || pal_idx >= shdpen) continue; - dst_ptr[ecx] = pal_base[pal_idx]; - } - 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; + for (int x = 0; x < dst_rect.width(); ++x) + { + const int x_off = (src_base_x + x * src_stride_x) >> FP; + const int y_off = (src_base_y + y * src_stride_y) >> FP; + const u8 pal_idx = src_base[(x_off + y_off * 16) ^ flip_mask]; + if (!pal_idx || pal_idx >= shdpen) continue; + ozbuf_ptr[x + y * GX_ZBUFW] = z8; + dst_ptr[x + y * dst_pitch] = pal_base[pal_idx]; } - while (--dst_h); } - else if (drawmode < 4) + } + else if (drawmode < 4) + { + // 0: all pens solid + // 1: solid pens only + // 2: all pens solid with alpha blending + // 3: solid pens only with alpha blending + + for (int y = 0; y < dst_rect.height(); ++y) { - // 0: all pens solid - // 1: solid pens only - // 2: all pens solid with alpha blending - // 3: solid pens only with alpha blending - do { - do { - const u8 pal_idx = src_ptr[src_x]; - src_x = src_fx >> FP; - src_fx += src_fdx; - if (!pal_idx || (drawmode & 0b01 && pal_idx >= shdpen) || ozbuf_ptr[ecx] < z8) continue; - ozbuf_ptr[ecx] = z8; - dst_ptr[ecx] = (drawmode & 0b10) ? alpha_blend_r32(dst_ptr[ecx], pal_base[pal_idx], alpha) : pal_base[pal_idx]; + for (int x = 0; x < dst_rect.width(); ++x) + { + const int x_off = (src_base_x + x * src_stride_x) >> FP; + const int y_off = (src_base_y + y * src_stride_y) >> FP; + const u8 pal_idx = src_base[(x_off + y_off * 16) ^ flip_mask]; + if (!pal_idx || (drawmode & 0b01 && pal_idx >= shdpen) || ozbuf_ptr[x + y * GX_ZBUFW] < z8) continue; + ozbuf_ptr[x + y * GX_ZBUFW] = z8; + + if ((drawmode & 0b10) == 0) // solid sprite + { + dst_ptr[x + y * dst_pitch] = pal_base[pal_idx]; } - while (++ecx); + else // alpha blended sprite + { + const u8 alpha_level = alpha; + const bool additive_mode = alpha & (1 << 8); + // mix_pri flips src & dst + // todo: find a game that exhibits this behavior + // const bool mix_pri = alpha & (1 << 9); - 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); - } - else - { - // 4: shadow pens only - do { - do { - const u8 pal_idx = src_ptr[src_x]; - src_x = src_fx >> FP; - src_fx += src_fdx; - 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; + const u32 src = pal_base[pal_idx]; + const u32 dst = dst_ptr[x + y * dst_pitch]; - // the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck! - dst_ptr[ecx] = shd_base[pix.as_rgb15()]; - //dst_ptr[ecx] =(eax>>3&0x001f);lend_r32(eax, 0x00000000, 128); + if (additive_mode) + { + // todo: improve additive blend calculation + const u32 temp = alpha_blend_r32(src, 0, alpha_level); + dst_ptr[x + y * dst_pitch] = add_blend_r32(dst, temp); + } + else + { + dst_ptr[x + y * dst_pitch] = alpha_blend_r32(dst, src, alpha_level); + } } - 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); } - } // if (!nozoom) + } else { - src_ptr = src_base + (src_fby<<4) + src_fbx; - src_fdy = src_fdx * dst_w + src_pitch; - ecx = dst_w; + // 4: shadow pens only - if (zcode < 0) // no shadow and z-buffering + const pen_t *shd_base = palette().shadow_table(); + u8 *szbuf_ptr = gx_shdzbuf + z_buffer_offset * 2; + + for (int y = 0; y < dst_rect.height(); ++y) { - do { - do { - const u8 pal_idx = *src_ptr; - src_ptr += src_fdx; - if (!pal_idx || pal_idx >= shdpen) continue; - dst_ptr[ecx] = pal_base[pal_idx]; - } - while (++ecx); + for (int x = 0; x < dst_rect.width(); ++x) + { + const int x_off = (src_base_x + x * src_stride_x) >> FP; + const int y_off = (src_base_y + y * src_stride_y) >> FP; + const u8 pal_idx = src_base[(x_off + y_off * 16) ^ flip_mask]; + const int szbuf_offset = x * 2 + y * GX_ZBUFW * 2; + if (pal_idx < shdpen || szbuf_ptr[szbuf_offset] < z8 || szbuf_ptr[szbuf_offset + 1] <= pri) continue; + szbuf_ptr[szbuf_offset] = z8; + szbuf_ptr[szbuf_offset + 1] = pri; - src_ptr += src_fdy; - dst_ptr += dst_pitch; - ecx = dst_w; + rgb_t pix = dst_ptr[x + y * dst_pitch]; + // the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck! + dst_ptr[x + y * dst_pitch] = shd_base[pix.as_rgb15()]; + //dst_ptr[ecx] =(eax>>3&0x001f);lend_r32(eax, 0x00000000, 128); } - while (--dst_h); - } - else if (drawmode < 4) - { - // 0: all pens solid - // 1: solid pens only - // 2: all pens solid with alpha blending - // 3: solid pens only with alpha blending - do { - do { - const u8 pal_idx = *src_ptr; - src_ptr += src_fdx; - if (!pal_idx || (drawmode & 0b01 && pal_idx >= shdpen) || ozbuf_ptr[ecx] < z8) continue; - ozbuf_ptr[ecx] = z8; - dst_ptr[ecx] = (drawmode & 0b10) ? alpha_blend_r32(dst_ptr[ecx], pal_base[pal_idx], alpha) : pal_base[pal_idx]; - } - while (++ecx); - - src_ptr += src_fdy; - ozbuf_ptr += GX_ZBUFW; - dst_ptr += dst_pitch; - ecx = dst_w; - } - while (--dst_h); - } - else - { - // 4: shadow pens only - do { - do { - const u8 pal_idx = *src_ptr; - src_ptr += src_fdx; - 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; - - // the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck! - dst_ptr[ecx] = shd_base[pix.as_rgb15()]; - } - while (++ecx); - - src_ptr += src_fdy; - szbuf_ptr += (GX_ZBUFW<<1); - dst_ptr += dst_pitch; - ecx = dst_w; - } - while (--dst_h); } } } diff --git a/src/mame/konami/k053246_k053247_k055673.h b/src/mame/konami/k053246_k053247_k055673.h index d73c9967fe8..681d7d98f2a 100644 --- a/src/mame/konami/k053246_k053247_k055673.h +++ b/src/mame/konami/k053246_k053247_k055673.h @@ -112,7 +112,7 @@ public: void zdrawgfxzoom32GP( bitmap_rgb32 &bitmap, const rectangle &cliprect, 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); + int scalex, int scaley, int alpha, int drawmode, int zcode, u8 pri, u8* gx_objzbuf, u8* gx_shdzbuf); void zdrawgfxzoom32GP( bitmap_ind16 &bitmap, const rectangle &cliprect, diff --git a/src/mame/konami/k054156_k054157_k056832.cpp b/src/mame/konami/k054156_k054157_k056832.cpp index dfa835f4ec2..bf47d0f1c3e 100644 --- a/src/mame/konami/k054156_k054157_k056832.cpp +++ b/src/mame/konami/k054156_k054157_k056832.cpp @@ -506,7 +506,7 @@ void k056832_device::get_tile_info( tile_data &tileinfo, int tile_index, int pa color = (attr & smptr->palm1) | (attr >> smptr->pals2 & smptr->palm2); flags = TILE_FLIPYX(flip); - m_k056832_cb(layer, &code, &color, &flags, &priority); + m_k056832_cb(layer, &code, &color, &flags, &priority, attr); tileinfo.set(m_gfx_num, code, diff --git a/src/mame/konami/k054156_k054157_k056832.h b/src/mame/konami/k054156_k054157_k056832.h index 538df05efc2..b9417ceb780 100644 --- a/src/mame/konami/k054156_k054157_k056832.h +++ b/src/mame/konami/k054156_k054157_k056832.h @@ -8,7 +8,7 @@ #include "k055555.h" // still needs k055555_get_palette_index #include "tilemap.h" -#define K056832_CB_MEMBER(_name) void _name(int layer, int *code, int *color, int *flags, int *priority) +#define K056832_CB_MEMBER(_name) void _name(int layer, int *code, int *color, int *flags, int *priority, u16 attr) #define K056832_PAGE_COUNT 16 @@ -31,7 +31,7 @@ class k055555_device; class k056832_device : public device_t, public device_gfx_interface { public: - using tile_delegate = device_delegate; + using tile_delegate = device_delegate; template k056832_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&mixer_tag) : k056832_device(mconfig, tag, owner, clock) diff --git a/src/mame/konami/k054338.cpp b/src/mame/konami/k054338.cpp index 8e0e61fd5c3..f81e6ffeb4c 100644 --- a/src/mame/konami/k054338.cpp +++ b/src/mame/konami/k054338.cpp @@ -65,7 +65,7 @@ u16 k054338_device::register_r(offs_t offset) return m_regs[offset]; } -void k054338_device::update_all_shadows( int rushingheroes_hack, palette_device &palette ) +void k054338_device::update_all_shadows(int rushingheroes_hack, palette_device &palette) { int i, d; int noclip = m_regs[K338_REG_CONTROL] & K338_CTL_CLIPSL; @@ -73,8 +73,7 @@ void k054338_device::update_all_shadows( int rushingheroes_hack, palette_device for (i = 0; i < 9; i++) { d = m_regs[K338_REG_SHAD1R + i] & 0x1ff; - if (d >= 0x100) - d -= 0x200; + if (d >= 0x100) d -= 0x200; m_shd_rgb[i] = d; } @@ -93,7 +92,7 @@ void k054338_device::update_all_shadows( int rushingheroes_hack, palette_device } // k054338 BG color fill -void k054338_device::fill_solid_bg( bitmap_rgb32 &bitmap, const rectangle &cliprect ) +void k054338_device::fill_solid_bg(bitmap_rgb32 &bitmap, const rectangle &cliprect) { uint32_t bgcolor = (register_r(K338_REG_BGC_R) & 0xff) << 16; bgcolor |= register_r(K338_REG_BGC_GB); @@ -142,60 +141,43 @@ void k054338_device::fill_backcolor(bitmap_rgb32 &bitmap, const rectangle &clipr } // addition blending unimplemented (requires major changes to drawgfx and tilemap.cpp) -int k054338_device::set_alpha_level( int pblend ) +int k054338_device::set_alpha_level(int pblend) { - uint16_t *regs; - int ctrl, mixpri, mixset, mixlv; + if (pblend > 3) logerror("mixing mode index out of range: %d (valid range: 0-3)", pblend); - if (pblend <= 0 || pblend > 3) - { - return (255); - } + if (!pblend) return 255; - regs = m_regs; - ctrl = m_regs[K338_REG_CONTROL]; - mixpri = ctrl & K338_CTL_MIXPRI; - mixset = regs[K338_REG_PBLEND + (pblend >> 1 & 1)] >> (~pblend << 3 & 8); - mixlv = mixset & 0x1f; + // sanitize input + pblend &= 0b11; - if (m_alpha_inv) - mixlv = 0x1f - mixlv; + const u8 mixset = m_regs[K338_REG_PBLEND + (pblend >> 1 & 1)] >> (~pblend << 3 & 8); + int mixlv = mixset & 0x1f; - if (!(mixset & 0x20)) - { - mixlv = (mixlv << 3) | (mixlv >> 2); - } - else - { - if (!mixpri) - { - // source x alpha + target (clipped at 255) - } - else - { - // source + target x alpha (clipped at 255) - } + if (m_alpha_inv) mixlv = 0x1f - mixlv; - // DUMMY - if (mixlv && mixlv < 0x1f) - mixlv = 0x10; + // expand mix level (5 bits -> 8) + mixlv = (mixlv << 3) | (mixlv >> 2); - mixlv = (mixlv << 3) | (mixlv >> 2); + const bool additive_mode = mixset & 0x20; + const bool mixpri = m_regs[K338_REG_CONTROL] & K338_CTL_MIXPRI; - if (VERBOSE) - popmessage("MIXSET%1d %s addition mode: %02x", pblend, (mixpri) ? "dst" : "src", mixset & 0x1f); - } + mixlv |= additive_mode << 8; + mixlv |= mixpri << 9; + // returns 10 bits: pa llll llll + // p: MI (mixpri) + // a: additive mode + // l: alpha level (expanded) return mixlv; } -void k054338_device::invert_alpha( int invert ) +void k054338_device::invert_alpha(int invert) { m_alpha_inv = invert; } -void k054338_device::export_config( int **shd_rgb ) +void k054338_device::export_config(int **shd_rgb) { *shd_rgb = m_shd_rgb; } diff --git a/src/mame/konami/konamigx.cpp b/src/mame/konami/konamigx.cpp index 0fcf1d93ce6..707cb1d3946 100644 --- a/src/mame/konami/konamigx.cpp +++ b/src/mame/konami/konamigx.cpp @@ -1860,6 +1860,8 @@ void konamigx_state::salmndr2(machine_config &config) konamigx(config); m_k056832->set_config(K056832_BPP_6, 1, 0); + m_k056832->set_tile_callback(FUNC(konamigx_state::salmndr2_tile_callback)); + m_k055673->set_sprite_callback(FUNC(konamigx_state::salmndr2_sprite_callback)); m_k055673->set_config(K055673_LAYOUT_GX6, -48, -23); } diff --git a/src/mame/konami/konamigx.h b/src/mame/konami/konamigx.h index a36b4063184..65af2df436d 100644 --- a/src/mame/konami/konamigx.h +++ b/src/mame/konami/konamigx.h @@ -115,13 +115,18 @@ public: TIMER_CALLBACK_MEMBER(boothack_callback); double adc0834_callback(uint8_t input); K056832_CB_MEMBER(type2_tile_callback); + K056832_CB_MEMBER(salmndr2_tile_callback); K056832_CB_MEMBER(alpha_tile_callback); K055673_CB_MEMBER(type2_sprite_callback); K055673_CB_MEMBER(dragoonj_sprite_callback); K055673_CB_MEMBER(salmndr2_sprite_callback); K055673_CB_MEMBER(le2_sprite_callback); - struct GX_OBJ { int order = 0, offs = 0, code = 0, color = 0; }; + struct GX_OBJ + { + u32 order = 0; + int offs = 0, code = 0, color = 0; + }; void common_init(); uint32_t k_6bpp_rom_long_r(offs_t offset, uint32_t mem_mask = ~0); @@ -130,13 +135,11 @@ public: tilemap_t *sub1, int sub1flags, tilemap_t *sub2, int sub2flags, int mixerflags, bitmap_ind16 *extra_bitmap, int rushingheroes_hack, - GX_OBJ *objpool, - int *objbuf, - int nobj + const std::vector &objpool ); - void gx_draw_basic_tilemaps(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mixerflags, int code); + void gx_draw_basic_tilemaps(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mixerflags, uint8_t layer); void gx_draw_basic_extended_tilemaps_1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mixerflags, int code, tilemap_t *sub1, int sub1flags, int rushingheroes_hack, int offs); void gx_draw_basic_extended_tilemaps_2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mixerflags, int code, tilemap_t *sub2, int sub2flags, bitmap_ind16 *extra_bitmap, int offs); @@ -253,6 +256,8 @@ protected: u8 m_current_brightness = 0xff; u8 m_brightness[3]{}; + u8 m_last_alpha_tile_mix_code = 0; + // mirrored K054338 settings int *m_K054338_shdRGB = nullptr; @@ -303,8 +308,6 @@ protected: std::unique_ptr m_gxtype1_roz_dstbitmap2; rectangle m_gxtype1_roz_dstbitmapclip; - std::unique_ptr m_gx_objpool; - u8 m_type3_psac2_bank = 0; u8 m_type3_spriteram_bank = 0; //int m_konamigx_type3_psac2_actual_last_bank = 0; @@ -339,6 +342,7 @@ protected: ----FFEEDDCCBBAA---------------- (layer A-F mix codes in forced blending) ---x---------------------------- (disable shadows) --x----------------------------- (disable z-buffering) + yy------------------------------ (last encountered tile mix code) */ #define GXMIX_BLEND_AUTO 0 // emulate all blend effects #define GXMIX_BLEND_NONE 1 // disable all blend effects diff --git a/src/mame/konami/konamigx_v.cpp b/src/mame/konami/konamigx_v.cpp index cdde3894abf..f0e4b232f13 100644 --- a/src/mame/konami/konamigx_v.cpp +++ b/src/mame/konami/konamigx_v.cpp @@ -55,9 +55,9 @@ void konamigx_state::konamigx_precache_registers(void) m_osinmix = m_k055555->K055555_read_register(K55_OSBLEND_ENABLES); m_osmixon = m_k055555->K055555_read_register(K55_OSBLEND_ON); - m_brightness[0] = u8(m_k054338->register_r(K338_REG_BRI3)); - m_brightness[1] = u8(m_k054338->register_r(K338_REG_BRI3 + 1) >> 8); - m_brightness[2] = u8(m_k054338->register_r(K338_REG_BRI3 + 1)); + m_brightness[0] = uint8_t(m_k054338->register_r(K338_REG_BRI3)); + m_brightness[1] = uint8_t(m_k054338->register_r(K338_REG_BRI3 + 1) >> 8); + m_brightness[2] = uint8_t(m_k054338->register_r(K338_REG_BRI3 + 1)); } inline int konamigx_state::K053247GX_combine_c18(int attrib) // (see p.46) @@ -249,9 +249,9 @@ void konamigx_state::wipezbuf(int noshadow) void konamigx_state::set_brightness(int layer) { - const u8 bri_mode = (m_k055555->K055555_read_register(K55_VBRI) >> layer * 2) & 0b11; + const uint8_t bri_mode = (m_k055555->K055555_read_register(K55_VBRI) >> layer * 2) & 0b11; - const u8 new_brightness = bri_mode ? m_brightness[bri_mode - 1] : 0xff; + const uint8_t new_brightness = bri_mode ? m_brightness[bri_mode - 1] : 0xff; if (m_current_brightness != new_brightness) { @@ -291,7 +291,7 @@ void konamigx_state::set_brightness(int layer) * shadow enables transparent shadows. Note that it applies to the last sprite pen ONLY. * The rest of the sprite remains normal. */ -#define GX_MAX_SPRITES 512*2 +#define GX_MAX_SPRITES 256*2 // 256 sprites + 256 shadows #define GX_MAX_LAYERS 6 #define GX_MAX_OBJECTS (GX_MAX_SPRITES + GX_MAX_LAYERS) @@ -302,7 +302,6 @@ void konamigx_state::konamigx_mixer_init(screen_device &screen, int objdma) m_gx_objzbuf = &screen.priority().pix(0); m_gx_shdzbuf = std::make_unique(GX_ZBUFSIZE); - m_gx_objpool = std::make_unique(GX_MAX_OBJECTS); m_k054338->export_config(&m_K054338_shdRGB); @@ -337,19 +336,11 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, tilemap_t *sub2, int sub2flags, int mixerflags, bitmap_ind16 *extra_bitmap, int rushingheroes_hack) { - int objbuf[GX_MAX_OBJECTS]; - int shadowon[3], shdpri[3], layerid[6], layerpri[6]; - - GX_OBJ *objpool, *objptr; - int cltc_shdpri, /*prflp,*/ disp; + // int prflp; // buffer can move when it's resized, so refresh the pointer m_gx_objzbuf = &screen.priority().pix(0); - // abort if object database failed to initialize - objpool = m_gx_objpool.get(); - if (!objpool) return; - // clear screen with backcolor and update flicker pulse if (m_gx_wrport1_0 & 0x20) m_k054338->fill_backcolor(bitmap, @@ -360,9 +351,9 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, m_k054338->fill_solid_bg(bitmap, cliprect); // abort if video has been disabled - disp = m_k055555->K055555_read_register(K55_INPUT_ENABLES); + const uint8_t disp = m_k055555->K055555_read_register(K55_INPUT_ENABLES); if (!disp) return; - cltc_shdpri = m_k054338->register_r(K338_REG_CONTROL); + uint16_t cltc_shdpri = m_k054338->register_r(K338_REG_CONTROL); if (!rushingheroes_hack) // Slam Dunk 2 never sets this. It's either part of the protection, or type4 doesn't use it @@ -384,12 +375,13 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, konamigx_precache_registers(); // init OBJSET2 and mixer parameters (see p.51 and chapter 7) - layerid[0] = 0; layerid[1] = 1; layerid[2] = 2; layerid[3] = 3; layerid[4] = 4; layerid[5] = 5; + uint8_t layerid[6] = {0, 1, 2, 3, 4, 5}; // invert layer priority when this flag is set (not used by any GX game?) //prflp = K055555_read_register(K55_CONTROL) & K55_CTL_FLIPPRI; + uint8_t layerpri[6]; layerpri[0] = m_k055555->K055555_read_register(K55_PRIINP_0); layerpri[1] = m_k055555->K055555_read_register(K55_PRIINP_3); layerpri[3] = m_k055555->K055555_read_register(K55_PRIINP_7); @@ -411,10 +403,12 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, } // SHDPRISEL filters shadows by different priority comparison methods (UNIMPLEMENTED, see detail on p.66) + bool shadowon[3]; if (!(shdprisel & 0x03)) shadowon[0] = 0; if (!(shdprisel & 0x0c)) shadowon[1] = 0; if (!(shdprisel & 0x30)) shadowon[2] = 0; + uint8_t shdpri[3]; shdpri[0] = m_k055555->K055555_read_register(K55_SHAD1_PRI); shdpri[1] = m_k055555->K055555_read_register(K55_SHAD2_PRI); shdpri[2] = m_k055555->K055555_read_register(K55_SHAD3_PRI); @@ -446,27 +440,24 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, // pre-sort layers for (int j=0; j<5; j++) { - int temp1 = layerpri[j]; for (int i=j+1; i<6; i++) { - int temp2 = layerpri[i]; - if ((uint32_t)temp1 <= (uint32_t)temp2) + if (layerpri[j] <= layerpri[i]) { - layerpri[i] = temp1; layerpri[j] = temp1 = temp2; - temp2 = layerid[i]; layerid[i] = layerid[j]; layerid[j] = temp2; + std::swap(layerpri[j], layerpri[i]); + std::swap(layerid[j], layerid[i]); } } } // build object database and create indices - objptr = objpool; - int nobj = 0; + std::vector objpool; // max size: 6 layers + 256 sprites + 256 shadows for (int i=5; i>=0; i--) { int offs; - int code = layerid[i]; + const uint8_t code = layerid[i]; switch (code) { /* @@ -493,61 +484,45 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, if (offs != -128) { - objptr->order = layerpri[i]<<24; - objptr->code = code; - objptr->offs = offs; - objptr++; - - objbuf[nobj] = nobj; - nobj++; + const uint32_t order = layerpri[i] << 24; + const int color = 0; + objpool.push_back(GX_OBJ{order, offs, code, color}); } } -// i = j = 0xff; - int l = 0; + const uint32_t start_addr = m_type3_spriteram_bank ? 0x800 : 0; - u32 start_addr = m_type3_spriteram_bank ? 0x800 : 0; - u32 end_addr = start_addr + 0x800; - - - for (int offs=start_addr; offsm_k053247_cb(&code, &color, &pri); - /* - shadow = shadow code - spri = shadow priority - temp1 = add solid object - temp2 = solid pens draw mode - temp3 = add shadow object - temp4 = shadow pens draw mode - */ - int temp4 = 0; - int temp3 = 0; - int temp2 = 0; - int temp1 = 0; - int spri = 0; - int shadow = 0; + uint8_t shadow_draw_mode = 0; // shadow pens draw mode (4-5) + bool add_shadow = 0; // add shadow object + uint8_t solid_draw_mode = 0; // solid pens draw mode (0-3) + bool add_solid = 0; // add solid object + uint8_t spri = 0; // shadow priority + uint8_t shadow = 0; // shadow code if (color & K055555_FULLSHADOW) { shadow = 3; // use default intensity and color spri = pri; // retain host priority - temp3 = 1; // add shadow - temp4 = 5; // draw full shadow + add_shadow = 1; + shadow_draw_mode = 5; // draw full shadow } else { @@ -558,12 +533,12 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, if (shadow != 1 || k053246_objset1 & 0x20) { shadow--; - temp1 = 1; // add solid - temp2 = 1; // draw partial solid + add_solid = 1; + solid_draw_mode = 1; // draw partial solid if (shadowon[shadow]) { - temp3 = 1; // add shadow - temp4 = 4; // draw partial shadow + add_shadow = 1; + shadow_draw_mode = 4; // draw partial shadow } } else @@ -571,23 +546,23 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, // drop the entire sprite to shadow if its shadow code is 1 and SD0EN is off (see p.48) shadow = 0; if (!shadowon[0]) continue; - temp3 = 1; // add shadow - temp4 = 5; // draw full shadow + add_shadow = 1; + shadow_draw_mode = 5; // draw full shadow } } else { - temp1 = 1; // add solid - temp2 = 0; // draw full solid + add_solid = 1; + solid_draw_mode = 0; // draw full solid } - if (temp1) + if (add_solid) { // tag sprite for alpha blending - if (color>>K055555_MIXSHIFT & 3) temp2 |= 2; + if (color>>K055555_MIXSHIFT & 3) solid_draw_mode |= 2; } - if (temp3) + if (add_shadow) { // determine shadow priority spri = (m_k053247_opset & 0x20) ? pri : shdpri[shadow]; // (see p.51 OPSET SDSEL) @@ -621,97 +596,171 @@ void konamigx_state::konamigx_mixer(screen_device &screen, bitmap_rgb32 &bitmap, ------------------------xxxx---- (shadow mode) ----------------------------xxxx (shadow code) */ - if (temp1) + if (add_solid) { // add objects with solid or alpha pens - int order = pri<<24 | zcode<<16 | offs<<(8-3) | temp2<<4; - objptr->order = order; - objptr->offs = offs; - objptr->code = code; - objptr->color = color; - objptr++; - - objbuf[nobj] = nobj; - nobj++; + uint32_t order = pri<<24 | zcode<<16 | offs<<(8-3) | solid_draw_mode<<4; + objpool.push_back(GX_OBJ{order, offs, code, color}); } - if (temp3 && !(color & K055555_SKIPSHADOW) && !(mixerflags & GXMIX_NOSHADOW)) + if (add_shadow && !(color & K055555_SKIPSHADOW) && !(mixerflags & GXMIX_NOSHADOW)) { // add objects with shadows if enabled - int order = spri<<24 | zcode<<16 | offs<<(8-3) | temp4<<4 | shadow; - objptr->order = order; - objptr->offs = offs; - objptr->code = code; - objptr->color = color; - objptr++; - - objbuf[nobj] = nobj; - nobj++; - } - } - - // sort objects in decending order (SLOW) - k = nobj; - l = nobj - 1; - - for (int j=0; j b.order; + }); konamigx_mixer_draw(screen,bitmap,cliprect,sub1,sub1flags,sub2,sub2flags,mixerflags,extra_bitmap,rushingheroes_hack, - objpool, - objbuf, - nobj + objpool ); } -void konamigx_state::gx_draw_basic_tilemaps(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mixerflags, int code) +void konamigx_state::konamigx_mixer_draw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, + tilemap_t *sub1, int sub1flags, + tilemap_t *sub2, int sub2flags, + int mixerflags, bitmap_ind16 *extra_bitmap, int rushingheroes_hack, + + /* passed from above function */ + const std::vector &objpool + ) { - int temp1,temp2,temp3,temp4; - int i = code<<1; - int j = mixerflags>>i & 3; - int k = 0; + // traverse draw list + const uint8_t disp = m_k055555->K055555_read_register(K55_INPUT_ENABLES); - int disp = m_k055555->K055555_read_register(K55_INPUT_ENABLES); - if (disp & (1<>(i+16); temp3 = 3; } + /* entries >=0 in our list are sprites */ + if (offs >= 0) + { + if (!(disp & K55_INP_OBJ)) continue; + + int drawmode = order>>4 & 0xf; + + int alpha = 255; + int pri = 0; + int zcode = -1; // negative zcode values turn off z-buffering + + if (drawmode & 2) + { + alpha = color>>K055555_MIXSHIFT & 3; + if (alpha) alpha = m_k054338->set_alpha_level(alpha); + if (alpha <= 0) continue; + } + color &= K055555_COLORMASK; + + if (drawmode >= 4) m_palette->set_shadow_mode(order & 0x0f); + + if (!(mixerflags & GXMIX_NOZBUF)) + { + zcode = order>>16 & 0xff; + pri = order>>24 & 0xff; + } + + m_k055673->k053247_draw_single_sprite_gxcore(bitmap, cliprect, + m_gx_objzbuf, m_gx_shdzbuf.get(), code, m_gx_spriteram, offs, + color, alpha, drawmode, zcode, pri, + /* non-gx only */ + 0,0,nullptr,nullptr,0 + ); + } + /* the rest are tilemaps of various kinda */ else { - temp1 = m_vinmix; - temp2 = m_vinmix>>i & 3; - temp3 = m_vmixon>>i & 3; + switch (offs) + { + case -1: + gx_draw_basic_tilemaps(screen, bitmap, cliprect, mixerflags, code); + continue; + case -2: + case -4: + gx_draw_basic_extended_tilemaps_1(screen, bitmap, cliprect, mixerflags, code, sub1, sub1flags, rushingheroes_hack, offs); + continue; + case -3: + case -5: + gx_draw_basic_extended_tilemaps_2(screen, bitmap, cliprect, mixerflags, code, sub2, sub2flags, extra_bitmap, offs); + continue; + } + continue; } + } +} - /* blend layer only when: - 1) m_vinmix != 0xff - 2) its internal mix code is set - 3) all mix code bits are internal(overridden until tile blending has been implemented) - 4) 0 > alpha < 255; - */ - if (temp1!=0xff && temp2 /*&& temp3==3*/) +void konamigx_state::gx_draw_basic_tilemaps(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mixerflags, uint8_t layer) +{ + const uint8_t disp = m_k055555->K055555_read_register(K55_INPUT_ENABLES); + + if (disp & (1 << layer)) + { + set_brightness(layer); + + const uint8_t layer2 = layer << 1; + const uint8_t j = mixerflags >> layer2 & 0b11; + + // keep internal and external mix codes separated, so the external mix code can be applied to category 1 tiles + uint8_t mix_mode_internal = 0; + uint8_t mix_mode_external = 0; + + if (j == GXMIX_BLEND_FORCE) mix_mode_internal = mixerflags >> (layer2 + 16) & 0b11; // hack + else { - temp4 = m_k054338->set_alpha_level(temp2); + const uint8_t v_inmix_on_layer = m_vmixon >> layer2 & 0b11; + const uint8_t v_inmix_layer = m_vinmix >> layer2 & 0b11; + const uint8_t tile_mix_code = uint32_t(mixerflags) >> 30; - if (temp4 <= 0) return; - if (temp4 < 255) k = TILEMAP_DRAW_ALPHA(temp4); + mix_mode_internal = v_inmix_layer & v_inmix_on_layer; + mix_mode_external = tile_mix_code & ~v_inmix_on_layer; } - if (mixerflags & 1<<(code+12)) k |= K056382_DRAW_FLAG_FORCE_XYSCROLL; + int flags = TILEMAP_DRAW_CATEGORY(0); + int flags2 = TILEMAP_DRAW_CATEGORY(1); - m_k056832->m_tilemap_draw(screen, bitmap, cliprect, code, k, 0); + if (mixerflags & 1 << (layer + 12)) + { + flags |= K056382_DRAW_FLAG_FORCE_XYSCROLL; + flags2 |= K056382_DRAW_FLAG_FORCE_XYSCROLL; + } + + // hack: mask out mixpri bit. if additive bit set, mask it out and invert alpha. + // this makes additive alpha effects look OK until they are properly handled. + int alpha = m_k054338->set_alpha_level(mix_mode_internal) & 0x1ff; + if (alpha & 0x100) + { + alpha &= 0xff; + if (alpha) alpha = ~alpha & 0xff; + } + + int alpha2 = m_k054338->set_alpha_level(mix_mode_external) & 0x1ff; + if (alpha2 & 0x100) alpha2 = ~alpha2 & 0xff; + + if (alpha < 255) flags |= TILEMAP_DRAW_ALPHA(alpha); + + if (alpha2 < 255) + { + // tiles with mix codes are put into category 1. + // draw them in a separate pass for per-tile blending if necessary. + flags2 |= TILEMAP_DRAW_ALPHA(alpha2); + m_k056832->m_tilemap_draw(screen, bitmap, cliprect, layer, flags2, 0); + } + else + { + // if no alpha is being applied to category 1 (tile mix code) tiles, + // draw all tiles with one m_tilemap_draw call + flags |= TILEMAP_DRAW_ALL_CATEGORIES; + } + m_k056832->m_tilemap_draw(screen, bitmap, cliprect, layer, flags, 0); } } @@ -738,7 +787,7 @@ void konamigx_state::gx_draw_basic_extended_tilemaps_1(screen_device &screen, bi if (temp1!=0xff && temp2 /*&& temp3==3*/) { - alpha = temp4 = m_k054338->set_alpha_level(temp2); + alpha = temp4 = m_k054338->set_alpha_level(temp2) & 0xff; if (temp4 <= 0) return; if (temp4 < 255) k = 1; @@ -786,7 +835,7 @@ void konamigx_state::gx_draw_basic_extended_tilemaps_2(screen_device &screen, bi if (temp1!=0xff && temp2 /*&& temp3==3*/) { //alpha = - temp4 = m_k054338->set_alpha_level(temp2); + temp4 = m_k054338->set_alpha_level(temp2) & 0xff; if (temp4 <= 0) return; //if (temp4 < 255) k = 1; @@ -831,91 +880,6 @@ void konamigx_state::gx_draw_basic_extended_tilemaps_2(screen_device &screen, bi } } -void konamigx_state::konamigx_mixer_draw(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, - tilemap_t *sub1, int sub1flags, - tilemap_t *sub2, int sub2flags, - int mixerflags, bitmap_ind16 *extra_bitmap, int rushingheroes_hack, - - /* passed from above function */ - GX_OBJ *objpool, - int *objbuf, - int nobj - ) -{ - // traverse draw list - int disp = m_k055555->K055555_read_register(K55_INPUT_ENABLES); - - for (int count=0; countorder; - int offs = objptr->offs; - int code = objptr->code; - int color = objptr->color; - - /* entries >=0 in our list are sprites */ - if (offs >= 0) - { - if (!(disp & K55_INP_OBJ)) continue; - - int drawmode = order>>4 & 0xf; - - int alpha = 255; - int pri = 0; - int zcode = -1; // negative zcode values turn off z-buffering - - if (drawmode & 2) - { - alpha = color>>K055555_MIXSHIFT & 3; - if (alpha) alpha = m_k054338->set_alpha_level(alpha); - if (alpha <= 0) continue; - } - color &= K055555_COLORMASK; - - if (drawmode >= 4) m_palette->set_shadow_mode(order & 0x0f); - - if (!(mixerflags & GXMIX_NOZBUF)) - { - zcode = order>>16 & 0xff; - pri = order>>24 & 0xff; - } - - - - - m_k055673->k053247_draw_single_sprite_gxcore(bitmap, cliprect, - m_gx_objzbuf, m_gx_shdzbuf.get(), code, m_gx_spriteram, offs, - color, alpha, drawmode, zcode, pri, - /* non-gx only */ - 0,0,nullptr,nullptr,0 - ); - } - /* the rest are tilemaps of various kinda */ - else - { - switch (offs) - { - case -1: - gx_draw_basic_tilemaps(screen, bitmap, cliprect, mixerflags, code); - continue; - case -2: - case -4: - gx_draw_basic_extended_tilemaps_1(screen, bitmap, cliprect, mixerflags, code, sub1, sub1flags, rushingheroes_hack, offs); - continue; - case -3: - case -5: - gx_draw_basic_extended_tilemaps_2(screen, bitmap, cliprect, mixerflags, code, sub2, sub2flags, extra_bitmap, offs); - continue; - } - continue; - } - - - - } -} - - /* Run and Gun 2 / Rushing Heroes */ TILE_GET_INFO_MEMBER(konamigx_state::get_gx_psac_tile_info) { @@ -1083,25 +1047,31 @@ K056832_CB_MEMBER(konamigx_state::type2_tile_callback) K055555GX_decode_vmixcolor(layer, color); } -K056832_CB_MEMBER(konamigx_state::alpha_tile_callback) +K056832_CB_MEMBER(konamigx_state::salmndr2_tile_callback) { - int mixcode; + const uint8_t mix_code = attr >> 4 & 0b11; + if (mix_code) { + *priority = 1; + m_last_alpha_tile_mix_code = mix_code; + } + int d = *code; - mixcode = K055555GX_decode_vmixcolor(layer, color); + *code = (m_gx_tilebanks[(d & 0xe000)>>13]<<13) + (d & 0x1fff); + K055555GX_decode_vmixcolor(layer, color); +} - if (mixcode < 0) - *code = (m_gx_tilebanks[(d & 0xe000)>>13]<<13) + (d & 0x1fff); - else - { - /* save mixcode and mark tile alpha (unimplemented) */ - // Daisu-Kiss stage presentation - // Sexy Parodius level 3b - *code = (m_gx_tilebanks[(d & 0xe000)>>13]<<13) + (d & 0x1fff); - - if (VERBOSE) - popmessage("skipped alpha tile(layer=%d mix=%d)", layer, mixcode); +K056832_CB_MEMBER(konamigx_state::alpha_tile_callback) +{ + const uint8_t mix_code = attr >> 6 & 0b11; + if (mix_code) { + *priority = 1; + m_last_alpha_tile_mix_code = mix_code; } + int d = *code; + + *code = (m_gx_tilebanks[(d & 0xe000)>>13]<<13) + (d & 0x1fff); + K055555GX_decode_vmixcolor(layer, color); } /* @@ -1489,7 +1459,8 @@ uint32_t konamigx_state::screen_update_konamigx(screen_device &screen, bitmap_rg } else { - konamigx_mixer(screen, bitmap, cliprect, nullptr, 0, nullptr, 0, 0, nullptr, m_gx_rushingheroes_hack); + int mixerflags = m_last_alpha_tile_mix_code << 30; + konamigx_mixer(screen, bitmap, cliprect, nullptr, 0, nullptr, 0, mixerflags, nullptr, m_gx_rushingheroes_hack); } // HACK: draw type-1 roz layer here for testing purposes only diff --git a/src/mame/konami/moo.cpp b/src/mame/konami/moo.cpp index 2add19cf604..5c3a0b45fb5 100644 --- a/src/mame/konami/moo.cpp +++ b/src/mame/konami/moo.cpp @@ -333,7 +333,7 @@ uint32_t moo_state::screen_update_moo(screen_device &screen, bitmap_rgb32 &bitma // There is probably a control bit somewhere to turn off alpha blending. m_alpha_enabled = m_k054338->register_r(K338_REG_CONTROL) & K338_CTL_MIXPRI; // DUMMY - alpha = (m_alpha_enabled) ? m_k054338->set_alpha_level(1) : 255; + alpha = (m_alpha_enabled) ? m_k054338->set_alpha_level(1) & 0xff : 255; if (alpha > 0) m_k056832->tilemap_draw(screen, bitmap, cliprect, layers[2], TILEMAP_DRAW_ALPHA(alpha), 4); diff --git a/src/mame/konami/mystwarr.cpp b/src/mame/konami/mystwarr.cpp index 2445cbca91f..529829d89f9 100644 --- a/src/mame/konami/mystwarr.cpp +++ b/src/mame/konami/mystwarr.cpp @@ -1034,7 +1034,7 @@ void mystwarr_state::viostorm(machine_config &config) m_screen->set_size(64*8, 32*8); m_screen->set_visarea(40, 40+384-1, 16, 16+224-1); - m_k056832->set_tile_callback(FUNC(mystwarr_state::game4bpp_tile_callback)); + m_k056832->set_tile_callback(FUNC(mystwarr_state::viostorm_tile_callback)); m_k055673->set_sprite_callback(FUNC(mystwarr_state::metamrph_sprite_callback)); m_k055673->set_config(K055673_LAYOUT_RNG, -62, -23); @@ -1082,7 +1082,7 @@ void mystwarr_state::metamrph(machine_config &config) m_screen->set_size(64*8, 32*8); m_screen->set_visarea(24, 24+288-1, 15, 15+224-1); - m_k056832->set_tile_callback(FUNC(mystwarr_state::game4bpp_tile_callback)); + m_k056832->set_tile_callback(FUNC(mystwarr_state::viostorm_tile_callback)); m_k055673->set_sprite_callback(FUNC(mystwarr_state::metamrph_sprite_callback)); m_k055673->set_config(K055673_LAYOUT_RNG, -51, -24); diff --git a/src/mame/konami/mystwarr.h b/src/mame/konami/mystwarr.h index 36973c63832..364e805d79d 100644 --- a/src/mame/konami/mystwarr.h +++ b/src/mame/konami/mystwarr.h @@ -55,6 +55,8 @@ private: uint8_t m_sound_ctrl = 0; uint8_t m_sound_nmi_clk = 0; + uint8_t m_last_alpha_tile_mix_code = 0; + uint16_t eeprom_r(offs_t offset, uint16_t mem_mask = ~0); void mweeprom_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); uint16_t dddeeprom_r(offs_t offset, uint16_t mem_mask = ~0); @@ -103,6 +105,7 @@ private: TIMER_DEVICE_CALLBACK_MEMBER(metamrph_interrupt); TIMER_DEVICE_CALLBACK_MEMBER(mchamp_interrupt); K056832_CB_MEMBER(mystwarr_tile_callback); + K056832_CB_MEMBER(viostorm_tile_callback); K056832_CB_MEMBER(game5bpp_tile_callback); K056832_CB_MEMBER(game4bpp_tile_callback); K055673_CB_MEMBER(mystwarr_sprite_callback); diff --git a/src/mame/konami/mystwarr_v.cpp b/src/mame/konami/mystwarr_v.cpp index 9fc8b894f93..a4a2bb9d3df 100644 --- a/src/mame/konami/mystwarr_v.cpp +++ b/src/mame/konami/mystwarr_v.cpp @@ -59,16 +59,27 @@ void mystwarr_state::decode_tiles() // Mystic Warriors requires tile based blending. K056832_CB_MEMBER(mystwarr_state::mystwarr_tile_callback) { - if (layer == 1) + const uint8_t mix_code = attr >> 2 & 0b11; + if (mix_code) { - //* water hack (TEMPORARY) - if ((*code & 0xff00) + (*color) == 0x4101) - m_cbparam++; - else - m_cbparam--; + *priority = 1; + m_last_alpha_tile_mix_code = mix_code; } - *color = m_layer_colorbase[layer] | (*color >> 1 & 0x1e); + *color = m_layer_colorbase[layer] | (*color >> 1 & 0x0f); +} + +K056832_CB_MEMBER(mystwarr_state::viostorm_tile_callback) +{ + // metamrph either uses bits 0-1 or 4-5, not sure which + const uint8_t mix_code = attr & 0b11; + if (mix_code) + { + *priority = 1; + m_last_alpha_tile_mix_code = mix_code; + } + + *color = m_layer_colorbase[layer] | (*color >> 2 & 0x0f); } // for games with 5bpp tile data @@ -209,8 +220,6 @@ VIDEO_START_MEMBER(mystwarr_state, mystwarr) m_k056832->set_layer_offs(1, 0-3, 0); m_k056832->set_layer_offs(2, 2-3, 0); m_k056832->set_layer_offs(3, 3-3, 0); - - m_cbparam = 0; } VIDEO_START_MEMBER(mystwarr_state, metamrph) @@ -262,14 +271,6 @@ VIDEO_START_MEMBER(mystwarr_state, martchmp) uint32_t mystwarr_state::screen_update_mystwarr(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - int blendmode = 0; - - //* water hack (TEMPORARY) - if (m_cbparam < 0) - m_cbparam = 0; - else if (m_cbparam >= 32) - blendmode = (1 << 16 | GXMIX_BLEND_FORCE) << 2; - for (int i = 0; i < 4; i++) { int old = m_layer_colorbase[i]; @@ -279,7 +280,8 @@ uint32_t mystwarr_state::screen_update_mystwarr(screen_device &screen, bitmap_rg m_sprite_colorbase = m_k055555->K055555_get_palette_index(4) << 5; - konamigx_mixer(screen, bitmap, cliprect, nullptr, 0, nullptr, 0, blendmode, nullptr, 0); + int mixerflags = m_last_alpha_tile_mix_code << 30; + konamigx_mixer(screen, bitmap, cliprect, nullptr, 0, nullptr, 0, mixerflags, nullptr, 0); return 0; } @@ -294,7 +296,8 @@ uint32_t mystwarr_state::screen_update_metamrph(screen_device &screen, bitmap_rg m_sprite_colorbase = m_k055555->K055555_get_palette_index(4) << 4; - konamigx_mixer(screen, bitmap, cliprect, nullptr, GXSUB_K053250 | GXSUB_4BPP, nullptr, 0, 0, nullptr, 0); + int mixerflags = m_last_alpha_tile_mix_code << 30; + konamigx_mixer(screen, bitmap, cliprect, nullptr, GXSUB_K053250 | GXSUB_4BPP, nullptr, 0, mixerflags, nullptr, 0); return 0; } diff --git a/src/mame/konami/xexex.cpp b/src/mame/konami/xexex.cpp index 12e6960e163..af99cbd1421 100644 --- a/src/mame/konami/xexex.cpp +++ b/src/mame/konami/xexex.cpp @@ -364,7 +364,7 @@ uint32_t xexex_state::screen_update_xexex(screen_device &screen, bitmap_rgb32 &b if (m_cur_alpha) { - alpha = m_k054338->set_alpha_level(1); + alpha = m_k054338->set_alpha_level(1) & 0xff; if (alpha > 0) {