flkatck.cpp: fix sprite-sprite priorities and removed hackish implementation in k007121 [Angelo Salese, Dink] (#4024)

* flkatck.cpp: apply old patch from Dink wrt sprite-sprite priorities (nw)
Making it a branch cause it's a lot nastier than that, hopefully going to fix this mess in the next days ...

* flkatck.cpp: fix sprite-sprite priorities and removed hackish implementation in k007121 [Angelo Salese, Dink]

* It's double buffered (nw)
This commit is contained in:
Angelo Salese 2018-09-25 12:45:35 +02:00 committed by Olivier Galibert
parent f675b78ae4
commit 64e3902d09
4 changed files with 92 additions and 128 deletions

View File

@ -98,8 +98,9 @@ void flkatck_state::flkatck_map(address_map &map)
map(0x0008, 0x03ff).ram(); /* RAM */
map(0x0400, 0x041f).rw(FUNC(flkatck_state::flkatck_ls138_r), FUNC(flkatck_state::flkatck_ls138_w)); /* inputs, DIPS, bankswitch, counters, sound command */
map(0x0800, 0x0bff).ram().w("palette", FUNC(palette_device::write8)).share("palette"); /* palette */
map(0x1000, 0x1fff).ram(); /* RAM */
map(0x2000, 0x3fff).ram().w(FUNC(flkatck_state::flkatck_k007121_w)).share("k007121_ram"); /* Video RAM (007121) */
map(0x1000, 0x1fff).ram().share("spriteram"); /* RAM */
map(0x2000, 0x2fff).ram().w(FUNC(flkatck_state::vram_w)).share("vram"); /* Video RAM (007121) */
map(0x3000, 0x3fff).ram();
map(0x4000, 0x5fff).bankr("bank1"); /* banked ROM */
map(0x6000, 0xffff).rom(); /* ROM */
}

View File

@ -16,7 +16,8 @@ class flkatck_state : public driver_device
public:
flkatck_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_k007121_ram(*this, "k007121_ram"),
m_vram(*this, "vram"),
m_spriteram(*this, "spriteram"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
m_k007121(*this, "k007121"),
@ -29,7 +30,8 @@ public:
private:
/* memory pointers */
required_shared_ptr<uint8_t> m_k007121_ram;
required_shared_ptr<uint8_t> m_vram;
required_shared_ptr<uint8_t> m_spriteram;
/* video-related */
tilemap_t *m_k007121_tilemap[2];
@ -53,7 +55,7 @@ private:
DECLARE_WRITE8_MEMBER(flkatck_ls138_w);
DECLARE_READ8_MEMBER(multiply_r);
DECLARE_WRITE8_MEMBER(multiply_w);
DECLARE_WRITE8_MEMBER(flkatck_k007121_w);
DECLARE_WRITE8_MEMBER(vram_w);
DECLARE_WRITE8_MEMBER(flkatck_k007121_regs_w);
TILE_GET_INFO_MEMBER(get_tile_info_A);
TILE_GET_INFO_MEMBER(get_tile_info_B);

View File

@ -23,8 +23,8 @@ TILE_GET_INFO_MEMBER(flkatck_state::get_tile_info_A)
uint8_t ctrl_3 = m_k007121->ctrlram_r(3);
uint8_t ctrl_4 = m_k007121->ctrlram_r(4);
uint8_t ctrl_5 = m_k007121->ctrlram_r(5);
int attr = m_k007121_ram[tile_index];
int code = m_k007121_ram[tile_index + 0x400];
int attr = m_vram[tile_index];
int code = m_vram[tile_index + 0x400];
int bit0 = (ctrl_5 >> 0) & 0x03;
int bit1 = (ctrl_5 >> 2) & 0x03;
int bit2 = (ctrl_5 >> 4) & 0x03;
@ -51,8 +51,8 @@ TILE_GET_INFO_MEMBER(flkatck_state::get_tile_info_A)
TILE_GET_INFO_MEMBER(flkatck_state::get_tile_info_B)
{
int attr = m_k007121_ram[tile_index + 0x800];
int code = m_k007121_ram[tile_index + 0xc00];
int attr = m_vram[tile_index + 0x800];
int code = m_vram[tile_index + 0xc00];
SET_TILE_INFO_MEMBER(0,
code,
@ -80,16 +80,13 @@ void flkatck_state::video_start()
***************************************************************************/
WRITE8_MEMBER(flkatck_state::flkatck_k007121_w)
WRITE8_MEMBER(flkatck_state::vram_w)
{
m_k007121_ram[offset] = data;
if (offset < 0x1000) /* tiles */
{
if (offset & 0x800) /* score */
m_k007121_tilemap[1]->mark_tile_dirty(offset & 0x3ff);
else
m_k007121_tilemap[0]->mark_tile_dirty(offset & 0x3ff);
}
m_vram[offset] = data;
if (offset & 0x800) /* score */
m_k007121_tilemap[1]->mark_tile_dirty(offset & 0x3ff);
else
m_k007121_tilemap[0]->mark_tile_dirty(offset & 0x3ff);
}
WRITE8_MEMBER(flkatck_state::flkatck_k007121_regs_w)
@ -118,18 +115,12 @@ WRITE8_MEMBER(flkatck_state::flkatck_k007121_regs_w)
***************************************************************************/
/***************************************************************************
Flack Attack sprites. Each sprite has 16 bytes!:
***************************************************************************/
uint32_t flkatck_state::screen_update_flkatck(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
rectangle clip[2];
const rectangle &visarea = screen.visible_area();
uint16_t sprite_buffer = (m_k007121->ctrlram_r(3) & 8) * 0x100;
if (m_flipscreen)
{
clip[0] = visarea;
@ -162,7 +153,7 @@ uint32_t flkatck_state::screen_update_flkatck(screen_device &screen, bitmap_ind1
/* draw the graphics */
m_k007121_tilemap[0]->draw(screen, bitmap, clip[0], 0, 0);
m_k007121->sprites_draw(bitmap, cliprect, m_gfxdecode->gfx(0), m_gfxdecode->palette(), &m_k007121_ram[0x1000], 0, 40, 0, screen.priority(), (uint32_t)-1, true);
m_k007121->sprites_draw(bitmap, cliprect, m_gfxdecode->gfx(0), m_gfxdecode->palette(), &m_spriteram[sprite_buffer], 0, 40, 0, screen.priority(), (uint32_t)-1, true);
m_k007121_tilemap[1]->draw(screen, bitmap, clip[1], 0, 0);
return 0;
}

View File

@ -46,6 +46,7 @@ control registers
000: scroll x (low 8 bits)
001: -------x scroll x (high bit)
------x- enable rowscroll? (combatsc)
-----x-- unknown (flak attack)
----x--- this probably selects an alternate screen layout used in combat
school where tilemap #2 is overlayed on front and doesn't scroll.
The 32 lines of the front layer can be individually turned on or
@ -206,17 +207,6 @@ WRITE8_MEMBER( k007121_device::ctrl_w )
* 4 | ----xxx- | sprite size 000=16x16 001=16x8 010=8x16 011=8x8 100=32x32
* 4 | -------x | x position (high bit)
*
* Flack Attack uses a different, "wider" layout with 32 bytes per sprite,
* mapped as follows, and the priority order is reversed. Maybe it is a
* compatibility mode with an older custom IC. It is not known how this
* alternate layout is selected.
*
* 0 -> e
* 1 -> f
* 2 -> 6
* 3 -> 4
* 4 -> 8
*
*/
void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, device_palette_interface &palette,
@ -224,55 +214,37 @@ void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &clipre
{
// gfx_element *gfx = gfxs[chip];
int flipscreen = m_flipscreen;
int i, num, inc, offs[5];
int i, num, inc;
if (is_flakatck)
{
num = 0x40;
inc = -0x20;
source += 0x3f * 0x20;
offs[0] = 0x0e;
offs[1] = 0x0f;
offs[2] = 0x06;
offs[3] = 0x04;
offs[4] = 0x08;
}
else /* all others */
{
/* TODO: sprite limit is supposed to be per-line! (check MT #00185) */
num = 0x40;
//num = (k007121->ctrlram[0x03] & 0x40) ? 0x80 : 0x40; /* WRONG!!! (needed by combatsc) */
inc = 5;
offs[0] = 0x00;
offs[1] = 0x01;
offs[2] = 0x02;
offs[3] = 0x03;
offs[4] = 0x04;
/* when using priority buffer, draw front to back */
if (pri_mask != -1)
{
source += (num - 1)*inc;
inc = -inc;
}
/* TODO: sprite limit is supposed to be per-line! (check MT #00185) */
num = 0x40;
//num = (k007121->ctrlram[0x03] & 0x40) ? 0x80 : 0x40; /* WRONG!!! (needed by combatsc) */
inc = 5;
/* when using priority buffer, draw front to back */
if (pri_mask != -1)
{
source += (num - 1)*inc;
inc = -inc;
}
for (i = 0; i < num; i++)
{
int number = source[offs[0]]; /* sprite number */
int sprite_bank = source[offs[1]] & 0x0f; /* sprite bank */
int sx = source[offs[3]]; /* vertical position */
int sy = source[offs[2]]; /* horizontal position */
int attr = source[offs[4]]; /* attributes */
int xflip = source[offs[4]] & 0x10; /* flip x */
int yflip = source[offs[4]] & 0x20; /* flip y */
int color = base_color + ((source[offs[1]] & 0xf0) >> 4);
int number = source[0]; /* sprite number */
int sprite_bank = source[1] & 0x0f; /* sprite bank */
int sx = source[3]; /* vertical position */
int sy = source[2]; /* horizontal position */
int attr = source[4]; /* attributes */
int xflip = source[4] & 0x10; /* flip x */
int yflip = source[4] & 0x20; /* flip y */
int color = base_color + ((source[1] & 0xf0) >> 4);
int width, height;
int transparent_mask;
static const int x_offset[4] = {0x0,0x1,0x4,0x5};
static const int y_offset[4] = {0x0,0x2,0x8,0xa};
int x,y, ex, ey, flipx, flipy, destx, desty;
if (attr & 0x01) sx -= 256;
if (sy >= 240) sy -= 256;
@ -282,68 +254,66 @@ void k007121_device::sprites_draw( bitmap_ind16 &bitmap, const rectangle &clipre
/* Flak Attack doesn't use a lookup PROM, it maps the color code directly */
/* to a palette entry */
// TODO: is
if (is_flakatck)
transparent_mask = 1 << 0;
else
transparent_mask = palette.transpen_mask(*gfx, color, 0);
if (!is_flakatck || source[0x00]) /* Flak Attack needs this */
{
number += bank_base;
number += bank_base;
switch (attr & 0xe)
{
case 0x06: width = height = 1; break;
case 0x04: width = 1; height = 2; number &= (~2); break;
case 0x02: width = 2; height = 1; number &= (~1); break;
case 0x00: width = height = 2; number &= (~3); break;
case 0x08: width = height = 4; number &= (~3); break;
default: width = 1; height = 1;
switch (attr & 0xe)
{
case 0x06: width = height = 1; break;
case 0x04: width = 1; height = 2; number &= (~2); break;
case 0x02: width = 2; height = 1; number &= (~1); break;
case 0x00: width = height = 2; number &= (~3); break;
case 0x08: width = height = 4; number &= (~3); break;
default: width = 1; height = 1;
// logerror("Unknown sprite size %02x\n", attr & 0xe);
// popmessage("Unknown sprite size %02x\n", attr & 0xe);
}
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
ex = xflip ? (width - 1 - x) : x;
ey = yflip ? (height - 1 - y) : y;
if (flipscreen)
{
flipx = !xflip;
flipy = !yflip;
destx = 248 - (sx + x * 8);
desty = 248 - (sy + y * 8);
}
else
{
flipx = xflip;
flipy = yflip;
destx = global_x_offset + sx + x * 8;
desty = sy + y * 8;
}
if (pri_mask != -1)
gfx->prio_transmask(bitmap,cliprect,
number + x_offset[ex] + y_offset[ey],
color,
flipx,flipy,
destx,desty,
priority_bitmap,pri_mask,
transparent_mask);
else
gfx->transmask(bitmap,cliprect,
number + x_offset[ex] + y_offset[ey],
color,
flipx,flipy,
destx,desty,
transparent_mask);
}
}
}
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
ex = xflip ? (width - 1 - x) : x;
ey = yflip ? (height - 1 - y) : y;
if (flipscreen)
{
flipx = !xflip;
flipy = !yflip;
destx = 248 - (sx + x * 8);
desty = 248 - (sy + y * 8);
}
else
{
flipx = xflip;
flipy = yflip;
destx = global_x_offset + sx + x * 8;
desty = sy + y * 8;
}
if (pri_mask != -1)
gfx->prio_transmask(bitmap,cliprect,
number + x_offset[ex] + y_offset[ey],
color,
flipx,flipy,
destx,desty,
priority_bitmap,pri_mask,
transparent_mask);
else
gfx->transmask(bitmap,cliprect,
number + x_offset[ex] + y_offset[ey],
color,
flipx,flipy,
destx,desty,
transparent_mask);
}
}
source += inc;
}
}