tatsumi.cpp: apply page wraparound for backgrounds, fixes various glitches in Big Fight and Cycle Warriors [Angelo Salese]

This commit is contained in:
angelosa 2018-06-07 00:54:11 +02:00
parent 1c75a851e3
commit 1f7a89052c
3 changed files with 67 additions and 22 deletions

View File

@ -16,8 +16,8 @@
- Round Up 5: Finish road layer.
Tunnel sections are borderline unplayable, plus slopes are ugly to watch.
- Apache 3: road layer, has twelve rotation registers!
- Cycle Warriors: transparent road layer on sidelines, wrong mask_data?
- Missing BG layer (Round Up 5) - banked VRAM data from somewhere!?
- (fixed) Cycle Warriors: transparent road layer on sidelines, wrong mask_data?
- (fixed) Missing BG layer (Round Up 5) - banked VRAM data from somewhere!?
- Round Up 5: always boots with a coin inserted
$5152 is the coin counter, gets an explicit 1 at boot.
There are other two buffers read from 68k before that, written to $5156 and $515a
@ -25,10 +25,10 @@
- (fixed) Round Up 5 doesn't survive a reset
- (fixed?) Cycle Warriors: test mode text does not appear as it needs a -256 Y
scroll offset from somewhere.
- Cycle Warriors: sometimes it draws garbage on character select or even hangs
- (fixed) Cycle Warriors: sometimes it draws garbage on character select or even hangs
depending on where player coins up, most likely caused by miscommunication with sub CPU?
- Cycle Warriors: ranking screen is completely wrong;
- Cycle Warriors: ugly orange color on character select and briefing screens, layer disable?
- (fixed) Cycle Warriors: ranking screen is completely wrong;
- (fixed) Cycle Warriors: ugly orange color on character select and briefing screens, layer disable?
- Combine Big Fight & CycleWarriors video routines - currently each
game uses different sized tilemaps - these are probably software
controlled rather than hardwired, but I don't think either game
@ -190,11 +190,6 @@ WRITE16_MEMBER(cyclwarr_state::cyclwarr_sprite_w)
COMBINE_DATA(&m_spriteram[offset]);
}
WRITE16_MEMBER(cyclwarr_state::bigfight_a20000_w)
{
COMBINE_DATA(&m_bigfight_a20000[offset]);
}
WRITE16_MEMBER(cyclwarr_state::bigfight_a40000_w)
{
COMBINE_DATA(&m_bigfight_a40000[offset]);
@ -203,6 +198,7 @@ WRITE16_MEMBER(cyclwarr_state::bigfight_a40000_w)
WRITE16_MEMBER(cyclwarr_state::bigfight_a60000_w)
{
COMBINE_DATA(&m_bigfight_a60000[offset]);
// popmessage("%04x",m_bigfight_a60000[offset]);
}
template<int Bank>
@ -343,7 +339,7 @@ void cyclwarr_state::common_map(address_map &map)
map(0x080000, 0x08ffff).rw(this, FUNC(cyclwarr_state::cyclwarr_videoram_r<1>), FUNC(cyclwarr_state::cyclwarr_videoram_w<1>)).share("cw_videoram1");
map(0x090000, 0x09ffff).rw(this, FUNC(cyclwarr_state::cyclwarr_videoram_r<0>), FUNC(cyclwarr_state::cyclwarr_videoram_w<0>)).share("cw_videoram0");
map(0x0a2000, 0x0a2007).w(this, FUNC(cyclwarr_state::bigfight_a20000_w));
map(0x0a2000, 0x0a2007).w(this, FUNC(cyclwarr_state::video_config_w));
map(0x0a4000, 0x0a4001).w(this, FUNC(cyclwarr_state::bigfight_a40000_w));
map(0x0a6000, 0x0a6001).w(this, FUNC(cyclwarr_state::bigfight_a60000_w));
map(0x0ac000, 0x0ac003).w(this, FUNC(tatsumi_state::hd6445_crt_w)).umask16(0x00ff);

View File

@ -195,7 +195,7 @@ public:
DECLARE_READ16_MEMBER(cyclwarr_sprite_r);
DECLARE_WRITE16_MEMBER(cyclwarr_sprite_w);
DECLARE_WRITE16_MEMBER(bigfight_a20000_w);
DECLARE_WRITE16_MEMBER(video_config_w);
DECLARE_WRITE16_MEMBER(bigfight_a40000_w);
DECLARE_WRITE16_MEMBER(bigfight_a60000_w);
DECLARE_WRITE8_MEMBER(cyclwarr_control_w);
@ -234,16 +234,17 @@ private:
std::vector<uint8_t> m_mask;
tilemap_t *m_layer[4];
uint16_t m_bigfight_a20000[8];
uint16_t m_video_config[4];
uint16_t m_bigfight_a60000[2];
uint16_t m_bigfight_a40000[2];
uint16_t m_bigfight_bank;
uint16_t m_bigfight_last_bank;
uint16_t m_road_color_bank, m_prev_road_bank;
uint16_t m_layer_page_size[4];
bool m_layer1_can_be_road;
void tile_expand();
void draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *src, const uint16_t* scrollx, const uint16_t* scrolly, bool is_road, int hi_priority);
void draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *src, const uint16_t* scrollx, const uint16_t* scrolly, const uint16_t layer_page_size, bool is_road, int hi_priority);
void draw_bg_layers(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int hi_priority);
};

View File

@ -1058,6 +1058,27 @@ uint32_t roundup5_state::screen_update_roundup5(screen_device &screen, bitmap_rg
*
*********************************/
/*
* these video registers never changes
*
* Big Fight
* 72f2 5af2 3af2 22fa
*
* Cycle Warriors
* 5673 92c2 3673 267b
*
* Following is complete guesswork (since nothing changes it's very hard to pinpoint what these bits do :/)
* Layer order is 3-1-2-0 ?
* x--- -x-- ---- ---- one of these might be enable page select
* ---- ---- x--- ---- tilemap size
* ---x ---- ---- x--- one these might be color bank
*
*/
WRITE16_MEMBER(cyclwarr_state::video_config_w)
{
COMBINE_DATA(&m_video_config[offset]);
}
template<int Bank>
TILE_GET_INFO_MEMBER(cyclwarr_state::get_tile_info_bigfight)
{
@ -1162,9 +1183,14 @@ VIDEO_START_MEMBER(cyclwarr_state,cyclwarr)
// set up scroll bases
// TODO: more HW configs
m_layer[3]->set_scrolldx(-8,-8);
m_layer_page_size[3] = 0x200;
m_layer[2]->set_scrolldx(-8,-8);
m_layer_page_size[2] = 0x200;
m_layer[1]->set_scrolldx(-8,-8);
m_layer_page_size[1] = 0x200;
m_layer[0]->set_scrolldx(-0x10,-0x10);
m_layer_page_size[0] = 0x100;
m_layer1_can_be_road = true;
}
@ -1184,11 +1210,14 @@ VIDEO_START_MEMBER(cyclwarr_state,bigfight)
m_layer[2]->set_scrolldx(-8,-8);
m_layer[1]->set_scrolldx(-8,-8);
m_layer[0]->set_scrolldx(-0x10,-0x10);
for(int i=0;i<4;i++)
m_layer_page_size[i] = 0x200;
m_layer1_can_be_road = false;
}
void cyclwarr_state::draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *src, const uint16_t* scrollx, const uint16_t* scrolly, bool is_road, int hi_priority)
void cyclwarr_state::draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, tilemap_t *src, const uint16_t* scrollx, const uint16_t* scrolly, const uint16_t layer_page_size, bool is_road, int hi_priority)
{
rectangle clip;
clip.min_x = cliprect.min_x;
@ -1196,21 +1225,31 @@ void cyclwarr_state::draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const
// TODO: both always enabled when this occurs
bool rowscroll_enable = (scrollx[0] & 0x1000) == 0;
bool colscroll_enable = (scrollx[0] & 0x2000) == 0;
// this controls wraparound (tilemap can't go above a threshold)
// TODO: Actually scrolly registers 0xf0 to 0xff are used (can split the tilemap furthermore?)
uint16_t page_select = scrolly[0xff];
for (int y=cliprect.min_y; y<=cliprect.max_y; y++)
{
clip.min_y = clip.max_y = y;
int y_base = rowscroll_enable ? y : 0;
int x_base = colscroll_enable ? y : 0;
int src_y = (scrolly[y_base] & 0xfff);
int src_y = (scrolly[y_base] & 0x7ff);
int src_x = (scrollx[x_base] & 0x7ff);
// apparently if this is on disables wraparound target
int page_disable = scrolly[y_base] & 0x800;
int cur_page = src_y + y;
// special handling for cycle warriors road: it reads in scrolly table bits 15-13 an
// additional tile color bank and per scanline.
if(is_road == true)
{
if(scrolly[y_base] & 0x8000)
{
m_road_color_bank = (scrolly[y_base] >> 13) & 3;
// road mode disables page wraparound
page_disable = 1;
}
else
m_road_color_bank = 0;
@ -1221,6 +1260,13 @@ void cyclwarr_state::draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const
}
}
// apply wraparound, if enabled tilemaps can't go above a certain threshold
// cfr. Cycle Warriors scrolling text (ranking, ending), backgrounds when uphill,
// Big Fight vertical scrolling in the morning Funnel stage (not the one chosen at start),
// also Big Fight text garbage in the stage after Mevella joins you (forgot the name)
if((cur_page - page_select) >= layer_page_size && page_disable == 0)
src_y -= layer_page_size;
src->set_scrollx(0,src_x);
src->set_scrolly(0,src_y);
src->draw(screen, bitmap, clip, TILEMAP_DRAW_CATEGORY(hi_priority), 0);
@ -1229,10 +1275,10 @@ void cyclwarr_state::draw_bg(screen_device &screen, bitmap_rgb32 &bitmap, const
void cyclwarr_state::draw_bg_layers(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int hi_priority)
{
draw_bg(screen, bitmap, cliprect, m_layer[3], &m_cyclwarr_videoram[1][0x000], &m_cyclwarr_videoram[1][0x100], false, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[2], &m_cyclwarr_videoram[1][0x200], &m_cyclwarr_videoram[1][0x300], false, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[1], &m_cyclwarr_videoram[0][0x000], &m_cyclwarr_videoram[0][0x100], m_layer1_can_be_road, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[0], &m_cyclwarr_videoram[0][0x200], &m_cyclwarr_videoram[0][0x300], false, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[3], &m_cyclwarr_videoram[1][0x000], &m_cyclwarr_videoram[1][0x100], m_layer_page_size[3], false, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[2], &m_cyclwarr_videoram[1][0x200], &m_cyclwarr_videoram[1][0x300], m_layer_page_size[2],false, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[1], &m_cyclwarr_videoram[0][0x000], &m_cyclwarr_videoram[0][0x100], m_layer_page_size[1],m_layer1_can_be_road, hi_priority);
draw_bg(screen, bitmap, cliprect, m_layer[0], &m_cyclwarr_videoram[0][0x200], &m_cyclwarr_videoram[0][0x300], m_layer_page_size[0], false, hi_priority);
}
uint32_t cyclwarr_state::screen_update_cyclwarr(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
@ -1258,6 +1304,8 @@ uint32_t cyclwarr_state::screen_update_cyclwarr(screen_device &screen, bitmap_rg
,m_cyclwarr_videoram[0][0x200],m_cyclwarr_videoram[0][0x300],m_cyclwarr_videoram[0][0x3ff]);
#endif
// popmessage("%04x %04x %04x %04x",m_video_config[0],m_video_config[1],m_video_config[2],m_video_config[3]);
screen.priority().fill(0, cliprect);
draw_sprites(screen.priority(),cliprect,1,(m_sprite_control_ram[0xe0]&0x1000) ? 0x1000 : 0); // Alpha pass only
draw_bg_layers(screen, bitmap, cliprect, 0);