From d1c6a3b04d150cbe77109728de3bdf8558702534 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Sat, 28 Jan 2012 15:37:24 +0000 Subject: [PATCH] Converted wizdfire to use generic deco functions [David Haywood] --- src/mame/drivers/cninja.c | 3 + src/mame/drivers/rohga.c | 21 +- src/mame/includes/rohga.h | 1 + src/mame/video/deco16ic.c | 7 + src/mame/video/deco16ic.h | 2 + src/mame/video/rohga.c | 425 ++++++++++---------------------------- 6 files changed, 140 insertions(+), 319 deletions(-) diff --git a/src/mame/drivers/cninja.c b/src/mame/drivers/cninja.c index afe258d8556..1d8edfa651c 100644 --- a/src/mame/drivers/cninja.c +++ b/src/mame/drivers/cninja.c @@ -1076,6 +1076,9 @@ static MACHINE_CONFIG_START( edrandy, cninja_state ) 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 */ MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM) diff --git a/src/mame/drivers/rohga.c b/src/mame/drivers/rohga.c index cfc19afae6f..1eba36b07a0 100644 --- a/src/mame/drivers/rohga.c +++ b/src/mame/drivers/rohga.c @@ -113,6 +113,7 @@ #include "sound/2151intf.h" #include "sound/okim6295.h" #include "video/decocomn.h" +#include "video/decospr.h" 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( "gfx2", 0, tilelayout, 0, 32 ) /* Gfx chip 1 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( "gfx5", 0, spritelayout, 1536, 32 ) + GFXDECODE_ENTRY( "gfx4", 0, spritelayout, 0, 32 ) /* Sprites 16x16 */ + GFXDECODE_ENTRY( "gfx5", 0, spritelayout, 0, 32 ) GFXDECODE_END 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("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 */ 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("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 */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") diff --git a/src/mame/includes/rohga.h b/src/mame/includes/rohga.h index 98e67e23dd0..e0fcdf03e54 100644 --- a/src/mame/includes/rohga.h +++ b/src/mame/includes/rohga.h @@ -45,6 +45,7 @@ public: WRITE16_HANDLER( rohga_buffer_spriteram16_w ); VIDEO_START( rohga ); +VIDEO_START( wizdfire ); SCREEN_UPDATE_IND16( rohga ); SCREEN_UPDATE_IND16( schmeisr ); diff --git a/src/mame/video/deco16ic.c b/src/mame/video/deco16ic.c index 139193da5ca..e8f929ab36c 100644 --- a/src/mame/video/deco16ic.c +++ b/src/mame/video/deco16ic.c @@ -345,6 +345,13 @@ static TILE_GET_INFO_DEVICE( get_pf1_tile_info_b ) flags); } +TIMER_DEVICE_CALLBACK( deco16_scantimer ) +{ + int scanline = param; + timer.machine().primary_screen->update_partial(scanline); +} + + /*****************************************************************************************/ /* diff --git a/src/mame/video/deco16ic.h b/src/mame/video/deco16ic.h index f8e1f6b292a..84ed34bb895 100644 --- a/src/mame/video/deco16ic.h +++ b/src/mame/video/deco16ic.h @@ -96,4 +96,6 @@ void deco16ic_set_scrolldx(device_t *device, int tmap, int size, int dx, int dx_ /* used by cninjabl */ void deco16ic_set_enable( device_t *device, int tmap, int enable ); +TIMER_DEVICE_CALLBACK( deco16_scantimer ); + #endif diff --git a/src/mame/video/rohga.c b/src/mame/video/rohga.c index 7893a9d3e7b..082dea78fa4 100644 --- a/src/mame/video/rohga.c +++ b/src/mame/video/rohga.c @@ -7,7 +7,7 @@ #include "emu.h" #include "includes/rohga.h" #include "video/deco16ic.h" - +#include "video/decospr.h" 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(); - 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 ) @@ -480,12 +172,103 @@ SCREEN_UPDATE_IND16( schmeisr ) return 0; } +VIDEO_START(wizdfire) +{ + machine.device("spritegen1")->alloc_sprite_bitmap(); + machine.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("spritegen1")->get_sprite_temp_bitmap(); + penbase = 0x400; + } + else + { + sprite_bitmap = &machine.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 ) { rohga_state *state = screen.machine().driver_data(); UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff); UINT16 priority = decocomn_priority_r(state->m_decocomn, 0, 0xffff); + /* draw sprite gfx to temp bitmaps */ + screen.machine().device("spritegen2")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 0x400, true); + screen.machine().device("spritegen1")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0x400, true); + /* Update playfields */ flip_screen_set(screen.machine(), BIT(flip, 7)); deco16ic_pf_update(state->m_deco_tilegen1, 0, 0); @@ -495,19 +278,18 @@ SCREEN_UPDATE_RGB32( wizdfire ) bitmap.fill(screen.machine().pens[512], cliprect); 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); - 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?! */ deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, TILEMAP_DRAW_ALPHA(0x80), 0); else deco16ic_tilemap_1_draw(state->m_deco_tilegen2, bitmap, cliprect, 0, 0); - /* See notes in wizdfire_draw_sprites about this */ - wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0, 3); - wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 2, 4); - wizdfire_draw_sprites(screen.machine(), bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 1, 4); + mixwizdfirelayer(screen.machine(), bitmap, cliprect, 0,3); + mixwizdfirelayer(screen.machine(), bitmap, cliprect, 2,4); + mixwizdfirelayer(screen.machine(), bitmap, cliprect, 1,4); deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0); return 0; @@ -518,6 +300,12 @@ SCREEN_UPDATE_RGB32( nitrobal ) rohga_state *state = screen.machine().driver_data(); UINT16 flip = deco16ic_pf_control_r(state->m_deco_tilegen1, 0, 0xffff); + /* draw sprite gfx to temp bitmaps */ + screen.machine().device("spritegen1")->set_alt_format(true); + screen.machine().device("spritegen2")->set_alt_format(true); + screen.machine().device("spritegen2")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram2.u16, 0x400, false); + screen.machine().device("spritegen1")->draw_sprites(bitmap, cliprect, screen.machine().generic.buffered_spriteram.u16, 0x400, false); + /* Update playfields */ flip_screen_set(screen.machine(), BIT(flip, 7)); 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_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("spritegen2")->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0000, 0x600, 0xff); + screen.machine().device("spritegen1")->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0000, 0x400, 0x1ff); + deco16ic_tilemap_1_draw(state->m_deco_tilegen1, bitmap, cliprect, 0, 0); return 0;