SSV: add masking logic for non 6/8bpp modes, needed by eaglshot (#4341)

* SSV: add proper bitplane masking logic for all cases, needed by eaglshot

* make new logic only apply to eaglshot for now, it's clearly correct for that, but there must be an enable somewhere (nw)

* (nw)

* try this way, without further evidence it's difficult to make a call (nw)

* use standardized spelling on gdfs title (nw)

* copyright holders (nw)
This commit is contained in:
David Haywood 2018-11-29 08:48:35 +00:00 committed by Vas Crabb
parent 7bdd411be0
commit c6ec55d1d3
3 changed files with 45 additions and 54 deletions

View File

@ -889,7 +889,6 @@ WRITE16_MEMBER(ssv_state::eaglshot_gfxram_w)
offset += (m_scroll[0x76/2] & 0xf) * 0x40000/2;
COMBINE_DATA(&m_eaglshot_gfxram[offset]);
m_gfxdecode->gfx(0)->mark_dirty(offset / (16*8/2));
m_gfxdecode->gfx(1)->mark_dirty(offset / (16*8/2));
}
@ -1835,9 +1834,9 @@ static INPUT_PORTS_START( mslider )
PORT_DIPUNUSED_DIPLOC( 0x0080, 0x0080, "DSW1:8" ) /* Manual lists this dip as "Unused" */
PORT_MODIFY("DSW2") // IN1 - $210004
PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION( "DSW2:1" )
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_DIPNAME( 0x0001, 0x0000, DEF_STR( Flip_Screen ) ) PORT_DIPLOCATION( "DSW2:1" )
PORT_DIPSETTING( 0x0001, DEF_STR( On ) ) // service mode calls this OFF
PORT_DIPSETTING( 0x0000, DEF_STR( Off ) ) // and this ON, TODO: check if it's an error in the video code, or a mistake in the game
PORT_DIPNAME( 0x0002, 0x0002, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION( "DSW2:2" )
PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0002, DEF_STR( On ) )
@ -2399,23 +2398,8 @@ static const gfx_layout layout_16x8x8 =
16*8*2
};
static const gfx_layout layout_16x8x6 =
{
16,8,
RGN_FRAC(1,4),
6,
{
RGN_FRAC(2,4)+8, RGN_FRAC(2,4)+0,
RGN_FRAC(1,4)+8, RGN_FRAC(1,4)+0,
RGN_FRAC(0,4)+8, RGN_FRAC(0,4)+0 },
{ STEP8(0,1), STEP8(16,1) },
{ STEP8(0,16*2) },
16*8*2
};
static GFXDECODE_START( gfx_ssv )
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8x8, 0, 0x8000/64 ) // [0] Sprites (256 colors)
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8x6, 0, 0x8000/64 ) // [1] Sprites (64 colors)
GFXDECODE_END
static const gfx_layout layout_16x8x8_ram =
@ -2429,20 +2413,8 @@ static const gfx_layout layout_16x8x8_ram =
16*8*8
};
static const gfx_layout layout_16x8x6_ram =
{
16,8,
0x40000 * 16 / (16 * 8),
6,
{ 2,3,4,5,6,7 },
{ STEP16(0,8) },
{ STEP8(0,16*8) },
16*8*8
};
static GFXDECODE_START( gfx_eaglshot )
GFXDECODE_ENTRY( nullptr, 0, layout_16x8x8_ram, 0, 0x8000/64 ) // [0] Sprites (256 colors, decoded from RAM)
GFXDECODE_ENTRY( nullptr, 0, layout_16x8x6_ram, 0, 0x8000/64 ) // [1] Sprites (64 colors, decoded from RAM)
GFXDECODE_END
static const gfx_layout layout_16x16x8 =
@ -2458,7 +2430,6 @@ static const gfx_layout layout_16x16x8 =
static GFXDECODE_START( gfx_gdfs )
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8x8, 0, 0x8000/64 ) // [0] Sprites (256 colors)
GFXDECODE_ENTRY( "gfx1", 0, layout_16x8x6, 0, 0x8000/64 ) // [1] Sprites (64 colors)
GFXDECODE_ENTRY( "gfx3", 0, layout_16x16x8, 0, 0x8000/256 ) // [3] Tilemap
GFXDECODE_END
@ -4770,13 +4741,13 @@ GAME( 1993, survartsj, survarts, survarts, survarts, ssv_state, init_survarts,
GAME( 1994, drifto94, 0, drifto94, drifto94, ssv_state, init_drifto94, ROT0, "Visco", "Drift Out '94 - The Hard Order (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1994, eaglshot, 0, eaglshot, eaglshot, ssv_state, init_eaglshot, ROT0, "Sammy", "Eagle Shot Golf", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1994, eaglshot, 0, eaglshot, eaglshot, ssv_state, init_eaglshot, ROT0, "Sammy", "Eagle Shot Golf (US)", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
GAME( 1995, hypreact, 0, hypreact, hypreact, ssv_state, init_hypreact, ROT0, "Sammy", "Mahjong Hyper Reaction (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1994, twineag2, 0, twineag2, twineag2, ssv_state, init_twineag2, ROT270, "Seta", "Twin Eagle II - The Rescue Mission", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, gdfs, 0, gdfs, gdfs, ssv_state, init_gdfs, ROT0, "Banpresto", "Mobil Suit Gundam Final Shooting (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
GAME( 1995, gdfs, 0, gdfs, gdfs, ssv_state, init_gdfs, ROT0, "Banpresto", "Mobile Suit Gundam Final Shooting (Japan)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE ) // title screen spells the title "Mobil" but standardized spelling is "Mobile" it also lists the company name as "Banprest" instead of "Banpresto"
// Ultra X Weapon: "developed by Seta" in ending screen
GAME( 1995, ultrax, 0, ultrax, ultrax, ssv_state, init_ultrax, ROT270, "Banpresto / Tsuburaya Productions / Seta", "Ultra X Weapons / Ultra Keibitai", MACHINE_NO_COCKTAIL | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) // 95-01-30 13:27:15 on startup

View File

@ -169,8 +169,8 @@ private:
void update_irq_state();
IRQ_CALLBACK_MEMBER(irq_callback);
void drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow, int realline, int line);
void drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx,uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy,int shadow);
void drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow, int realline, int line);
void drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx,uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy,int shadow);
void draw_16x16_tile_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int flipx, int flipy, int mode, int code, int color, int sx, int sy, int realline, int line);
void get_tile(int x, int y, int size, int page, int& code, int& attr, int& flipx, int& flipy);

View File

@ -1,5 +1,5 @@
// license:BSD-3-Clause
// copyright-holders:Luca Elia
// copyright-holders:Luca Elia, Roberto Zandona, David Haywood
/***************************************************************************
-= Seta, Sammy, Visco (SSV) System =-
@ -37,7 +37,8 @@
* bit c, which enables/disables the 2 high order bitplanes (256 / 64 color tiles)
is the only one implemented. Needed by keithlcy (logo), drifto94 (wheels).
is needed by keithlcy (logo), drifto94 (wheels).
eaglshot masks even more bits, needed for 'birdie' text etc.
A single-sprite can be:
@ -137,30 +138,51 @@
#include "render.h"
void ssv_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow, int realline, int line)
void ssv_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow, int realline, int line)
{
const uint8_t *const addr = gfx->get_data(code % gfx->elements());
const uint32_t realcolor = gfx->granularity() * (color % gfx->colors());
gfx_element *gfxelement = m_gfxdecode->gfx(0);
const uint8_t* const source = flipy ? addr + (7 - line) * gfx->rowbytes() : addr + line * gfx->rowbytes();
const uint8_t *const addr = gfxelement->get_data(code % gfxelement->elements());
const uint32_t realcolor = gfxelement->granularity() * (color % gfxelement->colors());
const uint8_t* const source = flipy ? addr + (7 - line) * gfxelement->rowbytes() : addr + line * gfxelement->rowbytes();
if (realline >= cliprect.min_y && realline <= cliprect.max_y)
{
uint8_t m_gfxbppmask = 0x00;
// comments at top suggest that each bit of 'gfx' enables 2 bitplanes, but ultrax case disagrees, also that would require 4 bits to cover all cases, and we only have 3
switch (gfx & 0x07)
{
case 0x07: m_gfxbppmask = 0xff; break; // common 8bpp case
case 0x06: m_gfxbppmask = 0x3f; break; // common 6bpp case + keithlcy (logo), drifto94 (wheels) masking
case 0x04: m_gfxbppmask = 0x0f; break; // eagle shot 4bpp birdie text (there is probably a case for the other 4bpp? but that's only used for Japanese text and the supported set isn't Japanese)
case 0x00: m_gfxbppmask = 0x3f; break; // ultrax, twineag2 text - is there a local / global mixup somewhere, or is this an 'invalid' setting that just enables all planes?
// unverified cases, just mimic old driver behavior of only using lowest bit
case 0x05: m_gfxbppmask = 0xff; break;
case 0x03: m_gfxbppmask = 0xff; break;
case 0x01: m_gfxbppmask = 0xff; break;
case 0x02: m_gfxbppmask = 0x3f; break;
}
uint16_t* dest = &bitmap.pix16(realline);
const int x0 = flipx ? (base_sx + gfx->width() - 1) : (base_sx);
const int x1 = flipx ? (base_sx - 1) : (x0 + gfx->width());
const int x0 = flipx ? (base_sx + gfxelement->width() - 1) : (base_sx);
const int x1 = flipx ? (base_sx - 1) : (x0 + gfxelement->width());
const int dx = flipx ? (-1) : (1);
int column = 0;
for (int sx = x0; sx != x1; sx += dx)
{
uint8_t pen = source[column];
uint8_t pen = source[column] & m_gfxbppmask;
if (pen && sx >= cliprect.min_x && sx <= cliprect.max_x)
{
if (shadow)
dest[sx] = ((dest[sx] & m_shadow_pen_mask) | (pen << m_shadow_pen_shift)) & 0x7fff; \
dest[sx] = ((dest[sx] & m_shadow_pen_mask) | (pen << m_shadow_pen_shift)) & 0x7fff;
else
dest[sx] = (realcolor + pen) & 0x7fff;
}
@ -169,7 +191,7 @@ void ssv_state::drawgfx_line(bitmap_ind16 &bitmap, const rectangle &cliprect, gf
}
}
void ssv_state::drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, gfx_element *gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow)
void ssv_state::drawgfx(bitmap_ind16 &bitmap, const rectangle &cliprect, int gfx, uint32_t code, uint32_t color, int flipx, int flipy, int base_sx, int base_sy, int shadow)
{
for (int line = 0; line < 8; line++)
{
@ -194,7 +216,6 @@ VIDEO_START_MEMBER(ssv_state,eaglshot)
m_eaglshot_gfxram = std::make_unique<uint16_t[]>(16 * 0x40000 / 2);
m_gfxdecode->gfx(0)->set_source((uint8_t *)m_eaglshot_gfxram.get());
m_gfxdecode->gfx(1)->set_source((uint8_t *)m_eaglshot_gfxram.get());
save_pointer(NAME(m_eaglshot_gfxram), 16 * 0x40000 / 2);
}
@ -203,7 +224,7 @@ TILE_GET_INFO_MEMBER(ssv_state::get_tile_info_0)
{
uint16_t tile = m_gdfs_tmapram[tile_index];
SET_TILE_INFO_MEMBER(2, tile, 0, TILE_FLIPXY( tile >> 14 ));
SET_TILE_INFO_MEMBER(1, tile, 0, TILE_FLIPXY( tile >> 14 ));
}
WRITE16_MEMBER(ssv_state::gdfs_tmapram_w)
@ -216,7 +237,6 @@ VIDEO_START_MEMBER(ssv_state,gdfs)
{
ssv_state::video_start();
m_gdfs_tmap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(ssv_state::get_tile_info_0),this), TILEMAP_SCAN_ROWS, 16,16, 0x100,0x100);
m_gdfs_tmap->set_transparent_pen(0);
@ -589,9 +609,9 @@ void ssv_state::draw_16x16_tile_line(bitmap_ind16 &bitmap, const rectangle &clip
int shadow = (mode & 0x0800);
/* Select 256 or 64 color tiles */
int gfx = ((mode & 0x0100) ? 0 : 1);
int gfx = ((mode & 0x0700) >> 8);
drawgfx_line(bitmap, cliprect, m_gfxdecode->gfx(gfx), realcode, color, flipx, flipy, sx, sy, shadow, realline, tileline);
drawgfx_line(bitmap, cliprect, gfx, realcode, color, flipx, flipy, sx, sy, shadow, realline, tileline);
}
@ -715,7 +735,7 @@ void ssv_state::draw_sprites_tiles(bitmap_ind16 &bitmap, const rectangle &clipre
{
for (int y = ystart; y != yend; y += yinc)
{
drawgfx(bitmap, cliprect, m_gfxdecode->gfx(gfx),
drawgfx(bitmap, cliprect, gfx,
code++,
color,
flipx, flipy,
@ -819,7 +839,7 @@ void ssv_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
}
/* Select 256 or 64 color tiles */
int gfx = (depth & 0x1000) ? 0 : 1;
int gfx = (depth & 0x7000) >>12;
int shadow = (depth & 0x8000);
/* Every single sprite is offset by x & yoffs, and additionally