mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
Konami (GX) blending - additive sprite blending, improved tile blending (#13473)
k053246_k053247_k055673.cpp, k053246_k053247_k055673.h: I went back to update zdrawgfxzoom32GP(), now down to a third of its original size before I started changing it. As a thinly veiled excuse for reworking the whole function, I went ahead and added additive sprite blending (to the now singular alpha call site). Remarks: the mix priority setting is not yet handled. It seems simple enough (flip dst and src), but I would like to find an example of this before I implement it. k054156_k054157_k056832.cpp: The attr variable holds what appear to be the elusive tile (external) mix codes. Attach it to the flags variable so these bits can be accessed in the tile callback functions. Tiles with mix codes gets their own tilemap category. Remarks: I've now changed the callback to include an attr param. k054338.cpp: Update set_alpha_level. This function now returns a level, an additive blend bool and a mixpri bool. Minor style changes to the overall file. Remarks: set_alpha_level doesn't actually set anything. Maybe rename to get_alpha_level? moo.cpp, xexex.cpp: Mask out the new additive & mixpri bits from set_alpha_level calls for now, until it's known if / how they should be used over there. mystwarr_v.cpp, mystwarr.h: Remove mystwarr water hack. Update mystwarr_tile_callback (and add viostorm_tile_callback) to read tile mix codes, store last read mix code in a new m_last_alpha_tile_mix_code variable. Attach m_last_alpha_tile_mix_code to mixerflags, which happens to have two unused bits. Remarks: I updated the mixerflags documentation to mention the usage of the last two bits. konamigx_v.cpp, konamigx.cpp, konamigx.h: Shrink GX_MAX_SPRITES, which to the best of my ability seems to be oversized. There does seem to be several oversized arrays / defs in these files, so I think this is one of them. The usual FredYeye updates to konamigx_mixer - move declarations closer to use, more suited types, rename temp vars, etc. Change objpool to a vector, simplifying usage (push_back, size). Replace sorting loop with reverse + stable_sort. Improve gx_draw_basic_tilemaps - read internal / external alpha mix codes based on vinmix_on. Tiles with mixcodes get drawn in a separate pass for per-tile blending. Update alpha_tile_callback and add salmndr2_tile_callback, same as the mystwarr_v callbacks. What started out as trying to sort out konamigx_mixer() to look at shadow/priority issues instead ended up with me finally getting a foot into the figurative tile blending door. The mystwarr water hack is gone, and sexyparo gets transparent windows. This might affect many GX and related games. Alpha blending might be broken in some games now, and needs to get their mix codes attached in their respective callbacks. salmndr2 got tagged in my automatic video comparison for differing from earlier versions, that's why I managed to fix it already. Known problems: metamrph: stained glass windows are near-transparent at the moment. I think additive tile blending will fix it... viostorm: character names fade in in reverse. This also uses additive blending, so this might also get fixed once that's in. fantjour: the top & bottom flames at the captain kebab ship go missing. Uses additive blending.
This commit is contained in:
parent
cfa56c0d33
commit
7feaa6968d
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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<void (int layer, int *code, int *color, int *flags, int *priority)>;
|
||||
using tile_delegate = device_delegate<void (int layer, int *code, int *color, int *flags, int *priority, u16 attr)>;
|
||||
|
||||
template <typename T> k056832_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&mixer_tag)
|
||||
: k056832_device(mconfig, tag, owner, clock)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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<GX_OBJ> &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<bitmap_ind16> m_gxtype1_roz_dstbitmap2;
|
||||
rectangle m_gxtype1_roz_dstbitmapclip;
|
||||
|
||||
std::unique_ptr<GX_OBJ[]> 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
|
||||
|
@ -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<uint8_t[]>(GX_ZBUFSIZE);
|
||||
m_gx_objpool = std::make_unique<GX_OBJ[]>(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<GX_OBJ> 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; offs<end_addr; offs+=8)
|
||||
for (int x = 0; x < 256; ++x)
|
||||
{
|
||||
const uint16_t offs = start_addr + x * 8;
|
||||
int pri = 0;
|
||||
|
||||
if (!(m_gx_spriteram[offs] & 0x8000)) continue;
|
||||
|
||||
int zcode = m_gx_spriteram[offs] & 0xff;
|
||||
uint8_t zcode = m_gx_spriteram[offs] & 0xff;
|
||||
|
||||
// invert z-order when opset_pri is set (see p.51 OPSET PRI)
|
||||
if (m_k053247_opset & 0x10) zcode = 0xff - zcode;
|
||||
|
||||
int code = m_gx_spriteram[offs+1];
|
||||
int color = k = m_gx_spriteram[offs+6];
|
||||
l = m_gx_spriteram[offs+7];
|
||||
// int l = m_gx_spriteram[offs+7];
|
||||
|
||||
m_k055673->m_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<l; j++)
|
||||
{
|
||||
int temp1 = objbuf[j];
|
||||
int temp2 = objpool[temp1].order;
|
||||
for (int i=j+1; i<k; i++)
|
||||
{
|
||||
int temp3 = objbuf[i];
|
||||
int temp4 = objpool[temp3].order;
|
||||
if ((uint32_t)temp2 <= (uint32_t)temp4) { temp2 = temp4; objbuf[i] = temp1; objbuf[j] = temp1 = temp3; }
|
||||
uint32_t order = spri<<24 | zcode<<16 | offs<<(8-3) | shadow_draw_mode<<4 | shadow;
|
||||
objpool.push_back(GX_OBJ{ order, offs, code, color});
|
||||
}
|
||||
}
|
||||
|
||||
// sort objects in descending order (SLOW)
|
||||
// reverse objpool to retain order in case of ties
|
||||
std::reverse(objpool.begin(), objpool.end());
|
||||
std::stable_sort(objpool.begin(), objpool.end(), [](const GX_OBJ &a, const GX_OBJ &b){
|
||||
return a.order > 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<GX_OBJ> &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<<code))
|
||||
for (int count=0; count<objpool.size(); count++)
|
||||
{
|
||||
set_brightness(code);
|
||||
const uint32_t order = objpool[count].order;
|
||||
const int offs = objpool[count].offs;
|
||||
const int code = objpool[count].code;
|
||||
int color = objpool[count].color;
|
||||
|
||||
if (j == GXMIX_BLEND_NONE) { temp1 = 0xff; temp2 = temp3 = 0; } else
|
||||
if (j == GXMIX_BLEND_FORCE) { temp1 = 0x00; temp2 = mixerflags>>(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; count<nobj; count++)
|
||||
{
|
||||
GX_OBJ *objptr = objpool + objbuf[count];
|
||||
int order = objptr->order;
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user