Haze: more of the same ...

This commit is contained in:
Angelo Salese 2011-03-23 16:32:15 +00:00
parent 920f9c5e09
commit 626c8b0fea
13 changed files with 254 additions and 403 deletions

View File

@ -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")

View File

@ -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")

View File

@ -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<okim6295_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<mirage_state>();
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<decospr_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<decospr_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<decospr_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<decospr_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")

View File

@ -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<sshangha_state>();
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<sshangha_state>();
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<sshangha_state>();
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<sshangha_state>();
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)

View File

@ -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 );

View File

@ -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];

View File

@ -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;
};

View File

@ -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<decospr_device>("spritegen")->alloc_sprite_bitmap(machine);
}
SCREEN_UPDATE( twocrude )
{
cbuster_state *state = screen->machine->driver_data<cbuster_state>();
@ -120,12 +54,16 @@ SCREEN_UPDATE( twocrude )
flip_screen_set(screen->machine, !BIT(flip, 7));
screen->machine->device<decospr_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<decospr_device>("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0800, 0x0900, 0x100, 0x0ff);
screen->machine->device<decospr_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<decospr_device>("spritegen")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0900, 0x100, 0x0ff);
screen->machine->device<decospr_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;
}

View File

@ -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<decospr_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;
}

View File

@ -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<decospr_device>("spritegen")->set_sprite_bitmap(state->temp_bitmap_sprites);
machine->device<decospr_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<deco32_state>();
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<deco32_state>();
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<decospr_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<decospr_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<decospr_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<decospr_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;

View File

@ -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];
}
}
}
}
}

View File

@ -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();

View File

@ -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<sshangha_state>();
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<sshangha_state>();
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<sshangha_state>();
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<decospr_device>("spritegen1")->alloc_sprite_bitmap(machine);
machine->device<decospr_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<sshangha_state>();
int offs;
screen->machine->device<decospr_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<decospr_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<decospr_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<decospr_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<decospr_device>("spritegen2")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0000, 0, 0x1ff);
screen->machine->device<decospr_device>("spritegen1")->inefficient_copy_sprite_bitmap(screen->machine, bitmap, cliprect, 0x0000, 0x0200, 0, 0x1ff);
return 0;
}