Video System improvements. Further unification of the functions, improved rendering of players in 3on3dunk and promoted it to working, also further improves the sprites in twrldc94. From Haze (nw)

New games added or promoted from NOT_WORKING status
---------------------------------------------------
3 On 3 Dunk Madness (US, prototype? 1997/02/04)  [David Haywood, ShouTime, Smitdogg, The Dumping Union]
This commit is contained in:
Scott Stone 2012-10-13 13:29:27 +00:00
parent 538cc2b1af
commit 6f7f63b16a
6 changed files with 361 additions and 555 deletions

View File

@ -164,8 +164,8 @@ WRITE16_MEMBER(_3x3puzzle_state::tilemap1_scrolly_w)
void _3x3puzzle_state::video_start() void _3x3puzzle_state::video_start()
{ {
m_tilemap1 = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(_3x3puzzle_state::get_tile1_info),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32); m_tilemap1 = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(_3x3puzzle_state::get_tile1_info),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);
m_tilemap2 = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(_3x3puzzle_state::get_tile2_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_tilemap2 = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(_3x3puzzle_state::get_tile2_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_tilemap3 = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(_3x3puzzle_state::get_tile3_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 64); m_tilemap3 = &machine().tilemap().create(tilemap_get_info_delegate(FUNC(_3x3puzzle_state::get_tile3_info),this), TILEMAP_SCAN_ROWS, 8, 8, 64, 32);
m_tilemap2->set_transparent_pen(0); m_tilemap2->set_transparent_pen(0);
m_tilemap3->set_transparent_pen(0); m_tilemap3->set_transparent_pen(0);
} }

View File

@ -288,8 +288,7 @@ static ADDRESS_MAP_START( aerofgt_map, AS_PROGRAM, 16, aerofgt_state )
AM_RANGE(0x1b0ff0, 0x1b0fff) AM_RAM /* stack area during boot */ AM_RANGE(0x1b0ff0, 0x1b0fff) AM_RAM /* stack area during boot */
AM_RANGE(0x1b2000, 0x1b3fff) AM_RAM_WRITE(aerofgt_bg1videoram_w) AM_SHARE("bg1videoram") AM_RANGE(0x1b2000, 0x1b3fff) AM_RAM_WRITE(aerofgt_bg1videoram_w) AM_SHARE("bg1videoram")
AM_RANGE(0x1b4000, 0x1b5fff) AM_RAM_WRITE(aerofgt_bg2videoram_w) AM_SHARE("bg2videoram") AM_RANGE(0x1b4000, 0x1b5fff) AM_RAM_WRITE(aerofgt_bg2videoram_w) AM_SHARE("bg2videoram")
AM_RANGE(0x1c0000, 0x1c3fff) AM_RAM AM_SHARE("spriteram1") AM_RANGE(0x1c0000, 0x1c7fff) AM_RAM AM_SHARE("spriteram1")
AM_RANGE(0x1c4000, 0x1c7fff) AM_RAM AM_SHARE("spriteram2")
AM_RANGE(0x1d0000, 0x1d1fff) AM_RAM AM_SHARE("spriteram3") AM_RANGE(0x1d0000, 0x1d1fff) AM_RAM AM_SHARE("spriteram3")
AM_RANGE(0xfef000, 0xffefff) AM_RAM /* work RAM */ AM_RANGE(0xfef000, 0xffefff) AM_RAM /* work RAM */
AM_RANGE(0xffff80, 0xffff87) AM_WRITE(aerofgt_gfxbank_w) AM_RANGE(0xffff80, 0xffff87) AM_WRITE(aerofgt_gfxbank_w)
@ -1254,8 +1253,7 @@ GFXDECODE_END
static GFXDECODE_START( aerofgt ) static GFXDECODE_START( aerofgt )
GFXDECODE_ENTRY( "gfx1", 0, aerofgt_charlayout, 0, 16 ) GFXDECODE_ENTRY( "gfx1", 0, aerofgt_charlayout, 0, 16 )
GFXDECODE_ENTRY( "gfx1", 0, aerofgt_charlayout, 256, 16 ) GFXDECODE_ENTRY( "gfx1", 0, aerofgt_charlayout, 256, 16 )
GFXDECODE_ENTRY( "gfx2", 0, aerofgt_spritelayout, 512, 16 ) GFXDECODE_ENTRY( "gfx2", 0, aerofgt_spritelayout, 512, 32 )
GFXDECODE_ENTRY( "gfx3", 0, aerofgt_spritelayout, 768, 16 )
GFXDECODE_END GFXDECODE_END
static GFXDECODE_START( aerfboot ) static GFXDECODE_START( aerfboot )
@ -2321,11 +2319,9 @@ ROM_START( aerofgt )
ROM_LOAD( "538a54.124", 0x000000, 0x80000, CRC(4d2c4df2) SHA1(f51c2b3135f0a921ac1a79e63d6878c03cb6254b) ) ROM_LOAD( "538a54.124", 0x000000, 0x80000, CRC(4d2c4df2) SHA1(f51c2b3135f0a921ac1a79e63d6878c03cb6254b) )
ROM_LOAD( "1538a54.124", 0x080000, 0x80000, CRC(286d109e) SHA1(3a5f3d2d89cf58f6ef15e4bd3f570b84e8e695b2) ) ROM_LOAD( "1538a54.124", 0x080000, 0x80000, CRC(286d109e) SHA1(3a5f3d2d89cf58f6ef15e4bd3f570b84e8e695b2) )
ROM_REGION( 0x100000, "gfx2", 0 ) ROM_REGION( 0x400000, "gfx2", 0 )
ROM_LOAD( "538a53.u9", 0x000000, 0x100000, CRC(630d8e0b) SHA1(5a0c252ccd53c5199a695909d25ecb4e53dc15b9) ) ROM_LOAD( "538a53.u9", 0x000000, 0x100000, CRC(630d8e0b) SHA1(5a0c252ccd53c5199a695909d25ecb4e53dc15b9) )
ROM_LOAD( "534g8f.u18", 0x200000, 0x080000, CRC(76ce0926) SHA1(5ef4cec215d4dd600d8fcd1bd9a4c09081d59e33) )
ROM_REGION( 0x080000, "gfx3", 0 )
ROM_LOAD( "534g8f.u18", 0x000000, 0x80000, CRC(76ce0926) SHA1(5ef4cec215d4dd600d8fcd1bd9a4c09081d59e33) )
ROM_REGION( 0x40000, "ymsnd.deltat", 0 ) /* sound samples */ ROM_REGION( 0x40000, "ymsnd.deltat", 0 ) /* sound samples */
ROM_LOAD( "it-19-01", 0x00000, 0x40000, CRC(6d42723d) SHA1(57c59234e9925430a4c687733682efed06d7eed1) ) ROM_LOAD( "it-19-01", 0x00000, 0x40000, CRC(6d42723d) SHA1(57c59234e9925430a4c687733682efed06d7eed1) )

View File

@ -216,7 +216,7 @@ WRITE8_MEMBER(gstriker_state::gs_sh_bankswitch_w)
UINT8 *RAM = memregion("audiocpu")->base(); UINT8 *RAM = memregion("audiocpu")->base();
int bankaddress; int bankaddress;
bankaddress = 0x10000 + (data & 0x03) * 0x8000; bankaddress = (data & 0x07) * 0x8000;
membank("bank1")->set_base(&RAM[bankaddress]); membank("bank1")->set_base(&RAM[bankaddress]);
} }
@ -625,7 +625,6 @@ ROM_START( gstriker )
ROM_REGION( 0x40000, "audiocpu", 0 ) ROM_REGION( 0x40000, "audiocpu", 0 )
ROM_LOAD( "human-3_27c1001.u87", 0x00000, 0x20000, CRC(2f28c01e) SHA1(63829ad7969d197b2f2c87cb88bdb9e9880ed2d6) ) ROM_LOAD( "human-3_27c1001.u87", 0x00000, 0x20000, CRC(2f28c01e) SHA1(63829ad7969d197b2f2c87cb88bdb9e9880ed2d6) )
ROM_RELOAD( 0x10000, 0x20000 )
ROM_REGION( 0x20000, "gfx1", 0 ) // score tilemap ROM_REGION( 0x20000, "gfx1", 0 ) // score tilemap
ROM_LOAD( "human-2_27c1024.u79", 0x00000, 0x20000, CRC(a981993b) SHA1(ed92c7581d2b84a8628744dd5f8a2266c45dcd5b) ) ROM_LOAD( "human-2_27c1024.u79", 0x00000, 0x20000, CRC(a981993b) SHA1(ed92c7581d2b84a8628744dd5f8a2266c45dcd5b) )
@ -661,7 +660,6 @@ ROM_START( gstrikera )
ROM_REGION( 0x40000, "audiocpu", 0 ) ROM_REGION( 0x40000, "audiocpu", 0 )
ROM_LOAD( "human-3_27c1001.u87", 0x00000, 0x20000, CRC(2f28c01e) SHA1(63829ad7969d197b2f2c87cb88bdb9e9880ed2d6) ) ROM_LOAD( "human-3_27c1001.u87", 0x00000, 0x20000, CRC(2f28c01e) SHA1(63829ad7969d197b2f2c87cb88bdb9e9880ed2d6) )
ROM_RELOAD( 0x10000, 0x20000 )
ROM_REGION( 0x20000, "gfx1", 0 ) // score tilemap ROM_REGION( 0x20000, "gfx1", 0 ) // score tilemap
ROM_LOAD( "human-2_27c1024.u79", 0x00000, 0x20000, CRC(a981993b) SHA1(ed92c7581d2b84a8628744dd5f8a2266c45dcd5b) ) ROM_LOAD( "human-2_27c1024.u79", 0x00000, 0x20000, CRC(a981993b) SHA1(ed92c7581d2b84a8628744dd5f8a2266c45dcd5b) )

View File

@ -488,4 +488,4 @@ ROM_END
******************************************************************************/ ******************************************************************************/
GAME( 1998, inufuku, 0, inufuku, inufuku, driver_device, 0, ROT0, "Video System Co.", "Quiz & Variety Sukusuku Inufuku (Japan)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE ) GAME( 1998, inufuku, 0, inufuku, inufuku, driver_device, 0, ROT0, "Video System Co.", "Quiz & Variety Sukusuku Inufuku (Japan)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )
GAME( 1996, 3on3dunk, 0, _3on3dunk, inufuku, driver_device, 0, ROT0, "Video System Co.", "3 On 3 Dunk Madness (US, prototype?)", GAME_NOT_WORKING ) GAME( 1996, 3on3dunk, 0, _3on3dunk, inufuku, driver_device, 0, ROT0, "Video System Co.", "3 On 3 Dunk Madness (US, prototype? 1997/02/04)", GAME_NO_COCKTAIL | GAME_SUPPORTS_SAVE )

View File

@ -15,15 +15,103 @@
// Tecmo World Cup '94 // Tecmo World Cup '94
// Tao Taido // Tao Taido
/* old notes */
/*** Fujitsu CG10103 **********************************************/
/*
Fujitsu CG10103 sprite generator
--------------------------------
- Tile based
- 16x16 4bpp tiles
- Up to 7x7 in each block
- 5 bit of palette selection for the mixer
- Scaling (x/y)
- Flipping
- Indipendent sorting list
- 1 bit of pri for the mixer
Note that this chip can be connected to a VS9210 which adds a level of indirection for
tile numbers. Basically, the VS9210 indirects the tilet number through a table in its attached
memory, before accessing the ROMs.
Sorting list format (VideoRAM offset 0)
---------------------------------------
de-- ---f ssss ssss
e=end of list
f=sprite present in this position
s=sprite index
d=disable sprite?
TODO:
Priorities should be right, but they probably need to be orthogonal with the mixer priorities.
Zoom factor is not correct, the scale is probably non-linear
Horizontal wrapping is just a hack. The chip probably calculates if it needs to draw the sprite at the
normal position, or wrapped along X/Y.
Abstracts the VS9210
*/
#include "emu.h" #include "emu.h"
#include "vsystem_spr.h" #include "vsystem_spr.h"
/* game specific tile indirection callbacks for different HW hookups */
UINT32 inufuku_tile_callback( UINT32 code, UINT16* lookupram1, UINT16* lookupram2 )
{
return ((lookupram1[code*2] & 0x0007) << 16) + lookupram1[(code*2)+ 1];
}
UINT32 suprslam_tile_callback( UINT32 code, UINT16* lookupram1, UINT16* lookupram2 )
{
return lookupram1[code];
}
UINT32 crshrace_tile_callback( UINT32 code, UINT16* lookupram1, UINT16* lookupram2 )
{
return lookupram1[code&0x7fff];
}
UINT32 f1gp2_tile_callback( UINT32 code, UINT16* lookupram1, UINT16* lookupram2 )
{
return lookupram1[code&0x3fff];
}
UINT32 gstriker_tile_callback( UINT32 code, UINT16* lookupram1, UINT16* lookupram2 )
{
// straight through
return code;
}
UINT32 taotaido_tile_callback( UINT32 code, UINT16* lookupram1, UINT16* lookupram2 )
{
code = lookupram1[code&0x7fff];
if (code > 0x3fff)
{
int block = (code & 0x3800)>>11;
code &= 0x07ff;
code |= lookupram2[block] * 0x800;
}
return code;
}
const device_type VSYSTEM_SPR = &device_creator<vsystem_spr_device>; const device_type VSYSTEM_SPR = &device_creator<vsystem_spr_device>;
vsystem_spr_device::vsystem_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) vsystem_spr_device::vsystem_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, VSYSTEM_SPR, "vsystem_spr_device", tag, owner, clock) : device_t(mconfig, VSYSTEM_SPR, "vsystem_spr_device", tag, owner, clock)
{ {
m_CG10103.transpen = 15;
m_CG10103.pal_base = 0;
} }
@ -77,10 +165,91 @@ void vsystem_spr_device::get_sprite_attributes(UINT16* ram)
curr_sprite.map = (ram[2] & 0x0001) << 16; curr_sprite.map = (ram[2] & 0x0001) << 16;
curr_sprite.map |= (ram[3] & 0xffff); curr_sprite.map |= (ram[3] & 0xffff);
}
void vsystem_spr_device::common_sprite_drawgfx(int gfxrgn, UINT16* spriteram2, UINT16* spriteram3, vsystem_spr_tile_indirection_callback tilecb, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
gfx_element *gfx = machine.gfx[gfxrgn];
curr_sprite.zoomx = 32 - curr_sprite.zoomx;
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
int ystart, yend, yinc;
if (!curr_sprite.flipy) { ystart = 0; yend = curr_sprite.ysize+1; yinc = 1; }
else { ystart = curr_sprite.ysize; yend = -1; yinc = -1; }
int ycnt = ystart;
while (ycnt != yend)
{
int xstart, xend, xinc;
if (!curr_sprite.flipx) { xstart = 0; xend = curr_sprite.xsize+1; xinc = 1; }
else { xstart = curr_sprite.xsize; xend = -1; xinc = -1; }
int xcnt = xstart;
while (xcnt != xend)
{
int startno = tilecb(curr_sprite.map++, spriteram2, spriteram3);
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_CG10103.transpen);
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_CG10103.transpen);
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_CG10103.transpen);
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, m_CG10103.transpen);
xcnt+=xinc;
}
ycnt+=yinc;
}
} }
// zooming is wrong for 3on3dunk ... suprslam implementation is probably better // same as above but for pdrawgfx implementations
void vsystem_spr_device::common_sprite_pdrawgfx(int gfxrgn, UINT16* spriteram2, UINT16* spriteram3, vsystem_spr_tile_indirection_callback tilecb, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
gfx_element *gfx = machine.gfx[gfxrgn];
int priority_mask;
switch (curr_sprite.pri)
{
default:
case 0: priority_mask = 0x00; break;
case 3: priority_mask = 0xfe; break;
case 2: priority_mask = 0xfc; break;
case 1: priority_mask = 0xf0; break;
}
curr_sprite.zoomx = 32 - curr_sprite.zoomx;
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
int ystart, yend, yinc;
if (!curr_sprite.flipy) { ystart = 0; yend = curr_sprite.ysize+1; yinc = 1; }
else { ystart = curr_sprite.ysize; yend = -1; yinc = -1; }
int ycnt = ystart;
while (ycnt != yend)
{
int xstart, xend, xinc;
if (!curr_sprite.flipx) { xstart = 0; xend = curr_sprite.xsize+1; xinc = 1; }
else { xstart = curr_sprite.xsize; xend = -1; xinc = -1; }
int xcnt = xstart;
while (xcnt != xend)
{
int startno = tilecb(curr_sprite.map++, spriteram2, spriteram3);
pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_CG10103.transpen);
pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_CG10103.transpen);
pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_CG10103.transpen);
pdrawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color + m_CG10103.pal_base, curr_sprite.flipx, curr_sprite.flipy, -0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, -0x200+curr_sprite.oy + ycnt * curr_sprite.zoomy/2, curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, machine.priority_bitmap,priority_mask, m_CG10103.transpen);
xcnt+=xinc;
}
ycnt+=yinc;
}
}
void vsystem_spr_device::draw_sprites_inufuku( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) void vsystem_spr_device::draw_sprites_inufuku( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
{ {
int offs; int offs;
@ -97,72 +266,22 @@ void vsystem_spr_device::draw_sprites_inufuku( UINT16* spriteram, int spriteram_
if ((spriteram[offs] & 0x8000) == 0x0000) if ((spriteram[offs] & 0x8000) == 0x0000)
{ {
int attr_start; int attr_start;
int x, y;
int priority_mask;
attr_start = 4 * (spriteram[offs] & 0x03ff); attr_start = 4 * (spriteram[offs] & 0x03ff);
get_sprite_attributes(&spriteram[attr_start]); get_sprite_attributes(&spriteram[attr_start]);
curr_sprite.oy += 1; // curr_sprite.oy += 1;
curr_sprite.map &= 0x7fff; curr_sprite.map &= 0x7fff;
switch (curr_sprite.pri) common_sprite_pdrawgfx(2, spriteram2, NULL, inufuku_tile_callback, machine, bitmap, cliprect);
{
default:
case 0: priority_mask = 0x00; break;
case 3: priority_mask = 0xfe; break;
case 2: priority_mask = 0xfc; break;
case 1: priority_mask = 0xf0; break;
}
curr_sprite.ox += (curr_sprite.xsize * curr_sprite.zoomx + 2) / 4;
curr_sprite.oy += (curr_sprite.ysize * curr_sprite.zoomy + 2) / 4;
curr_sprite.zoomx = 32 - curr_sprite.zoomx;
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
for (y = 0; y <= curr_sprite.ysize; y++)
{
int sx, sy;
if (curr_sprite.flipy)
sy = (curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y) / 2 + 16) & 0x1ff;
else
sy = (curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff;
for (x = 0; x <= curr_sprite.xsize; x++)
{
int code;
if (curr_sprite.flipx)
sx = (curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff;
else
sx = (curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff;
code = ((spriteram2[curr_sprite.map*2] & 0x0007) << 16) + spriteram2[(curr_sprite.map*2)+ 1];
pdrawgfxzoom_transpen(bitmap, cliprect, machine.gfx[2],
code,
curr_sprite.color,
curr_sprite.flipx, curr_sprite.flipy,
sx - 16, sy - 16,
curr_sprite.zoomx << 11, curr_sprite.zoomy << 11,
machine.priority_bitmap,priority_mask, 15);
curr_sprite.map ++;
}
}
} }
} }
} }
/* todo, fix zooming correctly, it's _not_ like aerofgt */
void vsystem_spr_device::draw_sprites_suprslam( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) void vsystem_spr_device::draw_sprites_suprslam( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
{ {
gfx_element *gfx = machine.gfx[1];
UINT16 *source = spriteram; UINT16 *source = spriteram;
UINT16 *source2 = spriteram; UINT16 *source2 = spriteram;
UINT16 *finish = source + 0x2000/2; UINT16 *finish = source + 0x2000/2;
@ -171,49 +290,15 @@ void vsystem_spr_device::draw_sprites_suprslam( UINT16* spriteram, int spriteram
{ {
UINT32 sprnum = source[0] & 0x03ff; UINT32 sprnum = source[0] & 0x03ff;
if (source[0] == 0x4000) break; if (source[0] == 0x4000) break;
sprnum *= 4; sprnum *= 4;
source++; source++;
/* DRAW START */
{
get_sprite_attributes(&source2[sprnum]); get_sprite_attributes(&source2[sprnum]);
curr_sprite.map &= 0x7fff; curr_sprite.map &= 0x7fff;
int xcnt, ycnt; common_sprite_drawgfx(1, spriteram2, NULL, suprslam_tile_callback, machine, bitmap, cliprect);
int loopno = 0;
curr_sprite.zoomx = 32 - curr_sprite.zoomx;
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
if (curr_sprite.oy > 0xff) curr_sprite.oy -=0x200;
for (ycnt = 0; ycnt < curr_sprite.ysize+1; ycnt ++)
{
if (!curr_sprite.flipx)
{
for (xcnt = 0; xcnt < curr_sprite.xsize+1; xcnt ++)
{
int startno = spriteram2[curr_sprite.map + loopno];
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 0, 0,curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15);
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 0, 0,-0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15);
loopno ++;
}
}
else
{
for (xcnt = curr_sprite.xsize; xcnt >= 0; xcnt --)
{
int startno = spriteram2[curr_sprite.map + loopno];
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 1, 0,curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15);
drawgfxzoom_transpen(bitmap, cliprect, gfx, startno, curr_sprite.color, 1, 0,-0x200+curr_sprite.ox + xcnt * curr_sprite.zoomx/2, curr_sprite.oy + ycnt * curr_sprite.zoomy/2,curr_sprite.zoomx << 11, curr_sprite.zoomy << 11, 15);
loopno ++;
}
}
}
}
} }
} }
@ -221,74 +306,14 @@ void vsystem_spr_device::draw_sprites_suprslam( UINT16* spriteram, int spriteram
void vsystem_spr_device::draw_sprite_taotaido( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, UINT16* spriteram3, running_machine &machine, UINT16 spriteno, bitmap_ind16 &bitmap, const rectangle &cliprect ) void vsystem_spr_device::draw_sprite_taotaido( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, UINT16* spriteram3, running_machine &machine, UINT16 spriteno, bitmap_ind16 &bitmap, const rectangle &cliprect )
{ {
/*- SPR RAM Format -**
4 words per sprite
zzzz sssp pppp pppp (y zoom, y size, y position)
zzzz sssp pppp pppp (x zoom, x size, x position)
yxpc cccc ---- ---- (flipy, >flipx, priority?, color)
-nnn nnnn nnnn nnnn (map_start lookup)
*/
int x,y;
UINT16 *source = &spriteram[spriteno*4]; UINT16 *source = &spriteram[spriteno*4];
gfx_element *gfx = machine.gfx[0];
get_sprite_attributes(&source[0]); get_sprite_attributes(&source[0]);
curr_sprite.map &= 0xffff; curr_sprite.map &= 0xffff;
curr_sprite.color &= 0x1f; curr_sprite.color &= 0x1f;
curr_sprite.ox += (curr_sprite.xsize*curr_sprite.zoomx+2)/4; common_sprite_drawgfx(0, spriteram2, spriteram3, taotaido_tile_callback, machine, bitmap, cliprect);
curr_sprite.oy += (curr_sprite.ysize*curr_sprite.zoomy+2)/4;
curr_sprite.zoomx = 32 - curr_sprite.zoomx;
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
for (y = 0;y <= curr_sprite.ysize;y++)
{
int sx,sy;
if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16;
else sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16;
for (x = 0;x <= curr_sprite.xsize;x++)
{
/* this indirection is a bit different to the other video system games */
int realstart;
realstart = spriteram2[curr_sprite.map&0x7fff];
if (realstart > 0x3fff)
{
int block;
block = (realstart & 0x3800)>>11;
realstart &= 0x07ff;
realstart |= spriteram3[block] * 0x800;
}
if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16;
else sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16;
drawgfxzoom_transpen(bitmap,cliprect,gfx,
realstart,
curr_sprite.color,
curr_sprite.flipx,curr_sprite.flipy,
sx,sy,
curr_sprite.zoomx << 11, curr_sprite.zoomy << 11,15);
curr_sprite.map++;
}
}
} }
void vsystem_spr_device::draw_sprites_taotaido( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, UINT16* spriteram3, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ) void vsystem_spr_device::draw_sprites_taotaido( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, UINT16* spriteram3, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect )
@ -316,10 +341,6 @@ void vsystem_spr_device::draw_sprites_crshrace(UINT16* spriteram, int spriteram_
while (offs < 0x0400 && (spriteram[offs] & 0x4000) == 0) while (offs < 0x0400 && (spriteram[offs] & 0x4000) == 0)
{ {
int attr_start; int attr_start;
int x, y;
/* table hand made by looking at the ship explosion in aerofgt attract mode */
/* it's almost a logarithmic scale but not exactly */
static const int zoomtable[16] = { 0,7,14,20,25,30,34,38,42,46,49,52,54,57,59,61 };
attr_start = 4 * (spriteram[offs++] & 0x03ff); attr_start = 4 * (spriteram[offs++] & 0x03ff);
@ -328,44 +349,7 @@ void vsystem_spr_device::draw_sprites_crshrace(UINT16* spriteram, int spriteram_
curr_sprite.color &= 0x1f; curr_sprite.color &= 0x1f;
curr_sprite.map &= 0x7fff; curr_sprite.map &= 0x7fff;
curr_sprite.zoomx = 16 - zoomtable[curr_sprite.zoomx] / 8; common_sprite_drawgfx(2, spriteram2, NULL, crshrace_tile_callback, machine, bitmap, cliprect);
curr_sprite.zoomy = 16 - zoomtable[curr_sprite.zoomy] / 8;
if (spriteram[attr_start + 2] & 0x20ff) curr_sprite.color = machine.rand();
for (y = 0; y <= curr_sprite.ysize; y++)
{
int sx,sy;
if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y) + 16) & 0x1ff) - 16;
else sy = ((curr_sprite.oy + curr_sprite.zoomy * y + 16) & 0x1ff) - 16;
for (x = 0; x <= curr_sprite.xsize; x++)
{
int code;
if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) + 16) & 0x1ff) - 16;
else sx = ((curr_sprite.ox + curr_sprite.zoomx * x + 16) & 0x1ff) - 16;
code = spriteram2[curr_sprite.map & 0x7fff];
curr_sprite.map++;
if (flipscreen)
drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2],
code,
curr_sprite.color,
!curr_sprite.flipx,!curr_sprite.flipy,
304-sx,208-sy,
0x1000 * curr_sprite.zoomx,0x1000 * curr_sprite.zoomy,15);
else
drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2],
code,
curr_sprite.color,
curr_sprite.flipx,curr_sprite.flipy,
sx,sy,
0x1000 * curr_sprite.zoomx,0x1000 * curr_sprite.zoomy,15);
}
}
} }
} }
@ -384,50 +368,13 @@ void vsystem_spr_device::draw_sprites_aerofght( UINT16* spriteram3, int spritera
/* is the way I handle pri correct? Or should I just check bit 13? */ /* is the way I handle pri correct? Or should I just check bit 13? */
if ((spriteram3[attr_start + 2] & 0x3000) == pri) if ((spriteram3[attr_start + 2] & 0x3000) == pri)
{ {
int x, y;
get_sprite_attributes(&spriteram3[attr_start]); get_sprite_attributes(&spriteram3[attr_start]);
curr_sprite.color &=0xf; curr_sprite.color &=0x1f;
curr_sprite.map &= 0x3fff; curr_sprite.map &= 0x3fff;
curr_sprite.ox += (curr_sprite.xsize * curr_sprite.zoomx + 2) / 4;
curr_sprite.oy += (curr_sprite.ysize * curr_sprite.zoomy + 2) / 4;
curr_sprite.zoomx = 32 - curr_sprite.zoomx; common_sprite_drawgfx(2, spriteram1, NULL, crshrace_tile_callback, machine, bitmap, cliprect);
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
for (y = 0; y <= curr_sprite.ysize; y++)
{
int sx, sy;
if (curr_sprite.flipy)
sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16;
else
sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16;
for (x = 0; x <= curr_sprite.xsize; x++)
{
int code;
if (curr_sprite.flipx)
sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16;
else
sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16;
if (curr_sprite.map < 0x2000)
code = spriteram1[curr_sprite.map & 0x1fff] & 0x1fff;
else
code = spriteram2[curr_sprite.map & 0x1fff] & 0x1fff;
drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[2 + (curr_sprite.map >= 0x2000 ? 1 : 0)],
code,
curr_sprite.color,
curr_sprite.flipx,curr_sprite.flipy,
sx,sy,
curr_sprite.zoomx << 11, curr_sprite.zoomy << 11,15);
curr_sprite.map++;
}
}
} }
offs++; offs++;
} }
@ -442,7 +389,6 @@ void vsystem_spr_device::f1gp2_draw_sprites(UINT16* spritelist, UINT16* sprcgram
while (offs < 0x0400 && (spritelist[offs] & 0x4000) == 0) while (offs < 0x0400 && (spritelist[offs] & 0x4000) == 0)
{ {
int attr_start; int attr_start;
int x, y;
attr_start = 4 * (spritelist[offs++] & 0x01ff); attr_start = 4 * (spritelist[offs++] & 0x01ff);
@ -451,157 +397,22 @@ void vsystem_spr_device::f1gp2_draw_sprites(UINT16* spritelist, UINT16* sprcgram
curr_sprite.color &= 0x1f; curr_sprite.color &= 0x1f;
curr_sprite.map &= 0x7fff; curr_sprite.map &= 0x7fff;
// aerofgt has the following adjustment, but doing it here would break the title screen common_sprite_drawgfx(1, sprcgram, NULL, f1gp2_tile_callback, machine, bitmap, cliprect);
// curr_sprite.ox += (curr_sprite.xsize*curr_sprite.zoomx+2)/4;
// curr_sprite.oy += (curr_sprite.ysize*curr_sprite.zoomy+2)/4;
curr_sprite.zoomx = 32 - curr_sprite.zoomx;
curr_sprite.zoomy = 32 - curr_sprite.zoomy;
if (spritelist[attr_start + 2] & 0x20ff)
curr_sprite.color = machine.rand();
for (y = 0; y <= curr_sprite.ysize; y++)
{
int sx,sy;
if (curr_sprite.flipy) sy = ((curr_sprite.oy + curr_sprite.zoomy * (curr_sprite.ysize - y)/2 + 16) & 0x1ff) - 16;
else sy = ((curr_sprite.oy + curr_sprite.zoomy * y / 2 + 16) & 0x1ff) - 16;
for (x = 0; x <= curr_sprite.xsize; x++)
{
int code;
if (curr_sprite.flipx) sx = ((curr_sprite.ox + curr_sprite.zoomx * (curr_sprite.xsize - x) / 2 + 16) & 0x1ff) - 16;
else sx = ((curr_sprite.ox + curr_sprite.zoomx * x / 2 + 16) & 0x1ff) - 16;
code = sprcgram[curr_sprite.map & 0x3fff];
curr_sprite.map++;
if (flipscreen)
drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1],
code,
curr_sprite.color,
!curr_sprite.flipx,!curr_sprite.flipy,
304-sx,208-sy,
curr_sprite.zoomx << 11,curr_sprite.zoomy << 11,15);
else
drawgfxzoom_transpen(bitmap,cliprect,machine.gfx[1],
code,
curr_sprite.color,
curr_sprite.flipx,curr_sprite.flipy,
sx,sy,
curr_sprite.zoomx << 11,curr_sprite.zoomy << 11,15);
}
}
} }
} }
/*** Fujitsu CG10103 **********************************************/ void vsystem_spr_device::CG10103_draw_sprite(running_machine &machine, bitmap_ind16& bitmap, const rectangle &cliprect, UINT16* spr, int drawpri)
/*
Fujitsu CG10103 sprite generator
--------------------------------
- Tile based
- 16x16 4bpp tiles
- Up to 7x7 in each block
- 5 bit of palette selection for the mixer
- Scaling (x/y)
- Flipping
- Indipendent sorting list
- 1 bit of pri for the mixer
Note that this chip can be connected to a VS9210 which adds a level of indirection for
tile numbers. Basically, the VS9210 indirects the tilet number through a table in its attached
memory, before accessing the ROMs.
Sorting list format (VideoRAM offset 0)
---------------------------------------
de-- ---f ssss ssss
e=end of list
f=sprite present in this position
s=sprite index
d=disable sprite?
TODO:
Priorities should be right, but they probably need to be orthogonal with the mixer priorities.
Zoom factor is not correct, the scale is probably non-linear
Horizontal wrapping is just a hack. The chip probably calculates if it needs to draw the sprite at the
normal position, or wrapped along X/Y.
Abstracts the VS9210
*/
void vsystem_spr_device::CG10103_draw_sprite(running_machine &machine, bitmap_ind16& screen, const rectangle &cliprect, UINT16* spr, int drawpri)
{ {
get_sprite_attributes(&spr[0]); get_sprite_attributes(&spr[0]);
curr_sprite.color &=0x1f; curr_sprite.color &=0x1f;
curr_sprite.pri >>= 1; curr_sprite.pri >>= 1;
int x, y;
int xstep, ystep;
int xfact, yfact;
// Check if we want to draw this sprite now // Check if we want to draw this sprite now
if (curr_sprite.pri != drawpri) if (curr_sprite.pri != drawpri)
return; return;
// Convert in fixed point to handle the scaling common_sprite_drawgfx(m_CG10103.gfx_region, NULL, NULL, gstriker_tile_callback, machine, bitmap, cliprect);
curr_sprite.ox <<= 16;
curr_sprite.oy <<= 16;
curr_sprite.xsize++;
curr_sprite.ysize++;
xstep = ystep = 16;
// Linear scale, surely wrong
xfact = 0x10000 - ((0x8000 * curr_sprite.zoomx) / 15);
yfact = 0x10000 - ((0x8000 * curr_sprite.zoomy) / 15);
xstep *= xfact;
ystep *= yfact;
// Handle flipping
if (curr_sprite.flipy)
{
curr_sprite.oy += (curr_sprite.ysize-1) * ystep;
ystep = -ystep;
}
if (curr_sprite.flipx)
{
curr_sprite.ox += (curr_sprite.xsize-1) * xstep;
xstep = -xstep;
}
// Draw the block
for (y=0;y<curr_sprite.ysize;y++)
{
int xp = curr_sprite.ox;
for (x=0;x<curr_sprite.xsize;x++)
{
// Hack to handle horizontal wrapping
drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, xp>>16, curr_sprite.oy>>16, xfact, yfact, m_CG10103_cur_chip->transpen);
drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, (xp>>16) - 0x200, curr_sprite.oy>>16, xfact, yfact, m_CG10103_cur_chip->transpen);
drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, xp>>16, (curr_sprite.oy>>16)-0x200, xfact, yfact, m_CG10103_cur_chip->transpen);
drawgfxzoom_transpen(screen, cliprect, machine.gfx[m_CG10103_cur_chip->gfx_region], curr_sprite.map, curr_sprite.color+m_CG10103_cur_chip->pal_base, curr_sprite.flipx, curr_sprite.flipy, (xp>>16) - 0x200, (curr_sprite.oy>>16)-0x200, xfact, yfact, m_CG10103_cur_chip->transpen);
xp += xstep;
curr_sprite.map++;
}
curr_sprite.oy += ystep;
}
} }
@ -610,9 +421,7 @@ void vsystem_spr_device::CG10103_draw(running_machine &machine, int numchip, bit
UINT16* splist; UINT16* splist;
int i; int i;
m_CG10103_cur_chip = &m_CG10103; splist = m_CG10103.vram;
splist = m_CG10103_cur_chip->vram;
// Parse the sorting list // Parse the sorting list
for (i=0;i<0x400;i++) for (i=0;i<0x400;i++)
@ -629,7 +438,7 @@ void vsystem_spr_device::CG10103_draw(running_machine &machine, int numchip, bit
int num = cmd & 0x3FF; int num = cmd & 0x3FF;
// Draw the sprite // Draw the sprite
CG10103_draw_sprite(machine, screen, cliprect, m_CG10103_cur_chip->vram + num*4, pri); CG10103_draw_sprite(machine, screen, cliprect, m_CG10103.vram + num*4, pri);
} }
} }
} }

View File

@ -13,13 +13,14 @@ struct tCG10103
}; };
typedef UINT32 (*vsystem_spr_tile_indirection_callback)(UINT32 code, UINT16* lookupram1, UINT16* lookupram2);
class vsystem_spr_device : public device_t class vsystem_spr_device : public device_t
{ {
public: public:
vsystem_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); vsystem_spr_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
tCG10103 m_CG10103; tCG10103 m_CG10103;
tCG10103* m_CG10103_cur_chip;
struct vsystem_sprite_attributes struct vsystem_sprite_attributes
{ {
@ -37,6 +38,8 @@ public:
} curr_sprite; } curr_sprite;
void get_sprite_attributes(UINT16* ram); void get_sprite_attributes(UINT16* ram);
void common_sprite_drawgfx(int gfxrgn, UINT16* spriteram2, UINT16* spriteram3, vsystem_spr_tile_indirection_callback tilecb, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect);
void common_sprite_pdrawgfx(int gfxrgn, UINT16* spriteram2, UINT16* spriteram3, vsystem_spr_tile_indirection_callback tilecb, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect);
void draw_sprites_inufuku( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ); void draw_sprites_inufuku( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect );
void draw_sprites_suprslam( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect ); void draw_sprites_suprslam( UINT16* spriteram, int spriteram_bytes, UINT16* spriteram2, running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect );