More DECO 56 refactoring from Haze

This commit is contained in:
Angelo Salese 2011-03-23 23:52:08 +00:00
parent 8579c805de
commit eae55a88b5
7 changed files with 427 additions and 467 deletions

View File

@ -713,8 +713,8 @@ static GFXDECODE_START( mutantf )
GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 64 ) /* Characters 8x8 */ GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 64 ) /* Characters 8x8 */
GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 64 ) /* Tiles 16x16 */ GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 64 ) /* Tiles 16x16 */
GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 0, 64 ) /* Tiles 16x16 */ GFXDECODE_ENTRY( "gfx3", 0, tilelayout, 0, 64 ) /* Tiles 16x16 */
GFXDECODE_ENTRY( "gfx4", 0, spritelayout, 256, 128 ) /* Sprites 16x16 */ GFXDECODE_ENTRY( "gfx4", 0, spritelayout, 0, 128 ) /* Sprites 16x16 */
GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 1024+768, 16 ) /* Sprites 16x16 */ GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 0, 16 ) /* Sprites 16x16 */
GFXDECODE_END GFXDECODE_END
/**********************************************************************************/ /**********************************************************************************/
@ -1131,10 +1131,18 @@ static MACHINE_CONFIG_START( mutantf, cninja_state )
MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1) MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
MCFG_SCREEN_UPDATE(mutantf) MCFG_SCREEN_UPDATE(mutantf)
MCFG_VIDEO_START(mutantf)
MCFG_GFXDECODE(mutantf) MCFG_GFXDECODE(mutantf)
MCFG_PALETTE_LENGTH(2048) MCFG_PALETTE_LENGTH(2048)
MCFG_DECO16IC_ADD("deco_custom", mutantf_deco16ic_intf) MCFG_DECO16IC_ADD("deco_custom", mutantf_deco16ic_intf)
MCFG_DEVICE_ADD("spritegen1", decospr_, 0)
decospr_device_config::set_gfx_region(device, 3);
MCFG_DEVICE_ADD("spritegen2", decospr_, 0)
decospr_device_config::set_gfx_region(device, 4);
/* sound hardware */ /* sound hardware */
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")

View File

@ -665,14 +665,35 @@ static WRITE32_HANDLER( nslasher_prot_w )
/**********************************************************************************/ /**********************************************************************************/
static READ32_HANDLER( deco32_spriteram_r )
{
deco32_state *state = space->machine->driver_data<deco32_state>();
return state->spriteram16[offset] ^ 0xffff0000;
}
static WRITE32_HANDLER( deco32_spriteram_w )
{
deco32_state *state = space->machine->driver_data<deco32_state>();
data &= 0x0000ffff;
mem_mask &= 0x0000ffff;
COMBINE_DATA(&state->spriteram16[offset]);
}
static WRITE32_HANDLER( deco32_buffer_spriteram_w )
{
deco32_state *state = space->machine->driver_data<deco32_state>();
memcpy(state->spriteram16_buffered, state->spriteram16, 0x1000);
}
static ADDRESS_MAP_START( captaven_map, ADDRESS_SPACE_PROGRAM, 32 ) static ADDRESS_MAP_START( captaven_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x0fffff) AM_ROM AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x100007) AM_READ(deco32_71_r) AM_RANGE(0x100000, 0x100007) AM_READ(deco32_71_r)
AM_RANGE(0x100000, 0x100003) AM_WRITE(buffer_spriteram32_w) AM_RANGE(0x100000, 0x100003) AM_WRITE(deco32_buffer_spriteram_w)
AM_RANGE(0x108000, 0x108003) AM_WRITENOP /* ? */ AM_RANGE(0x108000, 0x108003) AM_WRITENOP /* ? */
AM_RANGE(0x110000, 0x110fff) AM_RAM AM_BASE_SIZE_GENERIC(spriteram) /* Sprites */ AM_RANGE(0x110000, 0x111fff) AM_READWRITE(deco32_spriteram_r, deco32_spriteram_w)
AM_RANGE(0x120000, 0x127fff) AM_RAM AM_BASE_MEMBER(deco32_state, ram) /* Main RAM */ AM_RANGE(0x120000, 0x127fff) AM_RAM AM_BASE_MEMBER(deco32_state, ram) /* Main RAM */
AM_RANGE(0x128000, 0x128fff) AM_READ(captaven_prot_r) AM_RANGE(0x128000, 0x128fff) AM_READ(captaven_prot_r)
AM_RANGE(0x1280c8, 0x1280cb) AM_WRITE(deco32_sound_w) AM_RANGE(0x1280c8, 0x1280cb) AM_WRITE(deco32_sound_w)
AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(deco32_nonbuffered_palette_w) AM_BASE_GENERIC(paletteram) /* Palette RAM */ AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(deco32_nonbuffered_palette_w) AM_BASE_GENERIC(paletteram) /* Palette RAM */
@ -694,25 +715,7 @@ static ADDRESS_MAP_START( captaven_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x1e0000, 0x1e1fff) AM_RAM AM_BASE_MEMBER(deco32_state, pf3_rowscroll) AM_RANGE(0x1e0000, 0x1e1fff) AM_RAM AM_BASE_MEMBER(deco32_state, pf3_rowscroll)
ADDRESS_MAP_END ADDRESS_MAP_END
static READ32_HANDLER( deco32_spriteram_r )
{
deco32_state *state = space->machine->driver_data<deco32_state>();
return state->spriteram16[offset] ^ 0xffff0000;
}
static WRITE32_HANDLER( deco32_spriteram_w )
{
deco32_state *state = space->machine->driver_data<deco32_state>();
data &= 0x0000ffff;
mem_mask &= 0x0000ffff;
COMBINE_DATA(&state->spriteram16[offset]);
}
static WRITE32_HANDLER( deco32_buffer_spriteram_w )
{
deco32_state *state = space->machine->driver_data<deco32_state>();
memcpy(state->spriteram16_buffered, state->spriteram16, 0x1000);
}
static ADDRESS_MAP_START( fghthist_map, ADDRESS_SPACE_PROGRAM, 32 ) static ADDRESS_MAP_START( fghthist_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x001fff) AM_ROM AM_WRITE(deco32_pf1_data_w) AM_RANGE(0x000000, 0x001fff) AM_ROM AM_WRITE(deco32_pf1_data_w)
@ -1682,6 +1685,27 @@ static INTERRUPT_GEN( tattass_snd_interrupt )
cpu_set_input_line(device, M6809_FIRQ_LINE, HOLD_LINE); cpu_set_input_line(device, M6809_FIRQ_LINE, HOLD_LINE);
} }
UINT16 captaven_pri_callback(UINT16 x)
{
if ((x&0x60)==0x00)
{
return 0; // above everything
}
else if ((x&0x60)==0x20)
{
return 0xfff0; // above the 2nd playfield
}
else if ((x&0x60)==0x40)
{
return 0xfffc; // above the 1st playfield
}
else
{
return 0xfffe; // under everything
}
}
static MACHINE_CONFIG_START( captaven, deco32_state ) static MACHINE_CONFIG_START( captaven, deco32_state )
/* basic machine hardware */ /* basic machine hardware */
@ -1696,9 +1720,6 @@ static MACHINE_CONFIG_START( captaven, deco32_state )
MCFG_TIMER_ADD("int_timer", interrupt_gen) MCFG_TIMER_ADD("int_timer", interrupt_gen)
/* video hardware */
MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM)
MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
@ -1710,6 +1731,11 @@ static MACHINE_CONFIG_START( captaven, deco32_state )
MCFG_GFXDECODE(captaven) MCFG_GFXDECODE(captaven)
MCFG_PALETTE_LENGTH(2048) MCFG_PALETTE_LENGTH(2048)
MCFG_DEVICE_ADD("spritegen", decospr_, 0)
decospr_device_config::set_gfx_region(device, 3);
decospr_device_config::set_pri_callback(device, captaven_pri_callback);
MCFG_VIDEO_START(captaven) MCFG_VIDEO_START(captaven)
/* sound hardware */ /* sound hardware */
@ -1929,7 +1955,7 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( tattass, deco32_state ) static MACHINE_CONFIG_START( tattass, deco32_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD("maincpu", ARM, 28000000/4) /* Unconfirmed */ MCFG_CPU_ADD("maincpu", ARM, 28000000/*/4*/) /* Unconfirmed - the divider makes it far too slow, due to inaccurate core timings? */
MCFG_CPU_PROGRAM_MAP(tattass_map) MCFG_CPU_PROGRAM_MAP(tattass_map)
MCFG_CPU_VBLANK_INT("screen", deco32_vbl_interrupt) MCFG_CPU_VBLANK_INT("screen", deco32_vbl_interrupt)

View File

@ -39,6 +39,7 @@ public:
/*----------- defined in video/cninja.c -----------*/ /*----------- defined in video/cninja.c -----------*/
VIDEO_START( stoneage ); VIDEO_START( stoneage );
VIDEO_START( mutantf );
SCREEN_UPDATE( cninja ); SCREEN_UPDATE( cninja );
SCREEN_UPDATE( cninjabl ); SCREEN_UPDATE( cninjabl );

View File

@ -121,125 +121,6 @@ static void cninjabl_draw_sprites( running_machine *machine, bitmap_t *bitmap, c
} }
} }
static void mutantf_draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, const UINT16 *spriteptr, int gfxbank )
{
int offs, end, inc;
/*
Alternate format from most 16 bit games - same as Captain America
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?
0x001f: Colour
Word 3:
0xffff: Sprite value
*/
/* This may look strange, but the alpha-blended sprite chip definitely draws end to
front, ie, reversed from normal pdrawgfx style. */
if (gfxbank == 4)
{
offs = 0;
end = 0x400;
inc = 4;
}
else
{
offs = 0x3fc;
end = -4;
inc = -4;
}
while (offs != end)
{
int x, y, sprite, colour, fx, fy, w, h, sx, sy, x_mult, y_mult;
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;
if (gfxbank == 4)
{ /* Seems to be always alpha'd */
alpha = 0x80;
colour &= 0xf;
}
fx = (spriteptr[offs + 0] & 0x4000);
fy = (spriteptr[offs + 0] & 0x8000);
if (flip_screen_get(machine))
{
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++)
{
pdrawgfx_alpha(bitmap,cliprect,machine->gfx[gfxbank],
sprite + y + h * x,
colour,
fx,fy,
sx + x_mult * (w-x),sy + y_mult * (h-y),
machine->priority_bitmap,0,
0,alpha);
}
}
offs += inc;
}
}
/******************************************************************************/ /******************************************************************************/
SCREEN_UPDATE( cninja ) SCREEN_UPDATE( cninja )
@ -354,12 +235,19 @@ SCREEN_UPDATE( robocop2 )
return 0; return 0;
} }
VIDEO_START( mutantf )
{
machine->device<decospr_device>("spritegen1")->alloc_sprite_bitmap(machine);
machine->device<decospr_device>("spritegen2")->alloc_sprite_bitmap(machine);
}
SCREEN_UPDATE( mutantf ) SCREEN_UPDATE( mutantf )
{ {
cninja_state *state = screen->machine->driver_data<cninja_state>(); cninja_state *state = screen->machine->driver_data<cninja_state>();
UINT16 flip = deco16ic_pf12_control_r(state->deco16ic, 0, 0xffff); UINT16 flip = deco16ic_pf12_control_r(state->deco16ic, 0, 0xffff);
UINT16 priority = deco16ic_priority_r(state->deco16ic, 0, 0xffff); UINT16 priority = deco16ic_priority_r(state->deco16ic, 0, 0xffff);
flip_screen_set(screen->machine, BIT(flip, 7)); flip_screen_set(screen->machine, BIT(flip, 7));
deco16ic_pf12_update(state->deco16ic, state->pf1_rowscroll, state->pf2_rowscroll); deco16ic_pf12_update(state->deco16ic, state->pf1_rowscroll, state->pf2_rowscroll);
deco16ic_pf34_update(state->deco16ic, state->pf3_rowscroll, state->pf4_rowscroll); deco16ic_pf34_update(state->deco16ic, state->pf3_rowscroll, state->pf4_rowscroll);
@ -367,6 +255,12 @@ SCREEN_UPDATE( mutantf )
/* Draw playfields */ /* Draw playfields */
bitmap_fill(bitmap, cliprect, 0x400); /* Confirmed */ bitmap_fill(bitmap, cliprect, 0x400); /* Confirmed */
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(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram2.u16, 0x400, true);
screen->machine->device<decospr_device>("spritegen1")->draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram.u16, 0x400, true);
/* There is no priority prom on this board, but there is a /* There is no priority prom on this board, but there is a
priority control word, the only values used in game appear priority control word, the only values used in game appear
to be 2, 6 & 7 though: to be 2, 6 & 7 though:
@ -381,26 +275,17 @@ SCREEN_UPDATE( mutantf )
deco16ic_tilemap_4_draw(state->deco16ic, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); deco16ic_tilemap_4_draw(state->deco16ic, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
deco16ic_tilemap_2_draw(state->deco16ic, bitmap, cliprect, 0, 0); deco16ic_tilemap_2_draw(state->deco16ic, bitmap, cliprect, 0, 0);
deco16ic_tilemap_3_draw(state->deco16ic, bitmap, cliprect, 0, 0); deco16ic_tilemap_3_draw(state->deco16ic, bitmap, cliprect, 0, 0);
/* We need to abuse the priority bitmap a little by clearing it before
drawing each sprite layer. This is because there is no priority
orthogonality between sprite layers, but the alpha layer must obey
priority between sprites in each layer. Ie, if we didn't do this,
then when two alpha blended shadows overlapped then they would be 25%
transparent against the background, rather than 50% */
if (priority & 1) if (priority & 1)
{ {
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0); screen->machine->device<decospr_device>("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 0x100, 0x1ff);
mutantf_draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram.u16, 3); screen->machine->device<decospr_device>("spritegen2")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 1024+768, 0x0ff, 0x80); // fixed alpha of 0x80 for this layer?
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
mutantf_draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram2.u16, 4);
} }
else else
{ {
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0); screen->machine->device<decospr_device>("spritegen2")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 1024+768, 0x0ff, 0x80); // fixed alpha of 0x80 for this layer?
mutantf_draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram2.u16, 4); screen->machine->device<decospr_device>("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 0x100, 0x1ff);
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
mutantf_draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram.u16, 3);
} }
deco16ic_tilemap_1_draw(state->deco16ic, bitmap, cliprect, 0, 0); deco16ic_tilemap_1_draw(state->deco16ic, bitmap, cliprect, 0, 0);
return 0; return 0;

View File

@ -183,111 +183,7 @@ WRITE32_HANDLER( deco32_palette_dma_w )
/******************************************************************************/ /******************************************************************************/
static void captaven_draw_sprites(running_machine* machine, bitmap_t *bitmap, const rectangle *cliprect, const UINT32 *spritedata, int gfxbank)
{
int offs;
/*
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
0x0080: Unused?
0x0040: Priority
0x001f: Colour
Word 3:
0xffff: Sprite value
*/
for (offs = 0x400-4;offs >=0;offs -= 4)
{
int sx,sy,sprite,colour,fx,fy,x_mult,y_mult,w,h,x,y,prival;
sy = spritedata[offs+0];
sprite = spritedata[offs+3] & 0xffff;
if (sy==0x00000108 && !sprite)
continue; //fix!!!!!
if ((spritedata[offs+2]&0x60)==0x00)
{
prival = 0; // above everything
}
else if ((spritedata[offs+2]&0x60)==0x20)
{
prival = 0xfff0; // above the 2nd playfield
}
else if ((spritedata[offs+2]&0x60)==0x40)
{
prival = 0xfffc; // above the 1st playfield
}
else
{
// never used?
prival = 0xfffe; // under everything
}
sx = spritedata[offs+1];
if ((sy&0x2000) && (machine->primary_screen->frame_number() & 1)) continue;
colour = (spritedata[offs+2] >>0) & 0x1f;
h = (spritedata[offs+2]&0xf000)>>12;
w = (spritedata[offs+2]&0x0f00)>> 8;
fx = !(spritedata[offs+0]&0x4000);
fy = !(spritedata[offs+0]&0x8000);
if (!flip_screen_get(machine)) {
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 {
if (fx) fx=0; else fx=1;
if (fy) fy=0; else fy=1;
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++) {
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[gfxbank],
sprite + y + h * x,
colour,
fx,fy,
sx + x_mult * (w-x),sy + y_mult * (h-y),
machine->priority_bitmap,prival,0);
// wrap-around y
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[gfxbank],
sprite + y + h * x,
colour,
fx,fy,
sx + x_mult * (w-x),sy + y_mult * (h-y) - 512,
machine->priority_bitmap,prival,0);
}
}
}
}
/* /*
This renders sprites to a 16 bit bitmap, for later mixing. This renders sprites to a 16 bit bitmap, for later mixing.
@ -1023,7 +919,7 @@ VIDEO_START( nslasher )
SCREEN_EOF( captaven ) SCREEN_EOF( captaven )
{ {
memcpy(machine->generic.buffered_spriteram.u32,machine->generic.spriteram.u32,machine->generic.spriteram_size);
} }
SCREEN_EOF( dragngun ) SCREEN_EOF( dragngun )
@ -1194,7 +1090,8 @@ SCREEN_UPDATE( captaven )
else else
tilemap_draw(bitmap,cliprect,state->pf1a_tilemap,0,4); tilemap_draw(bitmap,cliprect,state->pf1a_tilemap,0,4);
captaven_draw_sprites(screen->machine,bitmap,cliprect,screen->machine->generic.buffered_spriteram.u32,3); screen->machine->device<decospr_device>("spritegen")->set_alt_format(true);
screen->machine->device<decospr_device>("spritegen")->draw_sprites(screen->machine, bitmap, cliprect, state->spriteram16_buffered, 0x400);
return 0; return 0;
} }

View File

@ -21,93 +21,20 @@
sshangha.c (could probably use pdrawgfx, not m_sprite_bitmap) sshangha.c (could probably use pdrawgfx, not m_sprite_bitmap)
cbuster.c (could probably use pdrawgfx, not m_sprite_bitmap) cbuster.c (could probably use pdrawgfx, not m_sprite_bitmap)
mirage.c (could probably use pdrawgfx, not m_sprite_bitmap) mirage.c (could probably use pdrawgfx, not m_sprite_bitmap)
cninja.c
partially converted: partially converted:
cninja.c (mutantf uses alpha etc.)
deco32.c - video mixing deco32.c - video mixing
difficult to convert: difficult to convert:
rohga.c - alpha effects, extra rom banking on the sprites etc. causes problems rohga.c - complex video mixing, 6bpp gfx..
lemmings.c - priority stuff (plus sprites seem somewhat different anyway??) lemmings.c - priority stuff (plus sprites seem somewhat different anyway??)
dassault.c - video mixing dassault.c - complex video mixing
boogwing.c - video mixing boogwing.c - complex video mixing
*/ */
#include "emu.h"
#include "decospr.h"
decospr_device_config::decospr_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
: device_config(mconfig, static_alloc_device_config, "decospr_device", tag, owner, clock)
{
m_gfxregion = 0;
m_pricallback = NULL;
}
device_config *decospr_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
{
return global_alloc(decospr_device_config(mconfig, tag, owner, clock));
}
device_t *decospr_device_config::alloc_device(running_machine &machine) const
{
return auto_alloc(&machine, decospr_device(machine, *this));
}
void decospr_device_config::set_gfx_region(device_config *device, int gfxregion)
{
decospr_device_config *dev = downcast<decospr_device_config *>(device);
dev->m_gfxregion = gfxregion;
// printf("decospr_device_config::set_gfx_region()\n");
}
void decospr_device_config::set_pri_callback(device_config *device, decospr_priority_callback_func callback)
{
decospr_device_config *dev = downcast<decospr_device_config *>(device);
dev->m_pricallback = callback;
// printf("decospr_device_config::set_pri_callback()\n");
}
decospr_device::decospr_device(running_machine &_machine, const decospr_device_config &config)
: device_t(_machine, config),
m_config(config),
m_gfxregion(m_config.m_gfxregion),
m_pricallback(m_config.m_pricallback)
{
}
void decospr_device::device_start()
{
// sprite_kludge_x = sprite_kludge_y = 0;
// printf("decospr_device::device_start()\n");
m_sprite_bitmap = 0;
}
void decospr_device::device_reset()
{
//printf("decospr_device::device_reset()\n");
}
/*
void decospr_device::decospr_sprite_kludge(int x, int y)
{
sprite_kludge_x = x;
sprite_kludge_y = y;
}
*/
void decospr_device::alloc_sprite_bitmap(running_machine* machine)
{
m_sprite_bitmap = auto_bitmap_alloc(machine, machine->primary_screen->width(), machine->primary_screen->height(), BITMAP_FORMAT_INDEXED16);
}
void decospr_device::set_pri_callback(decospr_priority_callback_func callback)
{
m_pricallback = callback;
}
/* /*
STANDARD FORMAT STANDARD FORMAT
@ -178,10 +105,86 @@ t = sprite tile
todo: the priotity callback for using pdrawgfx should really pack those 8 bits, and pass them instead of currently just todo: the priotity callback for using pdrawgfx should really pack those 8 bits, and pass them instead of currently just
passing offs+2 which lacks the extra priority bit passing offs+2 which lacks the extra priority bit
todo: add support for alternate format + basic blend mixing todo: basic blend mixing
*/ */
#include "emu.h"
#include "decospr.h"
decospr_device_config::decospr_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
: device_config(mconfig, static_alloc_device_config, "decospr_device", tag, owner, clock)
{
m_gfxregion = 0;
m_pricallback = NULL;
}
device_config *decospr_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
{
return global_alloc(decospr_device_config(mconfig, tag, owner, clock));
}
device_t *decospr_device_config::alloc_device(running_machine &machine) const
{
return auto_alloc(&machine, decospr_device(machine, *this));
}
void decospr_device_config::set_gfx_region(device_config *device, int gfxregion)
{
decospr_device_config *dev = downcast<decospr_device_config *>(device);
dev->m_gfxregion = gfxregion;
// printf("decospr_device_config::set_gfx_region()\n");
}
void decospr_device_config::set_pri_callback(device_config *device, decospr_priority_callback_func callback)
{
decospr_device_config *dev = downcast<decospr_device_config *>(device);
dev->m_pricallback = callback;
// printf("decospr_device_config::set_pri_callback()\n");
}
decospr_device::decospr_device(running_machine &_machine, const decospr_device_config &config)
: device_t(_machine, config),
m_config(config),
m_gfxregion(m_config.m_gfxregion),
m_pricallback(m_config.m_pricallback)
{
}
void decospr_device::device_start()
{
// sprite_kludge_x = sprite_kludge_y = 0;
// printf("decospr_device::device_start()\n");
m_sprite_bitmap = 0;
m_alt_format = 0;
}
void decospr_device::device_reset()
{
//printf("decospr_device::device_reset()\n");
}
/*
void decospr_device::decospr_sprite_kludge(int x, int y)
{
sprite_kludge_x = x;
sprite_kludge_y = y;
}
*/
void decospr_device::alloc_sprite_bitmap(running_machine* machine)
{
m_sprite_bitmap = auto_bitmap_alloc(machine, machine->primary_screen->width(), machine->primary_screen->height(), BITMAP_FORMAT_INDEXED16);
}
void decospr_device::set_pri_callback(decospr_priority_callback_func callback)
{
m_pricallback = callback;
}
void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16* spriteram, int sizewords, bool invert_flip ) void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16* spriteram, int sizewords, bool invert_flip )
{ {
@ -216,150 +219,268 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
while (offs!=end) while (offs!=end)
{ {
int x, y, sprite, colour, multi, mult2, fx, fy, inc, flash, mult, xsize, pri; int x, y, sprite, colour, multi, mult2, fx, fy, inc, flash, mult, h, w, pri;
sprite = spriteram[offs + 1]; if (!m_alt_format)
y = spriteram[offs];
flash = y & 0x1000;
xsize = y & 0x0800;
if (!(flash && (machine->primary_screen->frame_number() & 1)))
{ {
x = spriteram[offs + 2]; sprite = spriteram[offs + 1];
y = spriteram[offs];
if (!m_sprite_bitmap) flash = y & 0x1000;
colour = (x >> 9) & 0x1f; w = y & 0x0800;
else
{
colour = (x >> 9) & 0x7f; if (!(flash && (machine->primary_screen->frame_number() & 1)))
if (y&0x8000) colour |= 0x80; // fghthist uses this to mark priority {
//colour *= 0x10; // for raw drawing
} x = spriteram[offs + 2];
if (!m_sprite_bitmap)
colour = (x >> 9) & 0x1f;
else
{
colour = (x >> 9) & 0x7f;
if (y&0x8000) colour |= 0x80; // fghthist uses this to mark priority
}
if (m_pricallback)
pri = m_pricallback(x);
else
pri = 0;
fx = y & 0x2000;
fy = y & 0x4000;
multi = (1 << ((y & 0x0600) >> 9)) - 1; /* 1x, 2x, 4x, 8x height */
if (cliprect->max_x>256)
{
x = x & 0x01ff;
y = y & 0x01ff;
if (x >= 320) x -= 512;
if (y >= 256) y -= 512;
y = 240 - y;
x = 304 - x;
}
else
{
x = x & 0x01ff;
y = y & 0x01ff;
if (x >= 256) x -= 512;
if (y >= 256) y -= 512;
y = 240 - y;
x = 240 - x;
}
//if (x <= 320)
{
sprite &= ~multi;
if (fy)
inc = -1;
else
{
sprite += multi;
inc = 1;
}
if (flipscreen)
{
y = 240 - y;
if (cliprect->max_x>256)
x = 304 - x;
else
x = 240 - x;
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
mult = 16;
}
else
mult = -16;
mult2 = multi + 1;
while (multi >= 0)
{
if(!m_sprite_bitmap)
{
if (m_pricallback)
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite - multi * inc,
colour,
fx,fy,
x,y + mult * multi,
machine->priority_bitmap,pri,0);
else
drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite - multi * inc,
colour,
fx,fy,
x,y + mult * multi,
0);
// double wing uses this flag
if (w)
{
if (m_pricallback)
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
(sprite - multi * inc)-mult2,
colour,
fx,fy,
x-16,y + mult * multi,
machine->priority_bitmap,pri,0);
else
drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
(sprite - multi * inc)-mult2,
colour,
fx,fy,
x-16,y + mult * multi,
0);
}
}
else
{
// if we have a sprite bitmap draw raw data to it for manual mixing
drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion],
sprite - multi * inc,
colour*0x10,
fx,fy,
x,y + mult * multi,
0);
if (w)
{
drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion],
(sprite - multi * inc)-mult2,
colour*0x10,
fx,fy,
x-16,y + mult * multi,
0);
}
}
multi--;
}
}
}
}
else // m_alt_format
{
y = spriteram[offs+0];
sprite = spriteram[offs+3] & 0xffff;
if (m_pricallback) if (m_pricallback)
pri = m_pricallback(x); pri = m_pricallback(spriteram[offs+2]&0x00ff);
else else
pri = 0; pri = 0;
fx = y & 0x2000; x = spriteram[offs+1];
fy = y & 0x4000;
multi = (1 << ((y & 0x0600) >> 9)) - 1; /* 1x, 2x, 4x, 8x height */
if (cliprect->max_x>256) if (!((y&0x2000) && (machine->primary_screen->frame_number() & 1)));
{ {
x = x & 0x01ff; if (!m_sprite_bitmap)
y = y & 0x01ff; colour = (spriteram[offs+2] >>0) & 0x1f;
if (x >= 320) x -= 512;
if (y >= 256) y -= 512;
y = 240 - y;
x = 304 - x;
}
else
{
x = x & 0x01ff;
y = y & 0x01ff;
if (x >= 256) x -= 512;
if (y >= 256) y -= 512;
y = 240 - y;
x = 240 - x;
}
//if (x <= 320)
{
sprite &= ~multi;
if (fy)
inc = -1;
else else
{ colour = (spriteram[offs+2] >>0) & 0xff; // store all bits for manual mixing
sprite += multi;
inc = 1;
}
if (flipscreen)
{ h = (spriteram[offs+2]&0xf000)>>12;
w = (spriteram[offs+2]&0x0f00)>> 8;
fx = !(spriteram[offs+0]&0x4000);
fy = !(spriteram[offs+0]&0x8000);
if (!flipscreen) {
x = x & 0x01ff;
y = y & 0x01ff;
if (x>0x180) x=-(0x200 - x);
if (y>0x180) y=-(0x200 - y);
if (fx) { mult=-16; x+=16*w; } else { mult=16; x-=16; }
if (fy) { mult2=-16; y+=16*h; } else { mult2=16; y-=16; }
} else {
if (fx) fx=0; else fx=1;
if (fy) fy=0; else fy=1;
x = x & 0x01ff;
y = y & 0x01ff;
if (x&0x100) x=-(0x100 - (x&0xff));
if (y&0x100) y=-(0x100 - (y&0xff));
x = 304 - x;
y = 240 - y; y = 240 - y;
if (x >= 432) x -= 512;
if (cliprect->max_x>256) if (y >= 384) y -= 512;
x = 304 - x; if (fx) { mult=-16; x+=16; } else { mult=16; x-=16*w; }
else if (fy) { mult2=-16; y+=16; } else { mult2=16; y-=16*h; }
x = 240 - x;
if (fx) fx = 0; else fx = 1;
if (fy) fy = 0; else fy = 1;
mult = 16;
} }
else
mult = -16;
mult2 = multi + 1; for (int xx=0; xx<w; xx++)
while (multi >= 0)
{ {
if(!m_sprite_bitmap) for (int yy=0; yy<h; yy++)
{ {
if (m_pricallback) if(!m_sprite_bitmap)
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite - multi * inc,
colour,
fx,fy,
x,y + mult * multi,
machine->priority_bitmap,pri,0);
else
drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite - multi * inc,
colour,
fx,fy,
x,y + mult * multi,
0);
// double wing uses this flag
if (xsize)
{ {
if (m_pricallback) if (m_pricallback)
{
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion], pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
(sprite - multi * inc)-mult2, sprite + yy + h * xx,
colour, colour,
fx,fy, fx,fy,
x-16,y + mult * multi, x + mult * (w-xx),y + mult2 * (h-yy),
machine->priority_bitmap,pri,0); machine->priority_bitmap,pri,0);
else
drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion], // wrap-around y
(sprite - multi * inc)-mult2, pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite + yy + h * xx,
colour, colour,
fx,fy, fx,fy,
x-16,y + mult * multi, x + mult * (w-xx),y + mult2 * (h-yy) - 512,
machine->priority_bitmap,pri,0);
}
else
{
drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite + yy + h * xx,
colour,
fx,fy,
x + mult * (w-xx),y + mult2 * (h-yy),
0); 0);
// wrap-around y
drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite + yy + h * xx,
colour,
fx,fy,
x + mult * (w-xx),y + mult2 * (h-yy) - 512,
0);
}
} }
} else
else {
{
// if we have a sprite bitmap draw raw data to it for manual mixing
drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion],
sprite - multi * inc,
colour*0x10,
fx,fy,
x,y + mult * multi,
0);
if (xsize)
{
drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion], drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion],
(sprite - multi * inc)-mult2, sprite + yy + h * xx,
colour*0x10, colour*0x10,
fx,fy, fx,fy,
x-16,y + mult * multi, x + mult * (w-xx),y + mult2 * (h-yy),
0); 0);
// wrap-around y
drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion],
sprite + yy + h * xx,
colour*0x10,
fx,fy,
x + mult * (w-xx),y + mult2 * (h-yy) - 512,
0);
} }
} }
multi--;
} }
} }
} }
@ -370,7 +491,7 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
// inefficient, we should be able to mix in a single pass by comparing the existing priority bitmap from the tilemaps // inefficient, we should be able to mix in a single pass by comparing the existing priority bitmap from the tilemaps
void decospr_device::inefficient_copy_sprite_bitmap(running_machine* machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16 pri, UINT16 priority_mask, UINT16 colbase, UINT16 palmask) void decospr_device::inefficient_copy_sprite_bitmap(running_machine* machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16 pri, UINT16 priority_mask, UINT16 colbase, UINT16 palmask, UINT8 alpha)
{ {
if (!m_sprite_bitmap) if (!m_sprite_bitmap)
fatalerror("decospr_device::inefficient_copy_sprite_bitmap with no m_sprite_bitmap"); fatalerror("decospr_device::inefficient_copy_sprite_bitmap with no m_sprite_bitmap");
@ -386,16 +507,36 @@ void decospr_device::inefficient_copy_sprite_bitmap(running_machine* machine, bi
srcline= BITMAP_ADDR16(m_sprite_bitmap, y, 0); srcline= BITMAP_ADDR16(m_sprite_bitmap, y, 0);
dstline= BITMAP_ADDR32(bitmap, y, 0); dstline= BITMAP_ADDR32(bitmap, y, 0);
for (x=cliprect->min_x;x<=cliprect->max_x;x++) if (alpha==0xff)
{ {
UINT16 pix = srcline[x]; for (x=cliprect->min_x;x<=cliprect->max_x;x++)
if (pix&0xf)
{ {
if ((pix & priority_mask) ==pri ) UINT16 pix = srcline[x];
if (pix&0xf)
{ {
dstline[x] = paldata[(pix&palmask) + colbase]; if ((pix & priority_mask) ==pri )
} {
dstline[x] = paldata[(pix&palmask) + colbase];
}
}
}
}
else
{
for (x=cliprect->min_x;x<=cliprect->max_x;x++)
{
UINT16 pix = srcline[x];
if (pix&0xf)
{
if ((pix & priority_mask) ==pri )
{
UINT32 pal1 = paldata[(pix&palmask) + colbase];
UINT32 pal2 = dstline[x];
dstline[x] = alpha_blend_r32(pal2, pal1, alpha);
}
}
} }
} }
} }

View File

@ -25,8 +25,9 @@ public:
void draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16* spriteram, int sizewords, bool invert_flip = false ); void draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16* spriteram, int sizewords, bool invert_flip = false );
void set_pri_callback(decospr_priority_callback_func callback); void set_pri_callback(decospr_priority_callback_func callback);
void set_gfxregion(int region) { m_gfxregion = region; }; void set_gfxregion(int region) { m_gfxregion = region; };
void set_alt_format(bool alt) { m_alt_format = alt; };
void alloc_sprite_bitmap(running_machine* machine); void alloc_sprite_bitmap(running_machine* machine);
void inefficient_copy_sprite_bitmap(running_machine* machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16 pri, UINT16 priority_mask, UINT16 colbase, UINT16 palmask); void inefficient_copy_sprite_bitmap(running_machine* machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16 pri, UINT16 priority_mask, UINT16 colbase, UINT16 palmask, UINT8 alpha = 0xff);
bitmap_t* get_sprite_temp_bitmap(void) { return m_sprite_bitmap; }; bitmap_t* get_sprite_temp_bitmap(void) { return m_sprite_bitmap; };
protected: protected:
@ -36,6 +37,7 @@ protected:
UINT8 m_gfxregion; UINT8 m_gfxregion;
decospr_priority_callback_func m_pricallback; decospr_priority_callback_func m_pricallback;
bitmap_t *m_sprite_bitmap;// optional sprite bitmap (should be INDEXED16) bitmap_t *m_sprite_bitmap;// optional sprite bitmap (should be INDEXED16)
bool m_alt_format;
private: private:
}; };