Skip to content

Commit c510152

Browse files
authored
segas32: fix NBG0 - NBG3 layer flip (#14193)
1 parent 47fe973 commit c510152

File tree

1 file changed

+19
-25
lines changed

1 file changed

+19
-25
lines changed

src/mame/sega/segas32_v.cpp

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,8 @@
2020
- Verify that X/Y center has 10 bits of resolution when zooming and
2121
9 when not.
2222
23-
- In svf (the field) and radr (on the field), they use tilemap-specific
24-
flip in conjunction with rowscroll AND rowselect. According to Charles,
25-
in this case, the rowselect lookups should be done in reverse order,
26-
but this results in an incorrect display. For now, we assume there is
27-
a bug in the procedure and implement it so that it looks correct.
23+
- Sonic while globally flipped via the service menu, fails to flip
24+
the "SEGA" and "SEGASONIC" sprite based logos on the title screen.
2825
2926
- titlef NBG0 and NBG2 layers are currently hidden during gameplay.
3027
It sets $31ff02 with either $7be0 and $2960 (and $31ff8e is $c00).
@@ -61,8 +58,8 @@
6158
$31FF00 : w--- ---- ---- ---- : Screen width (0= 320, 1= 412)
6259
---- f--- ---- ---- : Bitmap format (1= 8bpp, 0= 4bpp)
6360
---- -t-- ---- ---- : Tile banking related
64-
---- --f- ---- ---- : 1= Global X/Y flip? (most games?)
65-
---- ---f ---- ---- : 1= prohbit Y flip? (Air Rescue 2nd screen title, also gets set on one of the intro sequence screens)
61+
---- --f- ---- ---- : 1= Global X/Y flip (enabled via service menu)
62+
---- ---f ---- ---- : 1= Prohibit layer Y flip (NBG0 - NBG3)
6663
---- ---- ---- 4--- : 1= X+Y flip for NBG3
6764
---- ---- ---- -2-- : 1= X+Y flip for NBG2
6865
---- ---- ---- --1- : 1= X+Y flip for NBG1
@@ -544,7 +541,7 @@ TILE_GET_INFO_MEMBER(segas32_state::get_tile_info)
544541

545542
int segas32_state::compute_clipping_extents(screen_device &screen, int enable, int clipout, int clipmask, const rectangle &cliprect, extents_list *list)
546543
{
547-
int flip = (m_videoram[0x1ff00/2] >> 9) & 1;
544+
int flip = BIT(m_videoram[0x1ff00 / 2], 9);
548545
rectangle tempclip;
549546
rectangle clips[5];
550547
int sorted[5];
@@ -646,20 +643,14 @@ int segas32_state::compute_clipping_extents(screen_device &screen, int enable, i
646643

647644
void segas32_state::compute_tilemap_flips(int bgnum, int &flipx, int &flipy)
648645
{
649-
/* determine if we're flipped */
650-
int global_flip = (m_videoram[0x1ff00 / 2] >> 9)&1;
651-
652-
flipx = global_flip;
653-
flipy = global_flip;
654-
655-
int layer_flip = (m_videoram[0x1ff00 / 2] >> bgnum) & 1;
646+
// determine flip bits
647+
int global_flip = BIT(m_videoram[0x1ff00 / 2], 9);
648+
int layer_flip = BIT(m_videoram[0x1ff00 / 2], bgnum);
649+
int prohibit_flipy = BIT(m_videoram[0x1ff00 / 2], 8);
656650

657-
flipy ^= layer_flip;
658-
flipx ^= layer_flip;
651+
flipx = (layer_flip) ? !global_flip : global_flip;
659652

660-
// this bit is set on Air Rescue (screen 2) title screen, during the Air Rescue introduction demo, and in f1en when you win a single player race
661-
// it seems to prohibit (at least) the per-tilemap y flipping (maybe global y can override it)
662-
if ((m_videoram[0x1ff00 / 2] >> 8) & 1) flipy = 0;
653+
flipy = (layer_flip && !prohibit_flipy) ? !global_flip : global_flip;
663654
}
664655

665656
/*************************************
@@ -705,7 +696,7 @@ void segas32_state::update_tilemap_zoom(screen_device &screen, segas32_state::la
705696
//if (screen.machine().input().code_pressed(KEYCODE_X) && bgnum == 1) opaque = 1;
706697
int flipx, flipy;
707698

708-
// todo determine flipping
699+
// determine flipping
709700
compute_tilemap_flips(bgnum, flipx, flipy);
710701

711702
/* determine the clipping */
@@ -863,7 +854,7 @@ void segas32_state::update_tilemap_rowscroll(screen_device &screen, segas32_stat
863854

864855
int flipx, flipy;
865856

866-
// todo determine flipping
857+
// determine flipping
867858
compute_tilemap_flips(bgnum, flipx, flipy);
868859

869860

@@ -914,21 +905,24 @@ void segas32_state::update_tilemap_rowscroll(screen_device &screen, segas32_stat
914905
}
915906

916907
int srcy;
908+
int ylookup;
917909
if (!flipy)
918910
{
919911
srcy = yscroll + y;
912+
ylookup = y;
920913
}
921914
else
922915
{
923916
const rectangle &visarea = screen.visible_area();
924917
srcy = yscroll + visarea.max_y - y;
918+
ylookup = visarea.max_y - y;
925919
}
926920

927921
/* apply row scroll/select */
928922
if (rowscroll)
929-
srcx += table[0x000 + 0x100 * (bgnum - 2) + y] & 0x3ff;
923+
srcx += table[0x000 + 0x100 * (bgnum - 2) + ylookup] & 0x3ff;
930924
if (rowselect)
931-
srcy = (yscroll + table[0x200 + 0x100 * (bgnum - 2) + y]) & 0x1ff;
925+
srcy = (yscroll + table[0x200 + 0x100 * (bgnum - 2) + ylookup]) & 0x1ff;
932926

933927

934928
/* look up the pages and get their source pixmaps */
@@ -996,7 +990,7 @@ void segas32_state::update_tilemap_text(screen_device &screen, segas32_state::la
996990
bitmap_ind16 &bitmap = layer.bitmap;
997991

998992
/* determine if we're flipped */
999-
int flip = (m_videoram[0x1ff00/2] >> 9) & 1;
993+
int flip = BIT(m_videoram[0x1ff00 / 2], 9);
1000994

1001995
/* determine the base of the tilemap and graphics data */
1002996
uint16_t const *const tilebase = &m_videoram[((m_videoram[0x1ff5c/2] >> 4) & 0x1f) * 0x800];

0 commit comments

Comments
 (0)