Converted wizdfire to use generic deco functions [David Haywood]

This commit is contained in:
Angelo Salese 2012-01-28 15:37:24 +00:00
parent 689c16a4b5
commit d1c6a3b04d
6 changed files with 140 additions and 319 deletions

View File

@ -1076,6 +1076,9 @@ static MACHINE_CONFIG_START( edrandy, cninja_state )
MCFG_TIMER_ADD("raster_timer", interrupt_gen) MCFG_TIMER_ADD("raster_timer", interrupt_gen)
// to force a partial update every line, fixes clouds in 2nd attract demo
MCFG_TIMER_ADD_SCANLINE("scantimer", deco16_scantimer, "screen", 0, 1)
/* video hardware */ /* video hardware */
MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM) MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM)

View File

@ -113,6 +113,7 @@
#include "sound/2151intf.h" #include "sound/2151intf.h"
#include "sound/okim6295.h" #include "sound/okim6295.h"
#include "video/decocomn.h" #include "video/decocomn.h"
#include "video/decospr.h"
static READ16_HANDLER( rohga_irq_ack_r ) static READ16_HANDLER( rohga_irq_ack_r )
{ {
@ -707,8 +708,8 @@ static GFXDECODE_START( wizdfire )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 32 ) /* Gfx chip 1 as 8x8 */ GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 32 ) /* Gfx chip 1 as 8x8 */
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 32 ) /* Gfx chip 1 as 16x16 */ GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 32 ) /* Gfx chip 1 as 16x16 */
GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 512, 32 ) /* Gfx chip 2 as 16x16 */ GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 512, 32 ) /* Gfx chip 2 as 16x16 */
GFXDECODE_ENTRY( "gfx4", 0, spritelayout, 1024, 32 ) /* Sprites 16x16 */ GFXDECODE_ENTRY( "gfx4", 0, spritelayout, 0, 32 ) /* Sprites 16x16 */
GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 1536, 32 ) GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 0, 32 )
GFXDECODE_END GFXDECODE_END
static GFXDECODE_START( schmeisr ) static GFXDECODE_START( schmeisr )
@ -874,6 +875,14 @@ static MACHINE_CONFIG_START( wizdfire, rohga_state )
MCFG_DECO16IC_ADD("tilegen1", rohga_deco16ic_tilegen1_intf) MCFG_DECO16IC_ADD("tilegen1", rohga_deco16ic_tilegen1_intf)
MCFG_DECO16IC_ADD("tilegen2", rohga_deco16ic_tilegen2_intf) MCFG_DECO16IC_ADD("tilegen2", rohga_deco16ic_tilegen2_intf)
MCFG_DEVICE_ADD("spritegen1", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 3);
MCFG_DEVICE_ADD("spritegen2", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 4);
MCFG_VIDEO_START(wizdfire)
/* sound hardware */ /* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
@ -919,6 +928,14 @@ static MACHINE_CONFIG_START( nitrobal, rohga_state )
MCFG_DECO16IC_ADD("tilegen1", nitrobal_deco16ic_tilegen1_intf) MCFG_DECO16IC_ADD("tilegen1", nitrobal_deco16ic_tilegen1_intf)
MCFG_DECO16IC_ADD("tilegen2", nitrobal_deco16ic_tilegen2_intf) MCFG_DECO16IC_ADD("tilegen2", nitrobal_deco16ic_tilegen2_intf)
MCFG_DEVICE_ADD("spritegen1", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 3);
MCFG_DEVICE_ADD("spritegen2", DECO_SPRITE, 0)
decospr_device::set_gfx_region(*device, 4);
MCFG_VIDEO_START(wizdfire)
/* sound hardware */ /* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")

View File

@ -45,6 +45,7 @@ public:
WRITE16_HANDLER( rohga_buffer_spriteram16_w ); WRITE16_HANDLER( rohga_buffer_spriteram16_w );
VIDEO_START( rohga ); VIDEO_START( rohga );
VIDEO_START( wizdfire );
SCREEN_UPDATE_IND16( rohga ); SCREEN_UPDATE_IND16( rohga );
SCREEN_UPDATE_IND16( schmeisr ); SCREEN_UPDATE_IND16( schmeisr );

View File

@ -345,6 +345,13 @@ static TILE_GET_INFO_DEVICE( get_pf1_tile_info_b )
flags); flags);
} }
TIMER_DEVICE_CALLBACK( deco16_scantimer )
{
int scanline = param;
timer.machine().primary_screen->update_partial(scanline);
}
/*****************************************************************************************/ /*****************************************************************************************/
/* /*

View File

@ -96,4 +96,6 @@ void deco16ic_set_scrolldx(device_t *device, int tmap, int size, int dx, int dx_
/* used by cninjabl */ /* used by cninjabl */
void deco16ic_set_enable( device_t *device, int tmap, int enable ); void deco16ic_set_enable( device_t *device, int tmap, int enable );
TIMER_DEVICE_CALLBACK( deco16_scantimer );
#endif #endif

View File

@ -7,7 +7,7 @@
#include "emu.h" #include "emu.h"
#include "includes/rohga.h" #include "includes/rohga.h"
#include "video/deco16ic.h" #include "video/deco16ic.h"
#include "video/decospr.h"
WRITE16_HANDLER( rohga_buffer_spriteram16_w ) WRITE16_HANDLER( rohga_buffer_spriteram16_w )
{ {
@ -109,314 +109,6 @@ static void rohga_draw_sprites( running_machine &machine, bitmap_ind16 &bitmap,
} }
} }
static void wizdfire_draw_sprites( running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16 *spriteptr, int mode, int bank )
{
int offs;
for (offs = 0; offs < 0x400; offs += 4)
{
int x, y, sprite, colour, multi, fx, fy, inc, flash, mult;
int alpha = 0xff;
sprite = spriteptr[offs + 1];
if (!sprite)
continue;
x = spriteptr[offs + 2];
/*
Sprite/playfield priority - we can't use pdrawgfx because we need alpha'd sprites overlaid
over non-alpha'd sprites, plus sprites underneath and above an alpha'd background layer.
Hence, we rely on the hardware sorting everything correctly and not relying on any orthoganality
effects (it doesn't seem to), and instead draw separate passes for each sprite priority. :(
*/
switch (mode)
{
case 4:
if ((x & 0xc000) != 0xc000)
continue;
break;
case 3:
if ((x & 0xc000) != 0x8000)
continue;
break;
case 2:
if ((x & 0x8000) != 0x8000)
continue;
break;
case 1:
case 0:
default:
if ((x & 0x8000) != 0)
continue;
break;
}
y = spriteptr[offs];
flash = y & 0x1000;
if (flash && (machine.primary_screen->frame_number() & 1))
continue;
colour = (x >> 9) & 0x1f;
if (bank == 4 && colour & 0x10)
{
alpha = 0x80;
colour &= 0xf;
}
fx = y & 0x2000;
fy = y & 0x4000;
multi = (1 << ((y & 0x0600) >> 9)) - 1; /* 1x, 2x, 4x, 8x height */
x = x & 0x01ff;
y = y & 0x01ff;
if (x >= 320) x -= 512;
if (y >= 256) y -= 512;
sprite &= ~multi;
if (fy)
inc = -1;
else
{
sprite += multi;
inc = 1;
}
if (flip_screen_get(machine))
{
x = 304 - x;
y = 240 - y;
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
mult = -16;
}
else
mult = +16;
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
while (multi >= 0)
{
drawgfx_alpha(bitmap,cliprect,machine.gfx[bank],
sprite - multi * inc,
colour,
fx,fy,
x,y + mult * multi,
0,alpha);
multi--;
}
}
}
static void nitrobal_draw_sprites( running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, const UINT16 *spriteptr, int gfxbank )
{
rohga_state *state = machine.driver_data<rohga_state>();
int offs, end, inc;
UINT16 priority = decocomn_priority_r(state->m_decocomn, 0, 0xffff);
/*
Alternate format from most 16 bit games - same as Captain America and Mutant Fighter
Word 0:
0x8000: Y flip
0x4000: X flip
0x2000: Flash (Sprite toggles on/off every frame)
0x1fff: Y value
Word 1:
0xffff: X value
Word 2:
0xf000: Block height
0x0f00: Block width
0x00e0: Unused?
sprites1:
bit 0x40 set for under PF2
bit 0x20 set on others...
bit 0x80 set in game pf3 (split)
Sprites 2:
bit 0x10 set on alpha sprites..
bit 0x80 set is above pf2 else under pf2
0x001f: Colour
Word 3:
0xffff: Sprite value
*/
offs = 0x3fc;
end = -4;
inc = -4;
while (offs != end)
{
int x, y, sprite, colour, fx, fy, w, h, sx, sy, x_mult, y_mult, tilemap_pri, sprite_pri;
int alpha = 0xff;
sprite = spriteptr[offs + 3];
if (!sprite)
{
offs += inc;
continue;
}
sx = spriteptr[offs + 1];
h = (spriteptr[offs + 2] & 0xf000) >> 12;
w = (spriteptr[offs + 2] & 0x0f00) >> 8;
sy = spriteptr[offs];
if ((sy & 0x2000) && (machine.primary_screen->frame_number() & 1))
{
offs += inc;
continue;
}
colour = (spriteptr[offs + 2] >> 0) & 0x1f;
// PRIORITIES - TODO
if (gfxbank == 3)
{
/* Sprite chip 1 */
switch (spriteptr[offs + 2] & 0xe0)
{
// case 0xc0: colour = rand()%0xff; tilemap_pri = 256; break; //todo
case 0xc0: tilemap_pri = 8; break; //? under other sprites
case 0x80: tilemap_pri = 32; break; //? under other sprites
case 0x20: tilemap_pri = 32; break; /* Over pf2 and under other sprite chip */
case 0x40: tilemap_pri = 8; break; /* Under pf2 and under other sprite chip */
case 0xa0: tilemap_pri = 32; break;
case 0:
tilemap_pri = 128; break;
default:
tilemap_pri = 128;
break;
}
/*
Intro:
0x40 is under pf2 and other sprites
0x20 is under pf2
Level 1
0xa0 means under other sprites and pf2?
Level 2 (tank scene)
Chip 1:
0x20 set means under pf2 else above??
0x80 set means under other sprites else above
Level 3:
0xc0 means under other sprites and pf2 check??
0x40 means under pf2
0xa0 means under pf2..
always over other sprites..?
PRI MODE 2: (Level 4)
sprite 1:
mode 0xa0 is under pf2 (sprites unknown)
mode 0x40 is under pf2 (sprites unknown)
sprite 2:
mode 0x40 is under pf2
mode 0 is under pf2
Level 5 (Space, pri mode 1)
sprite 1:
mode 0x80 is over pf2 and over other sprites
sprite 2:
mode 0 is over pf2
*/
sprite_pri = 1;
}
else
{
/* Sprite chip 2 (with alpha blending) */
/* Sprite above playfield 2, but still below other sprite chip */
// if (spriteptr[offs + 2] & 0x80)
tilemap_pri = 64;
// else
// tilemap_pri = 8;
if (priority)
tilemap_pri = 8;
else
tilemap_pri = 64;
sprite_pri = 2;
}
if (gfxbank == 4 && colour & 0x10)
{
alpha = 0x80;
colour &= 0xf;
}
fx = (spriteptr[offs + 0] & 0x4000);
fy = (spriteptr[offs + 0] & 0x8000);
if (!flip_screen_get(machine))
{ /* Inverted from Mutant Fighter! */
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
sx = sx & 0x01ff;
sy = sy & 0x01ff;
if (sx > 0x180) sx = -(0x200 - sx);
if (sy > 0x180) sy = -(0x200 - sy);
if (fx) { x_mult = -16; sx += 16 * w; } else { x_mult = 16; sx -= 16; }
if (fy) { y_mult = -16; sy += 16 * h; } else { y_mult = 16; sy -= 16; }
}
else
{
sx = sx & 0x01ff;
sy = sy & 0x01ff;
if (sx & 0x100) sx = -(0x100 - (sx & 0xff));
if (sy & 0x100) sy = -(0x100 - (sy & 0xff));
sx = 304 - sx;
sy = 240 - sy;
if (sx >= 432) sx -= 512;
if (sy >= 384) sy -= 512;
if (fx) { x_mult = -16; sx += 16; } else { x_mult = 16; sx -= 16 * w; }
if (fy) { y_mult = -16; sy += 16; } else { y_mult = 16; sy -= 16 * h; }
}
for (x = 0; x < w; x++)
{
for (y = 0; y < h; y++)
{
decocomn_pdrawgfx(
state->m_decocomn,
bitmap,cliprect,machine.gfx[gfxbank],
sprite + y + h * x,
colour,
fx,fy,
sx + x_mult * (w-x),sy + y_mult * (h-y),
0,tilemap_pri,sprite_pri,1,alpha);
}
}
offs += inc;
}
}
/******************************************************************************/ /******************************************************************************/
static void update_rohga( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int is_schmeisr ) static void update_rohga( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect, int is_schmeisr )
@ -480,12 +172,103 @@ SCREEN_UPDATE_IND16( schmeisr )
return 0; return 0;
} }
VIDEO_START(wizdfire)
{
machine.device<decospr_device>("spritegen1")->alloc_sprite_bitmap();
machine.device<decospr_device>("spritegen2")->alloc_sprite_bitmap();
}
// not amazingly efficient, called multiple times to pull a layer out of the sprite bitmaps, but keeps correct sprite<->sprite priorities
static void mixwizdfirelayer(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, int mode, int gfxregion)
{
int y, x;
const pen_t *paldata = machine.pens;
bitmap_ind16* sprite_bitmap;
int penbase;
if (gfxregion==3)
{
sprite_bitmap = &machine.device<decospr_device>("spritegen1")->get_sprite_temp_bitmap();
penbase = 0x400;
}
else
{
sprite_bitmap = &machine.device<decospr_device>("spritegen2")->get_sprite_temp_bitmap();
penbase = 0x600;
}
UINT16* srcline;
UINT32* dstline;
for (y=cliprect.min_y;y<=cliprect.max_y;y++)
{
srcline=&sprite_bitmap->pix16(y,0);
dstline=&bitmap.pix32(y,0);
for (x=cliprect.min_x;x<=cliprect.max_x;x++)
{
UINT16 pix = srcline[x];
switch (mode)
{
case 4:
if ((pix & 0x600) != 0x600)
continue;
break;
case 3:
if ((pix & 0x600) != 0x400)
continue;
break;
case 2:
if ((pix & 0x400) != 0x400)
continue;
break;
case 1:
case 0:
default:
if ((pix & 0x400) != 0x000)
continue;
break;
}
if (pix&0xf)
{
UINT16 pen = pix&0x1ff;
if (gfxregion==3)
{
dstline[x] = paldata[pen+penbase];
}
else
{
if (pen&0x100)
{
UINT32 base = dstline[x];
pen &=0xff;
dstline[x] = alpha_blend_r32(base, paldata[pen+penbase], 0x80);
}
else
{
dstline[x] = paldata[pen+penbase];
}
}
}
}
}
}
SCREEN_UPDATE_RGB32( wizdfire ) SCREEN_UPDATE_RGB32( wizdfire )
{ {
rohga_state *state = screen.machine().driver_data<rohga_state>(); rohga_state *state = screen.machine().driver_data<rohga_state>();
UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff); UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff);
UINT16 priority = decocomn_priority_r(state->m_decocomn, 0, 0xffff); UINT16 priority = decocomn_priority_r(state->m_decocomn, 0, 0xffff);
/* draw sprite gfx to temp bitmaps */
screen.machine().device<decospr_device>("spritegen2")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 0x400, true);
screen.machine().device<decospr_device>("spritegen1")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0x400, true);
/* Update playfields */ /* Update playfields */
flip_screen_set(screen.machine(), BIT(flip, 7)); flip_screen_set(screen.machine(), BIT(flip, 7));
deco16ic_pf_update(state->m_deco_tilegen1, 0, 0); deco16ic_pf_update(state->m_deco_tilegen1, 0, 0);
@ -495,19 +278,18 @@ SCREEN_UPDATE_RGB32( wizdfire )
bitmap.fill(screen.machine().pens[512], cliprect); bitmap.fill(screen.machine().pens[512], cliprect);
deco16ic_tilemap_2_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); deco16ic_tilemap_2_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 4, 3); mixwizdfirelayer(screen.machine(), bitmap, cliprect, 4,3);
deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0); deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0);
wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 3, 3); mixwizdfirelayer(screen.machine(), bitmap, cliprect, 3,3);
if ((priority & 0x1f) == 0x1f) /* Wizdfire has bit 0x40 always set, Dark Seal 2 doesn't?! */ if ((priority & 0x1f) == 0x1f) /* Wizdfire has bit 0x40 always set, Dark Seal 2 doesn't?! */
deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_ALPHA(0x80), 0); deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_ALPHA(0x80), 0);
else else
deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 0); deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 0);
/* See notes in wizdfire_draw_sprites about this */ mixwizdfirelayer(screen.machine(), bitmap, cliprect, 0,3);
wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0, 3); mixwizdfirelayer(screen.machine(), bitmap, cliprect, 2,4);
wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 2, 4); mixwizdfirelayer(screen.machine(), bitmap, cliprect, 1,4);
wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 1, 4);
deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0); deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0);
return 0; return 0;
@ -518,6 +300,12 @@ SCREEN_UPDATE_RGB32( nitrobal )
rohga_state *state = screen.machine().driver_data<rohga_state>(); rohga_state *state = screen.machine().driver_data<rohga_state>();
UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff); UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff);
/* draw sprite gfx to temp bitmaps */
screen.machine().device<decospr_device>("spritegen1")->set_alt_format(true);
screen.machine().device<decospr_device>("spritegen2")->set_alt_format(true);
screen.machine().device<decospr_device>("spritegen2")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 0x400, false);
screen.machine().device<decospr_device>("spritegen1")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0x400, false);
/* Update playfields */ /* Update playfields */
flip_screen_set(screen.machine(), BIT(flip, 7)); flip_screen_set(screen.machine(), BIT(flip, 7));
deco16ic_pf_update(state->m_deco_tilegen1, state->m_pf1_rowscroll, state->m_pf2_rowscroll); deco16ic_pf_update(state->m_deco_tilegen1, state->m_pf1_rowscroll, state->m_pf2_rowscroll);
@ -532,8 +320,11 @@ SCREEN_UPDATE_RGB32( nitrobal )
deco16ic_tilemap_12_combine_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); deco16ic_tilemap_12_combine_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 16); deco16ic_tilemap_2_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 16);
nitrobal_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 3);
nitrobal_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 4); /* ToDo reimplement priorities + mixing / alpha, it was busted worse than this before anyway, so no big loss that we don't do it for now ;-) */
screen.machine().device<decospr_device>("spritegen2")->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0000, 0x600, 0xff);
screen.machine().device<decospr_device>("spritegen1")->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0000, 0x400, 0x1ff);
deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0); deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0);
return 0; return 0;