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( "gfx2", 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( "gfx5", 0, spritelayout, 1024+768, 16 ) /* Sprites 16x16 */
GFXDECODE_ENTRY( "gfx4", 0, spritelayout, 0, 128 ) /* Sprites 16x16 */
GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 0, 16 ) /* Sprites 16x16 */
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_UPDATE(mutantf)
MCFG_VIDEO_START(mutantf)
MCFG_GFXDECODE(mutantf)
MCFG_PALETTE_LENGTH(2048)
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 */
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 )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
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(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(0x128000, 0x128fff) AM_READ(captaven_prot_r)
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 */
@ -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)
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 )
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);
}
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 )
/* basic machine hardware */
@ -1696,9 +1720,6 @@ static MACHINE_CONFIG_START( captaven, deco32_state )
MCFG_TIMER_ADD("int_timer", interrupt_gen)
/* video hardware */
MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM)
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
@ -1710,6 +1731,11 @@ static MACHINE_CONFIG_START( captaven, deco32_state )
MCFG_GFXDECODE(captaven)
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)
/* sound hardware */
@ -1929,7 +1955,7 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( tattass, deco32_state )
/* 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_VBLANK_INT("screen", deco32_vbl_interrupt)

View File

@ -39,6 +39,7 @@ public:
/*----------- defined in video/cninja.c -----------*/
VIDEO_START( stoneage );
VIDEO_START( mutantf );
SCREEN_UPDATE( cninja );
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 )
@ -354,12 +235,19 @@ SCREEN_UPDATE( robocop2 )
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 )
{
cninja_state *state = screen->machine->driver_data<cninja_state>();
UINT16 flip = deco16ic_pf12_control_r(state->deco16ic, 0, 0xffff);
UINT16 priority = deco16ic_priority_r(state->deco16ic, 0, 0xffff);
flip_screen_set(screen->machine, BIT(flip, 7));
deco16ic_pf12_update(state->deco16ic, state->pf1_rowscroll, state->pf2_rowscroll);
deco16ic_pf34_update(state->deco16ic, state->pf3_rowscroll, state->pf4_rowscroll);
@ -367,6 +255,12 @@ SCREEN_UPDATE( mutantf )
/* Draw playfields */
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
priority control word, the only values used in game appear
to be 2, 6 & 7 though:
@ -382,25 +276,16 @@ SCREEN_UPDATE( mutantf )
deco16ic_tilemap_2_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)
{
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
mutantf_draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram.u16, 3);
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
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);
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?
}
else
{
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
mutantf_draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram2.u16, 4);
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
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?
screen->machine->device<decospr_device>("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 0x100, 0x1ff);
}
deco16ic_tilemap_1_draw(state->deco16ic, bitmap, cliprect, 0, 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.
@ -1023,7 +919,7 @@ VIDEO_START( nslasher )
SCREEN_EOF( captaven )
{
memcpy(machine->generic.buffered_spriteram.u32,machine->generic.spriteram.u32,machine->generic.spriteram_size);
}
SCREEN_EOF( dragngun )
@ -1194,7 +1090,8 @@ SCREEN_UPDATE( captaven )
else
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;
}

View File

@ -21,93 +21,20 @@
sshangha.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)
cninja.c
partially converted:
cninja.c (mutantf uses alpha etc.)
deco32.c - video mixing
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??)
dassault.c - video mixing
boogwing.c - video mixing
dassault.c - complex 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
@ -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
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 )
{
@ -216,13 +219,17 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
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;
if (!m_alt_format)
{
sprite = spriteram[offs + 1];
y = spriteram[offs];
flash = y & 0x1000;
xsize = y & 0x0800;
w = y & 0x0800;
if (!(flash && (machine->primary_screen->frame_number() & 1)))
{
@ -234,7 +241,6 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
{
colour = (x >> 9) & 0x7f;
if (y&0x8000) colour |= 0x80; // fghthist uses this to mark priority
//colour *= 0x10; // for raw drawing
}
@ -318,7 +324,7 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
0);
// double wing uses this flag
if (xsize)
if (w)
{
if (m_pricallback)
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
@ -345,7 +351,7 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
fx,fy,
x,y + mult * multi,
0);
if (xsize)
if (w)
{
drawgfx_transpen_raw(m_sprite_bitmap,cliprect,machine->gfx[m_gfxregion],
(sprite - multi * inc)-mult2,
@ -363,6 +369,121 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c
}
}
}
}
else // m_alt_format
{
y = spriteram[offs+0];
sprite = spriteram[offs+3] & 0xffff;
if (m_pricallback)
pri = m_pricallback(spriteram[offs+2]&0x00ff);
else
pri = 0;
x = spriteram[offs+1];
if (!((y&0x2000) && (machine->primary_screen->frame_number() & 1)));
{
if (!m_sprite_bitmap)
colour = (spriteram[offs+2] >>0) & 0x1f;
else
colour = (spriteram[offs+2] >>0) & 0xff; // store all bits for manual mixing
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;
if (x >= 432) x -= 512;
if (y >= 384) y -= 512;
if (fx) { mult=-16; x+=16; } else { mult=16; x-=16*w; }
if (fy) { mult2=-16; y+=16; } else { mult2=16; y-=16*h; }
}
for (int xx=0; xx<w; xx++)
{
for (int yy=0; yy<h; yy++)
{
if(!m_sprite_bitmap)
{
if (m_pricallback)
{
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite + yy + h * xx,
colour,
fx,fy,
x + mult * (w-xx),y + mult2 * (h-yy),
machine->priority_bitmap,pri,0);
// wrap-around y
pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion],
sprite + yy + h * xx,
colour,
fx,fy,
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);
// 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
{
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),
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);
}
}
}
}
}
offs+=incr;
}
@ -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
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)
fatalerror("decospr_device::inefficient_copy_sprite_bitmap with no m_sprite_bitmap");
@ -386,6 +507,8 @@ void decospr_device::inefficient_copy_sprite_bitmap(running_machine* machine, bi
srcline= BITMAP_ADDR16(m_sprite_bitmap, y, 0);
dstline= BITMAP_ADDR32(bitmap, y, 0);
if (alpha==0xff)
{
for (x=cliprect->min_x;x<=cliprect->max_x;x++)
{
UINT16 pix = srcline[x];
@ -399,4 +522,22 @@ void decospr_device::inefficient_copy_sprite_bitmap(running_machine* machine, bi
}
}
}
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 set_pri_callback(decospr_priority_callback_func callback);
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 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; };
protected:
@ -36,6 +37,7 @@ protected:
UINT8 m_gfxregion;
decospr_priority_callback_func m_pricallback;
bitmap_t *m_sprite_bitmap;// optional sprite bitmap (should be INDEXED16)
bool m_alt_format;
private:
};