mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
added proper x-scroll handling for the decocass background, and some notes for further cleanup work regarding the background 'tilemap' - this improves Manhattan and several others.
This commit is contained in:
parent
b4da179247
commit
3ff105509c
@ -110,12 +110,12 @@ static ADDRESS_MAP_START( decocass_map, AS_PROGRAM, 8, decocass_state )
|
||||
AM_RANGE(0xe400, 0xe400) AM_WRITE(decocass_reset_w)
|
||||
|
||||
/* BIO-3 board */
|
||||
AM_RANGE(0xe402, 0xe402) AM_WRITE(decocass_mode_set_w)
|
||||
AM_RANGE(0xe403, 0xe403) AM_WRITE(decocass_back_h_shift_w)
|
||||
AM_RANGE(0xe404, 0xe404) AM_WRITE(decocass_back_vl_shift_w)
|
||||
AM_RANGE(0xe405, 0xe405) AM_WRITE(decocass_back_vr_shift_w)
|
||||
AM_RANGE(0xe406, 0xe406) AM_WRITE(decocass_part_h_shift_w)
|
||||
AM_RANGE(0xe407, 0xe407) AM_WRITE(decocass_part_v_shift_w)
|
||||
AM_RANGE(0xe402, 0xe402) AM_WRITE(decocass_mode_set_w) /* scroll mode regs + various enable regs */
|
||||
AM_RANGE(0xe403, 0xe403) AM_WRITE(decocass_back_h_shift_w) /* back (both) tilemap x scroll */
|
||||
AM_RANGE(0xe404, 0xe404) AM_WRITE(decocass_back_vl_shift_w) /* back (left) (top@rot0) tilemap y scroll */
|
||||
AM_RANGE(0xe405, 0xe405) AM_WRITE(decocass_back_vr_shift_w) /* back (right) (bot@rot0) tilemap y scroll */
|
||||
AM_RANGE(0xe406, 0xe406) AM_WRITE(decocass_part_h_shift_w) /* headlight */
|
||||
AM_RANGE(0xe407, 0xe407) AM_WRITE(decocass_part_v_shift_w) /* headlight */
|
||||
|
||||
AM_RANGE(0xe410, 0xe410) AM_WRITE(decocass_color_center_bot_w)
|
||||
AM_RANGE(0xe411, 0xe411) AM_WRITE(decocass_center_h_shift_space_w)
|
||||
|
@ -244,7 +244,7 @@ private:
|
||||
DECLARE_READ8_MEMBER(decocass_nodong_r);
|
||||
|
||||
UINT8* m_type1_map;
|
||||
|
||||
void draw_edge(bitmap_ind16 &bitmap, const rectangle &cliprect, int which, bool opaque);
|
||||
void draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_center(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void mark_bg_tile_dirty(offs_t offset);
|
||||
|
@ -2,6 +2,16 @@
|
||||
|
||||
DECO Cassette System video
|
||||
|
||||
The video system has clearly been designed for Highway Chase,
|
||||
which unsurprisingly is the first game on the system. The
|
||||
background 'tilemap' is very much like the road layer on the
|
||||
standalone Highway Chase with a concept of left/right edges
|
||||
with semi-independent scrolling, and the ability to transition
|
||||
between scrolling different sections.
|
||||
|
||||
Additionally it supports the headlight effect also needed for
|
||||
a Highway Chase style game.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
@ -460,6 +470,80 @@ void decocass_state::draw_missiles(bitmap_ind16 &bitmap, const rectangle &clipre
|
||||
}
|
||||
}
|
||||
|
||||
// we could still massively clean up the background tilemap handling, I have a feeling the
|
||||
// code to ignore tiles with 0x80 set on the left tilemap etc. is just a convenient hack
|
||||
// to stop garbage tiles appearing when scrolling due to the weird ram layout and clipping rules
|
||||
|
||||
// 0 is left edge, 1 is right edge
|
||||
void decocass_state::draw_edge(bitmap_ind16 &bitmap, const rectangle &cliprect, int which, bool opaque)
|
||||
{
|
||||
rectangle clip;
|
||||
bitmap_ind16* srcbitmap;
|
||||
|
||||
int scrolly_l = m_back_vl_shift;
|
||||
int scrolly_r = 256 - m_back_vr_shift;
|
||||
|
||||
// bit 0x04 of the mode select effectively selects between two banks of data
|
||||
if (0 == (m_mode_set & 0x04))
|
||||
scrolly_r += 256;
|
||||
else
|
||||
scrolly_l += 256;
|
||||
|
||||
int scrollx = 256 - m_back_h_shift;
|
||||
int scrolly;
|
||||
|
||||
if (which==0)
|
||||
{
|
||||
clip = m_bg_tilemap_l_clip;
|
||||
clip &= cliprect;
|
||||
scrolly = scrolly_l;
|
||||
srcbitmap = &m_bg_tilemap_l->pixmap();
|
||||
}
|
||||
else
|
||||
{
|
||||
clip = m_bg_tilemap_r_clip;
|
||||
clip &= cliprect;
|
||||
scrolly = scrolly_r;
|
||||
srcbitmap = &m_bg_tilemap_r->pixmap();
|
||||
}
|
||||
|
||||
int y,x;
|
||||
|
||||
// printf("m_mode_set %d\n", m_mode_set & 0x3);
|
||||
|
||||
// technically our y drawing probably shouldn't wrap / mask, but simply draw the 128pixel high 'edge' at the requested position
|
||||
// see note above this funciton
|
||||
for (y=clip.min_y; y<=clip.max_y;y++)
|
||||
{
|
||||
int srcline = (y + scrolly) & 0x1ff;
|
||||
UINT16* src = &srcbitmap->pix16(srcline);
|
||||
UINT16* dst = &bitmap.pix16(y);
|
||||
|
||||
for (x=clip.min_x; x<=clip.max_x;x++)
|
||||
{
|
||||
int srccol;
|
||||
|
||||
// 2 bits control the x scroll mode, allowing it to wrap either half of the tilemap, or transition one way or the other between the two halves
|
||||
|
||||
switch (m_mode_set & 3)
|
||||
{
|
||||
case 0x00: srccol = ((x + scrollx) & 0xff); break; // hwy normal case
|
||||
case 0x01: srccol = (x + scrollx + 0x100) & 0x1ff; break; // manhattan building top
|
||||
case 0x02: srccol = ((x + scrollx) & 0xff) + 0x100; break; // manhattan normal case
|
||||
case 0x03: srccol = (x + scrollx) & 0x1ff; break; // hwy, burnrub etc.
|
||||
}
|
||||
|
||||
UINT16 pix = src[srccol];
|
||||
|
||||
if ((pix & 0x3) || opaque)
|
||||
{
|
||||
dst[x] = pix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void decocass_state::video_start()
|
||||
{
|
||||
@ -477,7 +561,7 @@ void decocass_state::video_start()
|
||||
m_bg_tilemap_r_clip = machine().primary_screen->visible_area();
|
||||
m_bg_tilemap_r_clip.min_y = 256 / 2;
|
||||
|
||||
/* background videroam bits D0-D3 are shared with the tileram */
|
||||
/* background videoram bits D0-D3 are shared with the tileram */
|
||||
m_bgvideoram = m_tileram;
|
||||
m_bgvideoram_size = 0x0400; /* d000-d3ff */
|
||||
|
||||
@ -493,8 +577,7 @@ void decocass_state::video_start()
|
||||
|
||||
UINT32 decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int scrollx, scrolly_l, scrolly_r;
|
||||
rectangle clip;
|
||||
/* THIS CODE SHOULD NOT BE IN SCREEN UPDATE !! */
|
||||
|
||||
if (0xc0 != (machine().root_device().ioport("IN2")->read() & 0xc0)) /* coin slots assert an NMI */
|
||||
m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
@ -504,6 +587,9 @@ UINT32 decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind1
|
||||
else if (m_watchdog_count-- > 0)
|
||||
machine().watchdog_reset();
|
||||
|
||||
/* (end) THIS CODE SHOULD NOT BE IN SCREEN UPDATE !! */
|
||||
|
||||
|
||||
#ifdef MAME_DEBUG
|
||||
{
|
||||
if (machine().input().code_pressed_once(KEYCODE_I))
|
||||
@ -525,39 +611,10 @@ UINT32 decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind1
|
||||
|
||||
bitmap.fill(0, cliprect);
|
||||
|
||||
scrolly_l = m_back_vl_shift;
|
||||
scrolly_r = 256 - m_back_vr_shift;
|
||||
|
||||
scrollx = 256 - m_back_h_shift;
|
||||
if (0 == (m_mode_set & 0x02))
|
||||
scrollx += 256;
|
||||
|
||||
#if 0
|
||||
/* this is wrong */
|
||||
if (0 != m_back_h_shift && 0 == ((m_mode_set ^ (m_mode_set >> 1)) & 1))
|
||||
scrollx += 256;
|
||||
#endif
|
||||
|
||||
if (0 == (m_mode_set & 0x04))
|
||||
scrolly_r += 256;
|
||||
else
|
||||
scrolly_l += 256;
|
||||
|
||||
m_bg_tilemap_l->set_scrollx(0, scrollx);
|
||||
m_bg_tilemap_l->set_scrolly(0, scrolly_l);
|
||||
|
||||
m_bg_tilemap_r->set_scrollx(0, scrollx);
|
||||
m_bg_tilemap_r->set_scrolly(0, scrolly_r);
|
||||
|
||||
if (m_mode_set & 0x08) /* bkg_ena on ? */
|
||||
{
|
||||
clip = m_bg_tilemap_l_clip;
|
||||
clip &= cliprect;
|
||||
m_bg_tilemap_l->draw(bitmap, clip, TILEMAP_DRAW_OPAQUE, 0);
|
||||
|
||||
clip = m_bg_tilemap_r_clip;
|
||||
clip &= cliprect;
|
||||
m_bg_tilemap_r->draw(bitmap, clip, TILEMAP_DRAW_OPAQUE, 0);
|
||||
draw_edge(bitmap,cliprect,0,true);
|
||||
draw_edge(bitmap,cliprect,1,true);
|
||||
}
|
||||
|
||||
if (m_mode_set & 0x20)
|
||||
@ -571,13 +628,8 @@ UINT32 decocass_state::screen_update_decocass(screen_device &screen, bitmap_ind1
|
||||
draw_center(bitmap, cliprect);
|
||||
if (m_mode_set & 0x08) /* bkg_ena on ? */
|
||||
{
|
||||
clip = m_bg_tilemap_l_clip;
|
||||
clip &= cliprect;
|
||||
m_bg_tilemap_l->draw(bitmap, clip, 0, 0);
|
||||
|
||||
clip = m_bg_tilemap_r_clip;
|
||||
clip &= cliprect;
|
||||
m_bg_tilemap_r->draw(bitmap, clip, 0, 0);
|
||||
draw_edge(bitmap,cliprect,0,false);
|
||||
draw_edge(bitmap,cliprect,1,false);
|
||||
}
|
||||
}
|
||||
m_fg_tilemap->draw(bitmap, cliprect, 0, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user