mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +03:00
sinclair/tsconf.cpp: fix layers priority, screen updates (#12647)
This commit is contained in:
parent
0aad7c75a7
commit
a1bc579274
@ -229,6 +229,7 @@ void tsconf_state::machine_reset()
|
||||
m_zctl_di = 0xff;
|
||||
m_ay_selected = 0;
|
||||
|
||||
m_sprites_cache.clear();
|
||||
tsconf_update_bank0();
|
||||
tsconf_update_video_mode();
|
||||
|
||||
|
@ -136,6 +136,17 @@ private:
|
||||
T1_Y_OFFSET_H = 0x47
|
||||
};
|
||||
|
||||
struct sprite_data
|
||||
{
|
||||
u32 code;
|
||||
u32 color;
|
||||
int flipx;
|
||||
int flipy;
|
||||
s32 destx;
|
||||
s32 desty;
|
||||
u32 pmask;
|
||||
};
|
||||
|
||||
void update_frame_timer();
|
||||
emu_timer *m_frame_irq_timer = nullptr;
|
||||
emu_timer *m_scanline_irq_timer = nullptr;
|
||||
@ -222,6 +233,7 @@ private:
|
||||
required_device<ram_device> m_cram;
|
||||
required_device<ram_device> m_sfile;
|
||||
required_device<centronics_device> m_centronics;
|
||||
std::vector<sprite_data> m_sprites_cache;
|
||||
|
||||
required_device_array<ym2149_device, 2> m_ay;
|
||||
u8 m_ay_selected;
|
||||
|
@ -154,11 +154,18 @@ void tsconf_state::tsconf_update_screen(screen_device &screen, bitmap_rgb32 &bit
|
||||
if (!BIT(m_regs[V_CONFIG], 5))
|
||||
{
|
||||
if (VM == VM_ZX)
|
||||
{
|
||||
tsconf_draw_zx(screen, bitmap, cliprect);
|
||||
}
|
||||
else if (VM == VM_TXT)
|
||||
{
|
||||
tsconf_draw_txt(bitmap, cliprect);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap.fill(m_palette->pen_color(get_border_color()), cliprect);
|
||||
tsconf_draw_gfx(bitmap, cliprect);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -172,22 +179,19 @@ void tsconf_state::tsconf_update_screen(screen_device &screen, bitmap_rgb32 &bit
|
||||
{
|
||||
m_ts_tilemap[TM_TILES0]->draw(
|
||||
screen, bitmap, cliprect,
|
||||
BIT(m_regs[TS_CONFIG], 2) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 1);
|
||||
BIT(m_regs[TS_CONFIG], 2) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 1, 0);
|
||||
}
|
||||
|
||||
if (BIT(m_regs[TS_CONFIG], 6))
|
||||
{
|
||||
m_ts_tilemap[TM_TILES1]->draw(
|
||||
screen, bitmap, cliprect,
|
||||
BIT(m_regs[TS_CONFIG], 3) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 2);
|
||||
BIT(m_regs[TS_CONFIG], 3) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 2, 0);
|
||||
}
|
||||
|
||||
if (BIT(m_regs[TS_CONFIG], 7))
|
||||
{
|
||||
// draw_sprites(screen, bitmap, cliprect);
|
||||
// Avoid frequent expensive updates for now. Currently once per frame
|
||||
if (cliprect.bottom() == get_screen_area().bottom() && cliprect.right() == get_screen_area().right())
|
||||
draw_sprites(screen, bitmap, get_screen_area());
|
||||
draw_sprites(screen, bitmap, get_screen_area());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -249,6 +253,7 @@ void tsconf_state::tsconf_draw_txt(bitmap_rgb32 &bitmap, const rectangle &clipre
|
||||
void tsconf_state::tsconf_draw_gfx(bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
const rgb_t transparent = m_palette->pen_color(0);
|
||||
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
|
||||
{
|
||||
u16 y_offset = (OFFS_512(G_Y_OFFS_L) + m_gfx_y_frame_offset + vpos) & 0x1ff;
|
||||
@ -269,9 +274,21 @@ void tsconf_state::tsconf_draw_gfx(bitmap_rgb32 &bitmap, const rectangle &clipre
|
||||
if (x_offset == 512)
|
||||
video_location -= 256;
|
||||
u8 pix = *video_location++;
|
||||
*bm++ = m_palette->pen_color(pal_offset | (pix >> 4));
|
||||
rgb_t pen = m_palette->pen_color(pal_offset | (pix >> 4));
|
||||
if (pen != transparent)
|
||||
{
|
||||
*bm = pen;
|
||||
}
|
||||
bm++;
|
||||
if (width != 1)
|
||||
*bm++ = m_palette->pen_color(pal_offset | (pix & 0x0f));
|
||||
{
|
||||
pen = m_palette->pen_color(pal_offset | (pix & 0x0f));
|
||||
if (pen != transparent)
|
||||
{
|
||||
*bm = pen;
|
||||
}
|
||||
bm++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // VM_256C
|
||||
@ -280,7 +297,12 @@ void tsconf_state::tsconf_draw_gfx(bitmap_rgb32 &bitmap, const rectangle &clipre
|
||||
{
|
||||
if (x_offset == 512)
|
||||
video_location -= 512;
|
||||
*bm++ = m_palette->pen_color(*video_location++);
|
||||
rgb_t pen = m_palette->pen_color(*video_location++);
|
||||
if (pen != transparent)
|
||||
{
|
||||
*bm = pen;
|
||||
}
|
||||
bm++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -297,73 +319,69 @@ SFILE Reg.16 7 6 5 4 3 2 1 0
|
||||
*/
|
||||
void tsconf_state::draw_sprites(screen_device &screen_d, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle screen = get_screen_area();
|
||||
|
||||
u8 layer = 0;
|
||||
u8 *sinfo = m_sfile->pointer() + 1;
|
||||
u8 sid = 1;
|
||||
// Higher Sprite draws on top. Prepare to iterate backwards.
|
||||
for (; sid < 85 && layer < 3; sid++)
|
||||
if (m_sprites_cache.empty())
|
||||
{
|
||||
if (BIT(*sinfo, 6))
|
||||
layer++;
|
||||
sinfo += 6;
|
||||
}
|
||||
sinfo -= 1;
|
||||
|
||||
for (; sid; sid--)
|
||||
{
|
||||
s16 y = *sinfo++;
|
||||
y |= BIT(*sinfo, 0) << 8;
|
||||
y += screen.top() - (y >= screen.height() ? 512 : 0);
|
||||
u8 height8 = BIT(*sinfo, 1, 3);
|
||||
layer -= BIT(*sinfo, 6);
|
||||
if (!BIT(*sinfo, 5))
|
||||
const rectangle screen = get_screen_area();
|
||||
u8 layer = 0;
|
||||
u8 *sinfo = m_sfile->pointer();
|
||||
for (u8 sid = 0; sid < 85 && layer < 3; sid++)
|
||||
{
|
||||
// sprite disabled -> move to previous
|
||||
sinfo -= 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool flipy = BIT(*sinfo++, 7);
|
||||
s16 x = *sinfo++;
|
||||
x |= BIT(*sinfo, 0) << 8;
|
||||
x += screen.left() - (x >= screen.width() ? 512 : 0);
|
||||
u8 width8 = BIT(*sinfo, 1, 3);
|
||||
bool flipx = BIT(*sinfo++, 7);
|
||||
u16 code = *sinfo++;
|
||||
code |= BIT(*sinfo, 0, 4) << 8;
|
||||
u8 pal = BIT(*sinfo, 4, 4);
|
||||
sinfo -= 11;
|
||||
|
||||
u8 tile_row = code / 64 + flipy * height8;
|
||||
for (auto iy = y; iy <= y + height8 * 8; iy = iy + 8)
|
||||
s16 y = *sinfo++;
|
||||
y |= BIT(*sinfo, 0) << 8;
|
||||
y += screen.top() - (y >= screen.height() ? 512 : 0);
|
||||
const u8 height8 = BIT(*sinfo, 1, 3);
|
||||
const bool leap_next = BIT(*sinfo, 6);
|
||||
if (!BIT(*sinfo, 5))
|
||||
{
|
||||
u8 tile_col = (code % 64) + flipx * width8;
|
||||
for (auto ix = x; ix <= x + width8 * 8; ix = ix + 8)
|
||||
{
|
||||
if (layer == 2)
|
||||
{
|
||||
m_gfxdecode->gfx(TM_SPRITES)->transpen(
|
||||
bitmap, cliprect,
|
||||
tmp_tile_oversized_to_code((tile_row % 64) * 64 + (tile_col % 64)),
|
||||
pal, flipx, flipy, ix, iy,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_gfxdecode->gfx(TM_SPRITES)->prio_transpen(
|
||||
bitmap, cliprect,
|
||||
tmp_tile_oversized_to_code((tile_row % 64) * 64 + (tile_col % 64)),
|
||||
pal, flipx, flipy, ix, iy,
|
||||
screen_d.priority(), GFX_PMASK_2 | (layer ? GFX_PMASK_1 : 0), 0);
|
||||
}
|
||||
tile_col += flipx ? -1 : 1;
|
||||
}
|
||||
tile_row += flipy ? -1 : 1;
|
||||
// sprite disabled -> move to next
|
||||
sinfo += 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
const bool flipy = BIT(*sinfo++, 7);
|
||||
s16 x = *sinfo++;
|
||||
x |= BIT(*sinfo, 0) << 8;
|
||||
x += screen.left() - (x >= screen.width() ? 512 : 0);
|
||||
const u8 width8 = BIT(*sinfo, 1, 3);
|
||||
const bool flipx = BIT(*sinfo++, 7);
|
||||
u16 code = *sinfo++;
|
||||
code |= BIT(*sinfo, 0, 4) << 8;
|
||||
const u8 pal = BIT(*sinfo++, 4, 4);
|
||||
|
||||
u8 tile_row = code / 64 + flipy * height8;
|
||||
const u32 pmask = (~1) << layer;
|
||||
for (auto iy = y; iy <= y + height8 * 8; iy = iy + 8)
|
||||
{
|
||||
u8 tile_col = (code % 64) + flipx * width8;
|
||||
for (auto ix = x; ix <= x + width8 * 8; ix = ix + 8)
|
||||
{
|
||||
sprite_data spr = {};
|
||||
spr.code = (tile_row % 64) * 64 + (tile_col % 64);
|
||||
spr.color = pal;
|
||||
spr.flipx = flipx;
|
||||
spr.flipy = flipy;
|
||||
spr.destx = ix;
|
||||
spr.desty = iy;
|
||||
spr.pmask = pmask;
|
||||
|
||||
m_sprites_cache.push_back(spr);
|
||||
tile_col += flipx ? -1 : 1;
|
||||
}
|
||||
tile_row += flipy ? -1 : 1;
|
||||
}
|
||||
}
|
||||
layer += leap_next;
|
||||
}
|
||||
}
|
||||
|
||||
// Higher Sprite draws on top. Iterate backwards.
|
||||
for (auto spr = m_sprites_cache.rbegin(); spr != m_sprites_cache.rend(); ++spr)
|
||||
{
|
||||
m_gfxdecode->gfx(TM_SPRITES)->prio_transpen(bitmap, cliprect,
|
||||
tmp_tile_oversized_to_code(spr->code), spr->color, spr->flipx, spr->flipy, spr->destx, spr->desty,
|
||||
screen_d.priority(), spr->pmask, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void tsconf_state::ram_bank_write(u8 bank, offs_t offset, u8 data)
|
||||
@ -378,7 +396,10 @@ void tsconf_state::ram_bank_write(u8 bank, offs_t offset, u8 data)
|
||||
if (addr_w < 512)
|
||||
cram_write(addr_w, data);
|
||||
else if (addr_w < 1024)
|
||||
{
|
||||
m_sprites_cache.clear();
|
||||
m_sfile->write(addr_w - 512, data);
|
||||
}
|
||||
else
|
||||
tsconf_port_xxaf_w((addr_w - 1024) << 8, data);
|
||||
}
|
||||
@ -399,10 +420,16 @@ void tsconf_state::ram_page_write(u8 page, offs_t offset, u8 data)
|
||||
else
|
||||
{
|
||||
if (ram_addr >= PAGE4K(m_regs[T0_G_PAGE] & 0xf8) && ram_addr < PAGE4K((m_regs[T0_G_PAGE] & 0xf8) + 8))
|
||||
{
|
||||
m_gfxdecode->gfx(TM_TILES0)->mark_all_dirty();
|
||||
m_ts_tilemap[TM_TILES0]->mark_all_dirty();
|
||||
}
|
||||
|
||||
if (ram_addr >= PAGE4K(m_regs[T1_G_PAGE] & 0xf8) && ram_addr < PAGE4K((m_regs[T1_G_PAGE] & 0xf8) + 8))
|
||||
{
|
||||
m_gfxdecode->gfx(TM_TILES1)->mark_all_dirty();
|
||||
m_ts_tilemap[TM_TILES1]->mark_all_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (ram_addr >= get_vpage_offset() && ram_addr < get_vpage_offset() + PAGE4K((VM == VM_16C) ? 8 : 16))
|
||||
@ -451,6 +478,8 @@ void tsconf_state::cram_write16(offs_t offset, u16 data)
|
||||
|
||||
void tsconf_state::sfile_write16(offs_t offset, u16 data)
|
||||
{
|
||||
m_sprites_cache.clear();
|
||||
|
||||
u16 dest = offset & 0x1fe;
|
||||
m_sfile->write(dest, data >> 8);
|
||||
m_sfile->write(dest | 1, data & 0xff);
|
||||
@ -901,10 +930,12 @@ TIMER_CALLBACK_MEMBER(tsconf_state::irq_scanline)
|
||||
|
||||
case T0_G_PAGE:
|
||||
m_gfxdecode->gfx(TM_TILES0)->set_source(m_ram->pointer() + PAGE4K(val & 0xf8));
|
||||
m_ts_tilemap[TM_TILES0]->mark_all_dirty();
|
||||
break;
|
||||
|
||||
case T1_G_PAGE:
|
||||
m_gfxdecode->gfx(TM_TILES1)->set_source(m_ram->pointer() + PAGE4K(val & 0xf8));
|
||||
m_ts_tilemap[TM_TILES1]->mark_all_dirty();
|
||||
break;
|
||||
|
||||
case T0_X_OFFSET_L:
|
||||
|
Loading…
Reference in New Issue
Block a user