mirror of
https://github.com/holub/mame
synced 2025-05-29 17:13:05 +03:00
tatsumi.cpp: apply page wraparound for backgrounds, fixes various glitches in Big Fight and Cycle Warriors [Angelo Salese]
This commit is contained in:
parent
1c75a851e3
commit
1f7a89052c
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user