From eae55a88b52f0a25253a925dccdef7cadab9d8ed Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Wed, 23 Mar 2011 23:52:08 +0000 Subject: [PATCH] More DECO 56 refactoring from Haze --- src/mame/drivers/cninja.c | 12 +- src/mame/drivers/deco32.c | 74 +++-- src/mame/includes/cninja.h | 1 + src/mame/video/cninja.c | 151 ++--------- src/mame/video/deco32.c | 109 +------- src/mame/video/decospr.c | 543 +++++++++++++++++++++++-------------- src/mame/video/decospr.h | 4 +- 7 files changed, 427 insertions(+), 467 deletions(-) diff --git a/src/mame/drivers/cninja.c b/src/mame/drivers/cninja.c index d0fb7115cf1..66facdf3acf 100644 --- a/src/mame/drivers/cninja.c +++ b/src/mame/drivers/cninja.c @@ -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") diff --git a/src/mame/drivers/deco32.c b/src/mame/drivers/deco32.c index 575e78d1157..96bef80555c 100644 --- a/src/mame/drivers/deco32.c +++ b/src/mame/drivers/deco32.c @@ -665,14 +665,35 @@ static WRITE32_HANDLER( nslasher_prot_w ) /**********************************************************************************/ +static READ32_HANDLER( deco32_spriteram_r ) +{ + deco32_state *state = space->machine->driver_data(); + return state->spriteram16[offset] ^ 0xffff0000; +} + +static WRITE32_HANDLER( deco32_spriteram_w ) +{ + deco32_state *state = space->machine->driver_data(); + data &= 0x0000ffff; + mem_mask &= 0x0000ffff; + COMBINE_DATA(&state->spriteram16[offset]); +} + +static WRITE32_HANDLER( deco32_buffer_spriteram_w ) +{ + deco32_state *state = space->machine->driver_data(); + 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(); - return state->spriteram16[offset] ^ 0xffff0000; -} -static WRITE32_HANDLER( deco32_spriteram_w ) -{ - deco32_state *state = space->machine->driver_data(); - data &= 0x0000ffff; - mem_mask &= 0x0000ffff; - COMBINE_DATA(&state->spriteram16[offset]); -} - -static WRITE32_HANDLER( deco32_buffer_spriteram_w ) -{ - deco32_state *state = space->machine->driver_data(); - 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) diff --git a/src/mame/includes/cninja.h b/src/mame/includes/cninja.h index 13d54a68cdd..d7722f833f1 100644 --- a/src/mame/includes/cninja.h +++ b/src/mame/includes/cninja.h @@ -39,6 +39,7 @@ public: /*----------- defined in video/cninja.c -----------*/ VIDEO_START( stoneage ); +VIDEO_START( mutantf ); SCREEN_UPDATE( cninja ); SCREEN_UPDATE( cninjabl ); diff --git a/src/mame/video/cninja.c b/src/mame/video/cninja.c index 1cd1348f161..4485bd04a75 100644 --- a/src/mame/video/cninja.c +++ b/src/mame/video/cninja.c @@ -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("spritegen1")->alloc_sprite_bitmap(machine); + machine->device("spritegen2")->alloc_sprite_bitmap(machine); +} + SCREEN_UPDATE( mutantf ) { cninja_state *state = screen->machine->driver_data(); 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("spritegen1")->set_alt_format(true); + screen->machine->device("spritegen2")->set_alt_format(true); + screen->machine->device("spritegen2")->draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram2.u16, 0x400, true); + screen->machine->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: @@ -381,26 +275,17 @@ SCREEN_UPDATE( mutantf ) deco16ic_tilemap_4_draw(state->deco16ic, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); 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("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 0x100, 0x1ff); + screen->machine->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("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("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; diff --git a/src/mame/video/deco32.c b/src/mame/video/deco32.c index eddb1af212e..8a24641c1e1 100644 --- a/src/mame/video/deco32.c +++ b/src/mame/video/deco32.c @@ -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; xgfx[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("spritegen")->set_alt_format(true); + screen->machine->device("spritegen")->draw_sprites(screen->machine, bitmap, cliprect, state->spriteram16_buffered, 0x400); return 0; } diff --git a/src/mame/video/decospr.c b/src/mame/video/decospr.c index 49c36518c9b..8b5e58519f2 100644 --- a/src/mame/video/decospr.c +++ b/src/mame/video/decospr.c @@ -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(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(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(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(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,150 +219,268 @@ 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; - sprite = spriteram[offs + 1]; - - y = spriteram[offs]; - flash = y & 0x1000; - xsize = y & 0x0800; - if (!(flash && (machine->primary_screen->frame_number() & 1))) + if (!m_alt_format) { - 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 - //colour *= 0x10; // for raw drawing - } + sprite = spriteram[offs + 1]; + y = spriteram[offs]; + flash = y & 0x1000; + w = y & 0x0800; + + + if (!(flash && (machine->primary_screen->frame_number() & 1))) + { + + 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) - pri = m_pricallback(x); + pri = m_pricallback(spriteram[offs+2]&0x00ff); else pri = 0; - fx = y & 0x2000; - fy = y & 0x4000; - multi = (1 << ((y & 0x0600) >> 9)) - 1; /* 1x, 2x, 4x, 8x height */ + x = spriteram[offs+1]; - if (cliprect->max_x>256) + if (!((y&0x2000) && (machine->primary_screen->frame_number() & 1))); { - 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; + if (!m_sprite_bitmap) + colour = (spriteram[offs+2] >>0) & 0x1f; else - { - sprite += multi; - inc = 1; - } + colour = (spriteram[offs+2] >>0) & 0xff; // store all bits for manual mixing - 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; - - 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; + 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; } } - else - mult = -16; - mult2 = multi + 1; - - while (multi >= 0) + for (int xx=0; xxgfx[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_sprite_bitmap) { if (m_pricallback) + { pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion], - (sprite - multi * inc)-mult2, + sprite + yy + h * xx, colour, fx,fy, - x-16,y + mult * multi, + x + mult * (w-xx),y + mult2 * (h-yy), machine->priority_bitmap,pri,0); - else - drawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion], - (sprite - multi * inc)-mult2, + + // wrap-around y + pdrawgfx_transpen(bitmap,cliprect,machine->gfx[m_gfxregion], + sprite + yy + h * xx, colour, 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); + + // 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 - { - // 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) - { + else + { 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); + 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); } } - - - - - 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 -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,16 +507,36 @@ 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); - for (x=cliprect->min_x;x<=cliprect->max_x;x++) + if (alpha==0xff) { - UINT16 pix = srcline[x]; - - if (pix&0xf) + for (x=cliprect->min_x;x<=cliprect->max_x;x++) { - 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); + } + } } } } diff --git a/src/mame/video/decospr.h b/src/mame/video/decospr.h index c5623acf283..a2bb7b2ec6f 100644 --- a/src/mame/video/decospr.h +++ b/src/mame/video/decospr.h @@ -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: };