From 626c8b0fea99eb18823a426ef2e80d4d8a2d9639 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Wed, 23 Mar 2011 16:32:15 +0000 Subject: [PATCH] Haze: more of the same ... --- src/mame/drivers/cbuster.c | 13 ++-- src/mame/drivers/cninja.c | 4 ++ src/mame/drivers/mirage.c | 87 ++++----------------------- src/mame/drivers/sshangha.c | 113 ++++++++++++++++++++++++++--------- src/mame/includes/cbuster.h | 3 + src/mame/includes/deco32.h | 1 - src/mame/includes/sshangha.h | 5 ++ src/mame/video/cbuster.c | 91 +++++----------------------- src/mame/video/cninja.c | 75 +---------------------- src/mame/video/deco32.c | 51 ++-------------- src/mame/video/decospr.c | 105 ++++++++++++++++++++++++++++---- src/mame/video/decospr.h | 4 +- src/mame/video/sshangha.c | 105 +++++++------------------------- 13 files changed, 254 insertions(+), 403 deletions(-) diff --git a/src/mame/drivers/cbuster.c b/src/mame/drivers/cbuster.c index d114604b6ba..9b527f0b00f 100644 --- a/src/mame/drivers/cbuster.c +++ b/src/mame/drivers/cbuster.c @@ -24,7 +24,7 @@ #include "sound/2151intf.h" #include "sound/okim6295.h" #include "video/deco16ic.h" - +#include "video/decospr.h" static WRITE16_HANDLER( twocrude_control_w ) { @@ -33,7 +33,7 @@ static WRITE16_HANDLER( twocrude_control_w ) switch (offset << 1) { case 0: /* DMA flag */ - buffer_spriteram16_w(space, 0, 0, 0xffff); + memcpy(state->spriteram16_buffer, state->spriteram16, 0x800); return; case 6: /* IRQ ack */ @@ -118,7 +118,7 @@ static ADDRESS_MAP_START( twocrude_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x0ac000, 0x0ac7ff) AM_RAM AM_BASE_MEMBER(cbuster_state, pf3_rowscroll) AM_RANGE(0x0ae000, 0x0ae7ff) AM_RAM AM_BASE_MEMBER(cbuster_state, pf4_rowscroll) - AM_RANGE(0x0b0000, 0x0b07ff) AM_RAM AM_BASE_SIZE_GENERIC(spriteram) + AM_RANGE(0x0b0000, 0x0b07ff) AM_RAM AM_BASE_MEMBER(cbuster_state, spriteram16) AM_RANGE(0x0b4000, 0x0b4001) AM_WRITENOP AM_RANGE(0x0b5000, 0x0b500f) AM_DEVWRITE("deco_custom", deco16ic_pf12_control_w) AM_RANGE(0x0b6000, 0x0b600f) AM_DEVWRITE("deco_custom", deco16ic_pf34_control_w) @@ -326,21 +326,22 @@ static MACHINE_CONFIG_START( twocrude, cbuster_state ) MCFG_MACHINE_START(cbuster) MCFG_MACHINE_RESET(cbuster) - /* video hardware */ - MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(58) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529)) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MCFG_SCREEN_SIZE(32*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1) MCFG_SCREEN_UPDATE(twocrude) + MCFG_VIDEO_START(twocrude) MCFG_GFXDECODE(cbuster) MCFG_PALETTE_LENGTH(2048) MCFG_DECO16IC_ADD("deco_custom", twocrude_deco16ic_intf) + MCFG_DEVICE_ADD("spritegen", decospr_, 0) + decospr_device_config::set_gfx_region(device, 3); /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/cninja.c b/src/mame/drivers/cninja.c index 7ea6ea15ef3..d0fb7115cf1 100644 --- a/src/mame/drivers/cninja.c +++ b/src/mame/drivers/cninja.c @@ -842,6 +842,7 @@ static MACHINE_RESET( cninja ) state->irq_mask = 0; } + UINT16 cninja_pri_callback(UINT16 x) { /* Sprite/playfield priority */ @@ -1082,6 +1083,9 @@ static MACHINE_CONFIG_START( robocop2, cninja_state ) MCFG_PALETTE_LENGTH(2048) MCFG_DECO16IC_ADD("deco_custom", robocop2_deco16ic_intf) + MCFG_DEVICE_ADD("spritegen", decospr_, 0) + decospr_device_config::set_gfx_region(device, 3); + decospr_device_config::set_pri_callback(device, cninja_pri_callback); /* sound hardware */ MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") diff --git a/src/mame/drivers/mirage.c b/src/mame/drivers/mirage.c index 10d5c86a962..1de844f2ced 100644 --- a/src/mame/drivers/mirage.c +++ b/src/mame/drivers/mirage.c @@ -38,6 +38,7 @@ MR_01-.3A [a0b758aa] #include "includes/decoprot.h" #include "video/deco16ic.h" #include "sound/okim6295.h" +#include "video/decospr.h" class mirage_state : public driver_device { @@ -66,78 +67,9 @@ public: required_device oki_bgm; }; - -static void draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int pri ) +static VIDEO_START( mirage ) { - //mirage_state *state = machine->driver_data(); - UINT16 *spriteram = machine->generic.buffered_spriteram.u16;//state->spriteram; - int offs; - - for (offs = 0; offs < 0x400; offs += 4) - { - int x, y, sprite, colour, multi, fx, fy, inc, flash, mult; - - sprite = spriteram[offs + 1]; - if (!sprite) - continue; - - y = spriteram[offs]; - flash = y & 0x1000; - - if (flash && (machine->primary_screen->frame_number() & 1)) - continue; - - if (pri != ((y & 0x8000) >> 15)) - continue; - - x = spriteram[offs + 2]; - colour = (x >> 9) & 0x1f; - - 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; - y = 240 - y; - x = 304 - x; - - if (x > 320) - continue; - - sprite &= ~multi; - if (fy) - inc = -1; - else - { - sprite += multi; - inc = 1; - } - - if (flip_screen_get(machine)) - { - y =240 - y; - x =304 - x; - if (fx) fx = 0; else fx = 1; - if (fy) fy = 0; else fy = 1; - mult = 16; - } - else mult = -16; - - while (multi >= 0) - { - drawgfx_transpen(bitmap,cliprect,machine->gfx[2], - sprite - multi * inc, - colour, - fx,fy, - x,y + mult * multi,0); - - multi--; - } - } + machine->device("spritegen")->alloc_sprite_bitmap(machine); } static SCREEN_UPDATE( mirage ) @@ -146,14 +78,17 @@ static SCREEN_UPDATE( mirage ) UINT16 flip = deco16ic_pf12_control_r(state->deco16ic, 0, 0xffff); flip_screen_set(screen->machine, BIT(flip, 7)); + + screen->machine->device("spritegen")->draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram.u16, 0x400); + deco16ic_pf12_update(state->deco16ic, state->pf1_rowscroll, state->pf2_rowscroll); bitmap_fill(bitmap, cliprect, 256); /* not verified */ deco16ic_tilemap_2_draw(state->deco16ic, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); - draw_sprites(screen->machine, bitmap, cliprect, 1); + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0800, 0x0800, 0x200, 0x1ff); deco16ic_tilemap_1_draw(state->deco16ic, bitmap, cliprect, 0, 0); - draw_sprites(screen->machine, bitmap, cliprect, 0); + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0800, 0x200, 0x1ff); return 0; } @@ -396,16 +331,20 @@ static MACHINE_CONFIG_START( mirage, mirage_state ) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(58) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529)) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MCFG_SCREEN_SIZE(40*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1) MCFG_SCREEN_UPDATE(mirage) MCFG_SCREEN_EOF(mirage) + MCFG_VIDEO_START(mirage) + MCFG_GFXDECODE(mirage) MCFG_PALETTE_LENGTH(1024) MCFG_DECO16IC_ADD("deco_custom", mirage_deco16ic_intf) + MCFG_DEVICE_ADD("spritegen", decospr_, 0) + decospr_device_config::set_gfx_region(device, 2); /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/drivers/sshangha.c b/src/mame/drivers/sshangha.c index 256590c96ae..fb103bca666 100644 --- a/src/mame/drivers/sshangha.c +++ b/src/mame/drivers/sshangha.c @@ -18,6 +18,11 @@ Emulation by Bryan McPhail, mish@tendril.co.uk + ToDo: + + Palette handling is somewhat hacked, see paletteram16_xbgr_word_be_sprites_w + + ---- Stephh's notes (based on the games M68000 code and some tests) : @@ -38,17 +43,6 @@ Stephh's notes (based on the games M68000 code and some tests) : - The "Use Mahjong Tiles" Dip Switch only has an effect when playing "Shanghai Advanced". -1) 'sshangha' - - - There are writes to 0x100000-0x10000f (code from 0x000964 to 0x000a8c), - but their effect is unknown. - -2) 'sshanghb' - - - There are writes to 0x101000-0x10100f (code from 0x000964 to 0x000a8c), - but their effect is unknown. Note that the code is the SAME as the one - in 'sshangha' (only the 0x10?00? addresses are different). - ***************************************************************************/ #include "emu.h" @@ -57,6 +51,7 @@ Stephh's notes (based on the games M68000 code and some tests) : #include "sound/2203intf.h" #include "sound/okim6295.h" #include "includes/sshangha.h" +#include "video/decospr.h" #define SSHANGHA_HACK 0 @@ -130,6 +125,56 @@ static MACHINE_RESET( sshangha ) /******************************************************************************/ +/*------------------------------------------------- + set_color_8888 - set a 8-8-8 RGB color using + the 32-bit data provided and the specified + shift values +-------------------------------------------------*/ + + + + +INLINE void set_color_888(running_machine *machine, pen_t color, int rshift, int gshift, int bshift, UINT32 data) +{ + palette_set_color_rgb(machine, color, (data >> rshift) & 0xff, (data >> gshift) & 0xff, (data >> bshift) & 0xff); +} + + +WRITE16_HANDLER( paletteram16_xbgr_word_be_sprites2_w ) +{ + sshangha_state *state = space->machine->driver_data(); + COMBINE_DATA(&state->sprite_paletteram2[offset]); + set_color_888(space->machine, (offset/2)+0x100, 0, 8, 16, state->sprite_paletteram2[(offset) | 1] | (state->sprite_paletteram2[(offset) & ~1] << 16) ); +} + +WRITE16_HANDLER( paletteram16_xbgr_word_be_sprites_w ) +{ + // hack??? we have to call this otherwise the sprite colours for some selected tiles are wrong (most noticable on the 2nd level of quest mode) + // however if we simply mirror the memory both ways the how to play screen ends up with bad colours + // we use the 2nd copy of palette ram for low priority tiles only.. + // is this related to the bootleg only, or does the original have this issue too? + // maybe related to sprite DMA on the original, or the apparent lack of a 2nd sprite controller on the bootleg. + paletteram16_xbgr_word_be_sprites2_w(space,offset,data,mem_mask); + + sshangha_state *state = space->machine->driver_data(); + COMBINE_DATA(&state->sprite_paletteram[offset]); + set_color_888(space->machine, (offset/2)+0x000, 0, 8, 16, state->sprite_paletteram[(offset) | 1] | (state->sprite_paletteram[(offset) & ~1] << 16) ); +} + +WRITE16_HANDLER( paletteram16_xbgr_word_be_tilelow_w ) +{ + sshangha_state *state = space->machine->driver_data(); + COMBINE_DATA(&state->tile_paletteram1[offset]); + set_color_888(space->machine, (offset/2)+0x200, 0, 8, 16, state->tile_paletteram1[(offset) | 1] | (state->tile_paletteram1[(offset) & ~1] << 16) ); +} + +WRITE16_HANDLER( paletteram16_xbgr_word_be_tilehigh_w ) +{ + sshangha_state *state = space->machine->driver_data(); + COMBINE_DATA(&state->tile_paletteram2[offset]); + set_color_888(space->machine, (offset/2)+0x300, 0, 8, 16, state->tile_paletteram2[(offset) | 1] | (state->tile_paletteram2[(offset) & ~1] << 16) ); +} + static ADDRESS_MAP_START( sshangha_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x000000, 0x03ffff) AM_ROM AM_RANGE(0x100000, 0x10000f) AM_RAM AM_BASE_MEMBER(sshangha_state, sound_shared_ram) @@ -150,8 +195,13 @@ static ADDRESS_MAP_START( sshangha_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x360000, 0x360fff) AM_RAM AM_BASE_GENERIC(spriteram2) AM_RANGE(0x370000, 0x370001) AM_READ(deco_71_r) AM_RANGE(0x370000, 0x370007) AM_WRITENOP - AM_RANGE(0x380000, 0x383fff) AM_RAM_WRITE(paletteram16_xbgr_word_be_w) AM_BASE_GENERIC(paletteram) - AM_RANGE(0x3c0000, 0x3c0fff) AM_RAM /* Sprite ram buffer on bootleg only?? */ + + AM_RANGE(0x380000, 0x3803ff) AM_RAM_WRITE(paletteram16_xbgr_word_be_sprites_w) AM_BASE_MEMBER(sshangha_state, sprite_paletteram) + AM_RANGE(0x380400, 0x3807ff) AM_RAM_WRITE(paletteram16_xbgr_word_be_tilehigh_w) AM_BASE_MEMBER(sshangha_state, tile_paletteram2) + AM_RANGE(0x380800, 0x380bff) AM_RAM_WRITE(paletteram16_xbgr_word_be_sprites2_w) AM_BASE_MEMBER(sshangha_state, sprite_paletteram2) + AM_RANGE(0x380c00, 0x380fff) AM_RAM_WRITE(paletteram16_xbgr_word_be_tilelow_w) AM_BASE_MEMBER(sshangha_state, tile_paletteram1) + AM_RANGE(0x381000, 0x383fff) AM_RAM // unused palette area + AM_RANGE(0xfec000, 0xff3fff) AM_RAM AM_RANGE(0xff4000, 0xff47ff) AM_READWRITE(sshangha_protection16_r,sshangha_protection16_w) AM_BASE_MEMBER(sshangha_state, prot_data) ADDRESS_MAP_END @@ -171,14 +221,15 @@ static ADDRESS_MAP_START( sshanghb_map, ADDRESS_SPACE_PROGRAM, 16 ) AM_RANGE(0x320002, 0x320005) AM_WRITENOP AM_RANGE(0x320006, 0x320007) AM_READNOP //irq ack - AM_RANGE(0x340000, 0x340fff) AM_RAM AM_BASE_GENERIC(spriteram) - AM_RANGE(0x350000, 0x350001) AM_READ(deco_71_r) - AM_RANGE(0x350000, 0x350007) AM_WRITENOP - AM_RANGE(0x360000, 0x360fff) AM_RAM AM_BASE_GENERIC(spriteram2) - AM_RANGE(0x370000, 0x370001) AM_READ(deco_71_r) - AM_RANGE(0x370000, 0x370007) AM_WRITENOP - AM_RANGE(0x380000, 0x383fff) AM_RAM_WRITE(paletteram16_xbgr_word_be_w) AM_BASE_GENERIC(paletteram) - AM_RANGE(0x3c0000, 0x3c0fff) AM_RAM /* Sprite ram buffer on bootleg only?? */ + AM_RANGE(0x340000, 0x340fff) AM_RAM // original spriteram + + AM_RANGE(0x380000, 0x3803ff) AM_RAM_WRITE(paletteram16_xbgr_word_be_sprites_w) AM_BASE_MEMBER(sshangha_state, sprite_paletteram) + AM_RANGE(0x380400, 0x3807ff) AM_RAM_WRITE(paletteram16_xbgr_word_be_tilehigh_w) AM_BASE_MEMBER(sshangha_state, tile_paletteram2) + AM_RANGE(0x380800, 0x380bff) AM_RAM_WRITE(paletteram16_xbgr_word_be_sprites2_w) AM_BASE_MEMBER(sshangha_state, sprite_paletteram2) + AM_RANGE(0x380c00, 0x380fff) AM_RAM_WRITE(paletteram16_xbgr_word_be_tilelow_w) AM_BASE_MEMBER(sshangha_state, tile_paletteram1) + AM_RANGE(0x381000, 0x383fff) AM_RAM // unused palette area + + AM_RANGE(0x3c0000, 0x3c0fff) AM_RAM AM_BASE_GENERIC(spriteram) // bootleg spriteram AM_RANGE(0xfec000, 0xff3fff) AM_RAM AM_RANGE(0xff4000, 0xff47ff) AM_RAM ADDRESS_MAP_END @@ -323,9 +374,9 @@ static const gfx_layout tilelayout = }; static GFXDECODE_START( sshangha ) - GFXDECODE_ENTRY( "gfx1", 0, charlayout, 256, 64 ) /* Characters 8x8 */ - GFXDECODE_ENTRY( "gfx1", 0, tilelayout, 256, 64 ) /* Tiles 16x16 */ - GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 32 ) /* Sprites 16x16 */ + GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0x200, 64 ) /* Characters 8x8 */ + GFXDECODE_ENTRY( "gfx1", 0, tilelayout, 0x200, 64 ) /* Tiles 16x16 */ + GFXDECODE_ENTRY( "gfx2", 0, tilelayout, 0, 64 ) /* Sprites 16x16 */ GFXDECODE_END /******************************************************************************/ @@ -359,19 +410,23 @@ static MACHINE_CONFIG_START( sshangha, sshangha_state ) MCFG_MACHINE_RESET(sshangha) /* init machine */ - /* video hardware */ - /*MCFG_VIDEO_ATTRIBUTES(VIDEO_BUFFERS_SPRITERAM)*/ - MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_REFRESH_RATE(60) MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(529)) - MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) + MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MCFG_SCREEN_SIZE(40*8, 32*8) MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1) MCFG_SCREEN_UPDATE(sshangha) MCFG_GFXDECODE(sshangha) - MCFG_PALETTE_LENGTH(4096) + MCFG_PALETTE_LENGTH(0x4000) + + MCFG_DEVICE_ADD("spritegen1", decospr_, 0) + decospr_device_config::set_gfx_region(device, 2); + + MCFG_DEVICE_ADD("spritegen2", decospr_, 0) + decospr_device_config::set_gfx_region(device, 2); + MCFG_VIDEO_START(sshangha) diff --git a/src/mame/includes/cbuster.h b/src/mame/includes/cbuster.h index 18b8419c487..6d8785229ed 100644 --- a/src/mame/includes/cbuster.h +++ b/src/mame/includes/cbuster.h @@ -16,6 +16,8 @@ public: UINT16 * pf3_rowscroll; UINT16 * pf4_rowscroll; UINT16 * ram; + UINT16 * spriteram16; + UINT16 spriteram16_buffer[0x400]; /* misc */ UINT16 prot; @@ -34,4 +36,5 @@ public: WRITE16_HANDLER( twocrude_palette_24bit_rg_w ); WRITE16_HANDLER( twocrude_palette_24bit_b_w ); +VIDEO_START( twocrude ); SCREEN_UPDATE( twocrude ); diff --git a/src/mame/includes/deco32.h b/src/mame/includes/deco32.h index cd0e756ea6c..91eeb2829bb 100644 --- a/src/mame/includes/deco32.h +++ b/src/mame/includes/deco32.h @@ -61,7 +61,6 @@ public: int has_ace_ram; int last_pf3_bank; - bitmap_t* temp_bitmap_sprites; UINT16 spriteram16[0x1000]; UINT16 spriteram16_buffered[0x1000]; diff --git a/src/mame/includes/sshangha.h b/src/mame/includes/sshangha.h index bb3cab13e0c..6f733b212f6 100644 --- a/src/mame/includes/sshangha.h +++ b/src/mame/includes/sshangha.h @@ -19,6 +19,11 @@ public: int video_control; int last_pf1_bank; int last_pf2_bank; + + UINT16* sprite_paletteram; + UINT16* sprite_paletteram2; + UINT16* tile_paletteram1; + UINT16* tile_paletteram2; }; diff --git a/src/mame/video/cbuster.c b/src/mame/video/cbuster.c index 30931dff6df..a902078d74a 100644 --- a/src/mame/video/cbuster.c +++ b/src/mame/video/cbuster.c @@ -7,9 +7,12 @@ #include "emu.h" #include "includes/cbuster.h" #include "video/deco16ic.h" +#include "video/decospr.h" /******************************************************************************/ +/* maybe the game should just use generic palette handling, and have a darker palette by design... */ + static void update_24bitcol( running_machine *machine, int offset ) { UINT8 r, g, b; /* The highest palette value seems to be 0x8e */ @@ -36,83 +39,14 @@ WRITE16_HANDLER( twocrude_palette_24bit_b_w ) /******************************************************************************/ -static void draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int pri ) -{ - UINT16 *buffered_spriteram = machine->generic.buffered_spriteram.u16; - int offs; - - for (offs = 0; offs < 0x400; offs += 4) - { - int x, y, sprite, colour, multi, fx, fy, inc, flash, mult; - - sprite = buffered_spriteram[offs + 1] & 0x7fff; - if (!sprite) - continue; - - y = buffered_spriteram[offs]; - x = buffered_spriteram[offs + 2]; - - if ((y & 0x8000) && pri == 1) - continue; - if (!(y & 0x8000) && pri == 0) - continue; - - colour = (x >> 9) & 0xf; - if (x & 0x2000) - colour += 64; - - flash = y & 0x1000; - if (flash && (machine->primary_screen->frame_number() & 1)) - continue; - - 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 >= 256) x -= 512; - if (y >= 256) y -= 512; - x = 240 - x; - y = 240 - y; - - if (x > 256) - continue; /* Speedup */ - - sprite &= ~multi; - if (fy) - inc = -1; - else - { - sprite += multi; - inc = 1; - } - - if (flip_screen_get(machine)) - { - y = 240 - y; - x = 240 - x; - if (fx) fx = 0; else fx = 1; - if (fy) fy = 0; else fy = 1; - mult = 16; - } - else mult = -16; - - while (multi >= 0) - { - drawgfx_transpen(bitmap,cliprect,machine->gfx[3], - sprite - multi * inc, - colour, - fx,fy, - x,y + mult * multi,0); - - multi--; - } - } -} /******************************************************************************/ +VIDEO_START( twocrude ) +{ + machine->device("spritegen")->alloc_sprite_bitmap(machine); +} + SCREEN_UPDATE( twocrude ) { cbuster_state *state = screen->machine->driver_data(); @@ -120,12 +54,16 @@ SCREEN_UPDATE( twocrude ) flip_screen_set(screen->machine, !BIT(flip, 7)); + screen->machine->device("spritegen")->draw_sprites(screen->machine, bitmap, cliprect, state->spriteram16_buffer, 0x400); + + deco16ic_pf12_update(state->deco16ic, state->pf1_rowscroll, state->pf2_rowscroll); deco16ic_pf34_update(state->deco16ic, state->pf3_rowscroll, state->pf4_rowscroll); /* Draw playfields & sprites */ deco16ic_tilemap_4_draw(state->deco16ic, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0); - draw_sprites(screen->machine, bitmap, cliprect, 0); + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0800, 0x0900, 0x100, 0x0ff); + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0900, 0x0900, 0x500, 0x0ff); if (state->pri) { @@ -138,7 +76,8 @@ SCREEN_UPDATE( twocrude ) deco16ic_tilemap_2_draw(state->deco16ic, bitmap, cliprect, 0, 0); } - draw_sprites(screen->machine, bitmap, cliprect, 1); + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0900, 0x100, 0x0ff); + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0100, 0x0900, 0x500, 0x0ff); deco16ic_tilemap_1_draw(state->deco16ic, bitmap, cliprect, 0, 0); return 0; } diff --git a/src/mame/video/cninja.c b/src/mame/video/cninja.c index bf795c3df61..1cd1348f161 100644 --- a/src/mame/video/cninja.c +++ b/src/mame/video/cninja.c @@ -122,79 +122,6 @@ static void cninjabl_draw_sprites( running_machine *machine, bitmap_t *bitmap, c } -static void robocop2_draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect ) -{ - UINT16 *buffered_spriteram = machine->generic.buffered_spriteram.u16; - int offs; - - for (offs = 0x400 - 4; offs >=0 ; offs -= 4) - { - int x, y, sprite, colour, multi, fx, fy, inc, flash, mult, pri = 0; - sprite = buffered_spriteram[offs + 1]; - if (!sprite) - continue; - - x = buffered_spriteram[offs + 2]; - - /* Sprite/playfield priority */ - switch (x & 0xc000) - { - case 0x0000: pri = 0; break; - case 0x4000: pri = 0xf0; break; - case 0x8000: pri = 0xf0 | 0xcc; break; - case 0xc000: pri = 0xf0 | 0xcc; break; /* Perhaps 0xf0|0xcc|0xaa (Sprite under bottom layer) */ - } - - y = buffered_spriteram[offs]; - flash = y & 0x1000; - if (flash && (machine->primary_screen->frame_number() & 1)) - continue; - colour = (x >> 9) & 0x1f; - - 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; - x = 304 - x; - y = 240 - y; - - sprite &= ~multi; - if (fy) - inc = -1; - else - { - sprite += multi; - inc = 1; - } - - if (flip_screen_get(machine)) - { - y = 240 - y; - x = 304 - x; - if (fx) fx = 0; else fx = 1; - if (fy) fy = 0; else fy = 1; - mult = 16; - } - else - mult = -16; - - while (multi >= 0) - { - pdrawgfx_transpen(bitmap,cliprect,machine->gfx[3], - sprite - multi * inc, - colour, - fx,fy, - x,y + mult * multi, - machine->priority_bitmap,pri,0); - - multi--; - } - } -} static void mutantf_draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, const UINT16 *spriteptr, int gfxbank ) { @@ -422,7 +349,7 @@ SCREEN_UPDATE( robocop2 ) break; } - robocop2_draw_sprites(screen->machine, bitmap, cliprect); + screen->machine->device("spritegen")->draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.buffered_spriteram.u16, 0x400); 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 aadf463de39..eddb1af212e 100644 --- a/src/mame/video/deco32.c +++ b/src/mame/video/deco32.c @@ -933,10 +933,7 @@ VIDEO_START( fghthist ) state->pf1a_tilemap =0; state->dirty_palette = auto_alloc_array(machine, UINT8, 4096); - int width = machine->primary_screen->width(); - int height = machine->primary_screen->height(); - state->temp_bitmap_sprites = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_INDEXED16); - machine->device("spritegen")->set_sprite_bitmap(state->temp_bitmap_sprites); + machine->device("spritegen")->alloc_sprite_bitmap(machine); tilemap_set_transparent_pen(state->pf1_tilemap,0); tilemap_set_transparent_pen(state->pf2_tilemap,0); @@ -1288,52 +1285,12 @@ SCREEN_UPDATE( dragngun ) return 0; } -// inefficient, we should be able to mix in a single pass by comparing the existing priority bitmap from the tilemaps -// mixing is also still wrong for some levels (it was before this rewrite of the code also) -void fghthist_mix_sprites(running_machine* machine, bitmap_t *bitmap, const rectangle *cliprect, bool hipriority) -{ - deco32_state *state = machine->driver_data(); - - int y, x; - const pen_t *paldata = machine->pens; - - UINT16* srcline; - UINT32* dstline; - - for (y=cliprect->min_y;y<=cliprect->max_y;y++) - { - srcline= BITMAP_ADDR16(state->temp_bitmap_sprites, y, 0); - dstline= BITMAP_ADDR32(bitmap, y, 0); - - for (x=cliprect->min_x;x<=cliprect->max_x;x++) - { - UINT16 pix = srcline[x]; - - if (pix&0xf) - { - if (hipriority) - { - if (!(pix&0x800)) - dstline[x] = paldata[(pix&0x1ff) + 1024]; - } - else - { - if ((pix&0x800)) - dstline[x] = paldata[(pix&0x1ff) + 1024]; - } - - } - } - } - -} SCREEN_UPDATE( fghthist ) { deco32_state *state = screen->machine->driver_data(); bitmap_fill(screen->machine->priority_bitmap,cliprect,0); - bitmap_fill(state->temp_bitmap_sprites, cliprect, 0); bitmap_fill(bitmap,cliprect,screen->machine->pens[0x000]); // Palette index not confirmed screen->machine->device("spritegen")->draw_sprites(screen->machine, bitmap, cliprect, state->spriteram16_buffered, 0x800, true); @@ -1378,17 +1335,17 @@ SCREEN_UPDATE( fghthist ) if(state->pri&1) { tilemap_draw(bitmap,cliprect,state->pf2_tilemap,0,2); - fghthist_mix_sprites(screen->machine, bitmap, cliprect, false); // lower pri sprites from bitmap + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0800, 0x0800, 1024, 0x1ff); tilemap_draw(bitmap,cliprect,state->pf3_tilemap,0,4); } else { tilemap_draw(bitmap,cliprect,state->pf3_tilemap,0,2); - fghthist_mix_sprites(screen->machine, bitmap, cliprect, false); // lower pri sprites from bitmap + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0800, 0x0800, 1024, 0x1ff); tilemap_draw(bitmap,cliprect,state->pf2_tilemap,0,4); } - fghthist_mix_sprites(screen->machine, bitmap, cliprect, true); // hig pri sprites from bitmap + screen->machine->device("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0800, 1024, 0x1ff); tilemap_draw(bitmap,cliprect,state->pf1_tilemap,0,0); return 0; diff --git a/src/mame/video/decospr.c b/src/mame/video/decospr.c index e16e9d5c8a8..49c36518c9b 100644 --- a/src/mame/video/decospr.c +++ b/src/mame/video/decospr.c @@ -5,7 +5,7 @@ some games have different visible areas, but are confirmed as the same sprite chip. games with alpha aren't supported here yet, in most cases they need better mixing anyway, probably rendering to screen buffers and manual mixing. - see m_sprite_bitmap... + see m_sprite_bitmap... (note, if using that you must also use BITMAP_FORMAT_RGB32 in the machine config) used by: @@ -18,19 +18,19 @@ pktgaldx.c backfire.c darkseal.c + 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) 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 - lemmings.c - priority stuff + lemmings.c - priority stuff (plus sprites seem somewhat different anyway??) dassault.c - video mixing - deco32.c - video mixing - cbuster.c - needs updating to use proper priority (pdrawgfx), not multipass - mirage.c - needs updating to use proper priority (pdrawgfx), not multipass - - many more + boogwing.c - video mixing */ @@ -97,9 +97,9 @@ void decospr_device::decospr_sprite_kludge(int x, int y) } */ -void decospr_device::set_sprite_bitmap(bitmap_t* bitmap) +void decospr_device::alloc_sprite_bitmap(running_machine* machine) { - m_sprite_bitmap = bitmap; + 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) @@ -110,15 +110,17 @@ void decospr_device::set_pri_callback(decospr_priority_callback_func callback) /* +STANDARD FORMAT + offs +0 -------- -------- efFbSssy yyyyyyyy -s = size (multipart) -S = size (x?) (double wings) +s = size (height) +S = size (width) (double wings) f = flipy -b = flash F = flipx +b = flash/blink y = ypos e = extra priority bit (or at least externally detectable by mixer circuits) @@ -136,6 +138,48 @@ c = colour palette p = priority x = xpos +offs +3 +-------- -------- (unused) + +in reality all the colour / priority (and extra priority) bits are externally detectable and can be used for +priority and mixing, the sprite palette in twocrude for example isn't in a single block (there is a gap for the tilemaps) +but the mixing circuits take care of this + +ALTERNATE FORMAT (used by Mutant Fighter, Captain America) + +offs +0 +-------- -------- +fFbyyyyy yyyyyyyy + +f = flipy +F = flipx +b = flash/blink +y = ypos + +offs +1 +-------- -------- +xxxxxxxx xxxxxxxx + +x = xpos + +offs +2 +-------- -------- +ssssSSSS pppccccc + +s = size (height) +S = size (width) (double wings) + +offs +3 +-------- -------- +tttttttt tttttttt + +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 + */ @@ -145,6 +189,10 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c if (m_sprite_bitmap && m_pricallback) fatalerror("m_sprite_bitmap && m_pricallback is invalid"); + if (m_sprite_bitmap) + bitmap_fill(m_sprite_bitmap, cliprect, 0); + + int offs, end, incr; int flipscreen = flip_screen_get(machine); @@ -319,3 +367,36 @@ void decospr_device::draw_sprites( running_machine *machine, bitmap_t *bitmap, c offs+=incr; } } + + +// 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) +{ + if (!m_sprite_bitmap) + fatalerror("decospr_device::inefficient_copy_sprite_bitmap with no m_sprite_bitmap"); + + int y, x; + const pen_t *paldata = machine->pens; + + UINT16* srcline; + UINT32* dstline; + + for (y=cliprect->min_y;y<=cliprect->max_y;y++) + { + srcline= BITMAP_ADDR16(m_sprite_bitmap, y, 0); + dstline= BITMAP_ADDR32(bitmap, y, 0); + + for (x=cliprect->min_x;x<=cliprect->max_x;x++) + { + UINT16 pix = srcline[x]; + + if (pix&0xf) + { + if ((pix & priority_mask) ==pri ) + { + dstline[x] = paldata[(pix&palmask) + colbase]; + } + } + } + } +} \ No newline at end of file diff --git a/src/mame/video/decospr.h b/src/mame/video/decospr.h index 42754824084..c5623acf283 100644 --- a/src/mame/video/decospr.h +++ b/src/mame/video/decospr.h @@ -25,7 +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_sprite_bitmap(bitmap_t* bitmap); + 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); + bitmap_t* get_sprite_temp_bitmap(void) { return m_sprite_bitmap; }; protected: virtual void device_start(); diff --git a/src/mame/video/sshangha.c b/src/mame/video/sshangha.c index 89f863487bf..8f0d87592f9 100644 --- a/src/mame/video/sshangha.c +++ b/src/mame/video/sshangha.c @@ -7,7 +7,7 @@ #include "emu.h" #include "includes/sshangha.h" - +#include "video/decospr.h" /******************************************************************************/ @@ -17,13 +17,14 @@ static void sshangha_tilemap_draw(running_machine *machine, bitmap_t *bitmap, co const bitmap_t *bitmap0 = tilemap_get_pixmap(state->pf1_16x16_tilemap); const bitmap_t *bitmap1 = tilemap_get_pixmap(state->pf2_tilemap); int x,y,p; + const pen_t *pens = machine->pens; for (y=0; y<240; y++) { for (x=0; x<320; x++) { p=*BITMAP_ADDR16(bitmap0, y, x)&0xf; p|=(*BITMAP_ADDR16(bitmap1, y, x)&0xf)<<4; - *BITMAP_ADDR16(bitmap, y, x) = p|0x300; + *BITMAP_ADDR32(bitmap, y, x) = pens[p|0x200]; } } } @@ -38,72 +39,6 @@ WRITE16_HANDLER (sshangha_video_w) /******************************************************************************/ -static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, UINT16 *spritesrc, UINT16 pmask, UINT16 pval) -{ - int offs; - - for (offs = 0;offs < 0x800;offs += 4) - { - int x,y,sprite,colour,multi,fx,fy,inc,flash,mult; - - sprite = spritesrc[offs+1] & 0x3fff; - if (!sprite) continue; - - if ((spritesrc[offs+2]&pmask)!=pval) - continue; - - y = spritesrc[offs]; - flash=y&0x1000; - if (flash && (machine->primary_screen->frame_number() & 1)) continue; - - x = spritesrc[offs+2]; - colour = (x >>9) & 0x1f; - - 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 (flip_screen_get(machine)) - { - y=240-y; - x=304-x; - if (fx) fx=0; else fx=1; - if (fy) fy=0; else fy=1; - mult=-16; - } - - if (fy) - inc = -1; - else - { - sprite += multi; - inc = 1; - } - - mult=+16; - - if (fx) fx=0; else fx=1; - if (fy) fy=0; else fy=1; - - while (multi >= 0) - { - drawgfx_transpen(bitmap,cliprect,machine->gfx[2], - sprite - multi * inc, - colour, - fx,fy, - x,y + mult * multi,0); - - multi--; - } - } -} /******************************************************************************/ @@ -130,33 +65,25 @@ WRITE16_HANDLER( sshangha_control_0_w ) /******************************************************************************/ -#if 0 -static UINT32 sshangha_scan(UINT32 col,UINT32 row,UINT32 num_cols,UINT32 num_rows) -{ - /* logical (col,row) -> memory offset */ - return (col & 0x1f) + ((row & 0x1f) << 5) + ((col & 0x20) << 5); -} -#endif - static TILE_GET_INFO( get_pf2_tile_info ) { sshangha_state *state = machine->driver_data(); UINT16 tile=state->pf2_data[tile_index]; - SET_TILE_INFO(1,(tile&0xfff)|state->pf2_bank,(tile>>12)|32,0); + SET_TILE_INFO(1,(tile&0xfff)|state->pf2_bank,(tile>>12),0); } static TILE_GET_INFO( get_pf1_16x16_tile_info ) { sshangha_state *state = machine->driver_data(); UINT16 tile=state->pf1_data[tile_index]; - SET_TILE_INFO(1,(tile&0xfff)|state->pf1_bank,tile>>12,0); + SET_TILE_INFO(1,(tile&0xfff)|state->pf1_bank,(tile>>12)+0x10,0); } static TILE_GET_INFO( get_pf1_8x8_tile_info ) { sshangha_state *state = machine->driver_data(); UINT16 tile=state->pf1_data[tile_index]; - SET_TILE_INFO(0,(tile&0xfff)|state->pf1_bank,tile>>12,0); + SET_TILE_INFO(0,(tile&0xfff)|state->pf1_bank,(tile>>12)+0x10,0); } VIDEO_START( sshangha ) @@ -166,6 +93,9 @@ VIDEO_START( sshangha ) state->pf1_16x16_tilemap = tilemap_create(machine, get_pf1_16x16_tile_info,tilemap_scan_rows,16,16,32,32); state->pf2_tilemap = tilemap_create(machine, get_pf2_tile_info,tilemap_scan_rows, 16,16,32,32); + machine->device("spritegen1")->alloc_sprite_bitmap(machine); + machine->device("spritegen2")->alloc_sprite_bitmap(machine); + tilemap_set_transparent_pen(state->pf1_8x8_tilemap,0); tilemap_set_transparent_pen(state->pf1_16x16_tilemap,0); } @@ -177,6 +107,12 @@ SCREEN_UPDATE( sshangha ) sshangha_state *state = screen->machine->driver_data(); int offs; + screen->machine->device("spritegen1")->draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.spriteram.u16, 0x800, true); + + // I'm pretty sure only the original has the 2nd spriteram, used for the Japanese text on the 2nd scene (non-scrolling text) in the intro of the quest (3rd in JPN) mode + if (screen->machine->generic.spriteram2.u16) + screen->machine->device("spritegen2")->draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.spriteram2.u16, 0x800, true); + flip_screen_set_no_update(screen->machine, state->control_0[0]&0x80); tilemap_set_flip_all(screen->machine,flip_screen_x_get(screen->machine) ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0); @@ -230,11 +166,12 @@ SCREEN_UPDATE( sshangha ) used in any tilemap, so we plot it on the fly */ if ((state->video_control&4)==0) { sshangha_tilemap_draw(screen->machine, bitmap, cliprect); - draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.spriteram.u16,0x4000,0x4000); + screen->machine->device("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0200, 0x0200, 0x100, 0x1ff); } else { + tilemap_draw(bitmap,cliprect,state->pf2_tilemap,0,0); - draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.spriteram.u16,0x4000,0x4000); + screen->machine->device("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0200, 0x0200, 0x100, 0x1ff); if (state->control_0[6]&0x80) tilemap_draw(bitmap,cliprect,state->pf1_8x8_tilemap,0,0); @@ -242,7 +179,9 @@ SCREEN_UPDATE( sshangha ) tilemap_draw(bitmap,cliprect,state->pf1_16x16_tilemap,0,0); } - draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.spriteram2.u16,0x0000,0x0000); - draw_sprites(screen->machine, bitmap, cliprect, screen->machine->generic.spriteram.u16,0x4000,0x0000); + if (screen->machine->generic.spriteram2.u16) + screen->machine->device("spritegen2")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 0, 0x1ff); + + screen->machine->device("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0200, 0, 0x1ff); return 0; }