Galactic Storm

(c)1992 Taito

added by Hau
This commit is contained in:
Aaron Giles 2008-07-03 15:41:07 +00:00
parent b82b111e69
commit c26a5b3fd5
5 changed files with 1010 additions and 0 deletions

2
.gitattributes vendored
View File

@ -1467,6 +1467,7 @@ src/mame/drivers/gaelco2.c svneol=native#text/plain
src/mame/drivers/gaelco3d.c svneol=native#text/plain
src/mame/drivers/gaiden.c svneol=native#text/plain
src/mame/drivers/galaga.c svneol=native#text/plain
src/mame/drivers/galastrm.c svneol=native#text/plain
src/mame/drivers/galaxia.c svneol=native#text/plain
src/mame/drivers/galaxian.c svneol=native#text/plain
src/mame/drivers/galaxold.c svneol=native#text/plain
@ -2872,6 +2873,7 @@ src/mame/video/gaelco2.c svneol=native#text/plain
src/mame/video/gaelco3d.c svneol=native#text/plain
src/mame/video/gaiden.c svneol=native#text/plain
src/mame/video/galaga.c svneol=native#text/plain
src/mame/video/galastrm.c svneol=native#text/plain
src/mame/video/galaxian.c svneol=native#text/plain
src/mame/video/galaxold.c svneol=native#text/plain
src/mame/video/galivan.c svneol=native#text/plain

419
src/mame/drivers/galastrm.c Normal file
View File

@ -0,0 +1,419 @@
/*
Galactic Storm
(c)1992 Taito
----------------------------------------------------------
MAIN PCB
CPU:MC68EC020RP25
TC0480SCP
TC0100SCN
TC0510NIO
TC0580PIV x2
TC0110PCR
TC0470LIN x2
TC0570SPC
TC0610
ADC0809CCN
OSC1:32MHz
OSC2:20MHz
----------------------------------------------------------
SOUND BOARD
CPU:MC68000P12F,MC68681P
ENSONIQ 5701,5510,5505
OSC1:16MHz
OSC2:30.47618MHz
----------------------------------------------------------
based on driver from drivers/gunbustr.c by Bryan McPhail & David Graves
Written by Hau
07/03/2008
tips
$300.b debugmode
$305.b invincibility
*/
#include "driver.h"
#include "cpu/m68000/m68000.h"
#include "video/taitoic.h"
#include "audio/taitosnd.h"
#include "machine/eeprom.h"
#include "sound/es5506.h"
#include "includes/taito_f3.h"
#include "audio/taito_en.h"
VIDEO_START( galastrm );
VIDEO_UPDATE( galastrm );
static UINT16 coin_word, frame_counter=0;
static UINT32 *galastrm_ram;
extern INT16 galastrm_tc0610_ctrl_reg[2][8];
/*********************************************************************/
static INTERRUPT_GEN( galastrm_interrupt )
{
frame_counter ^= 1;
cpunum_set_input_line(machine, 0, 5, HOLD_LINE);
}
static TIMER_CALLBACK( galastrm_interrupt6 )
{
cpunum_set_input_line(machine, 0, 6, HOLD_LINE);
}
static int tc0110pcr_addr;
static int tc0610_0_addr;
static int tc0610_1_addr;
static WRITE32_HANDLER( galastrm_palette_w )
{
if (ACCESSING_BITS_16_31)
tc0110pcr_addr = data >> 16;
if ((ACCESSING_BITS_0_15) && (tc0110pcr_addr < 4096))
palette_set_color_rgb(machine, tc0110pcr_addr, pal5bit(data >> 10), pal5bit(data >> 5), pal5bit(data >> 0));
}
static WRITE32_HANDLER( galastrm_tc0610_0_w )
{
if (ACCESSING_BITS_16_31)
tc0610_0_addr = data >> 16;
if ((ACCESSING_BITS_0_15) && (tc0610_0_addr < 8))
galastrm_tc0610_ctrl_reg[0][tc0610_0_addr] = data;
}
static WRITE32_HANDLER( galastrm_tc0610_1_w )
{
if (ACCESSING_BITS_16_31)
tc0610_1_addr = data >> 16;
if ((ACCESSING_BITS_0_15) && (tc0610_1_addr < 8))
galastrm_tc0610_ctrl_reg[1][tc0610_1_addr] = data;
}
static READ32_HANDLER( galastrm_input_r )
{
switch (offset)
{
case 0x00:
{
return (input_port_read_indexed(machine,0) << 16) | input_port_read_indexed(machine,1) |
(eeprom_read_bit() << 7) | frame_counter << 9;
}
case 0x01:
{
return input_port_read_indexed(machine,2) | (coin_word << 16);
}
}
//logerror("CPU #0 PC %06x: read input %06x\n",activecpu_get_pc(),offset);
return 0x0;
}
static WRITE32_HANDLER( galastrm_input_w )
{
#if 0
{
char t[64];
static UINT32 mem[2];
COMBINE_DATA(&mem[offset]);
sprintf(t,"%08x %08x",mem[0],mem[1]);
popmessage(t);
}
#endif
switch (offset)
{
case 0x00:
{
if (ACCESSING_BITS_24_31) /* $400000 is watchdog */
{
watchdog_reset(machine);
}
if (ACCESSING_BITS_0_7)
{
eeprom_set_clock_line((data & 0x20) ? ASSERT_LINE : CLEAR_LINE);
eeprom_write_bit(data & 0x40);
eeprom_set_cs_line((data & 0x10) ? CLEAR_LINE : ASSERT_LINE);
return;
}
return;
}
case 0x01:
{
if (ACCESSING_BITS_24_31)
{
coin_lockout_w(0, ~data & 0x01000000);
coin_lockout_w(1, ~data & 0x02000000);
coin_counter_w(0, data & 0x04000000);
coin_counter_w(1, data & 0x04000000);
coin_word = (data >> 16) &0xffff;
}
//logerror("CPU #0 PC %06x: write input %06x\n",activecpu_get_pc(),offset);
}
}
}
static READ32_HANDLER( galastrm_adstick_ctrl_r )
{
if (offset == 0x00)
{
if (ACCESSING_BITS_24_31)
return input_port_read_indexed(machine, 3) << 24;
if (ACCESSING_BITS_16_23)
return input_port_read_indexed(machine, 4) << 16;
}
return 0;
}
static WRITE32_HANDLER( galastrm_adstick_ctrl_w )
{
timer_set(ATTOTIME_IN_CYCLES(1000,0), NULL, 0, galastrm_interrupt6);
}
/***********************************************************
MEMORY STRUCTURES
***********************************************************/
static ADDRESS_MAP_START( galastrm_readmem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x0fffff) AM_READ(SMH_ROM)
AM_RANGE(0x200000, 0x21ffff) AM_READ(SMH_RAM) /* main CPUA ram */
AM_RANGE(0x300000, 0x303fff) AM_READ(SMH_RAM) /* Sprite ram */
AM_RANGE(0x400000, 0x400007) AM_READ(galastrm_input_r)
AM_RANGE(0x500000, 0x500007) AM_READ(galastrm_adstick_ctrl_r)
AM_RANGE(0x600000, 0x6007ff) AM_READ(SMH_RAM) /* Sound shared ram */
AM_RANGE(0x800000, 0x80ffff) AM_READ(TC0480SCP_long_r)
AM_RANGE(0x830000, 0x83002f) AM_READ(TC0480SCP_ctrl_long_r)
AM_RANGE(0xd00000, 0xd0ffff) AM_READ(TC0100SCN_long_r) /* piv tilemaps */
AM_RANGE(0xd20000, 0xd2000f) AM_READ(TC0100SCN_ctrl_long_r)
ADDRESS_MAP_END
static ADDRESS_MAP_START( galastrm_writemem, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0x000000, 0x1fffff) AM_WRITE(SMH_ROM)
AM_RANGE(0x200000, 0x21ffff) AM_WRITE(SMH_RAM) AM_BASE(&galastrm_ram)
AM_RANGE(0x300000, 0x303fff) AM_WRITE(SMH_RAM) AM_BASE(&spriteram32) AM_SIZE(&spriteram_size)
AM_RANGE(0x400000, 0x400007) AM_WRITE(galastrm_input_w) /* eerom etc. */
AM_RANGE(0x40fff0, 0x40fff3) AM_WRITE(SMH_NOP)
AM_RANGE(0x500000, 0x500007) AM_WRITE(galastrm_adstick_ctrl_w)
AM_RANGE(0x600000, 0x6007ff) AM_WRITE(SMH_RAM) AM_BASE(&f3_shared_ram)
AM_RANGE(0x800000, 0x80ffff) AM_WRITE(TC0480SCP_long_w)
AM_RANGE(0x830000, 0x83002f) AM_WRITE(TC0480SCP_ctrl_long_w)
AM_RANGE(0x900000, 0x900003) AM_WRITE(galastrm_palette_w) /* TC0110PCR */
AM_RANGE(0xb00000, 0xb00003) AM_WRITE(galastrm_tc0610_0_w) /* TC0610 */
AM_RANGE(0xc00000, 0xc00003) AM_WRITE(galastrm_tc0610_1_w)
AM_RANGE(0xd00000, 0xd0ffff) AM_WRITE(TC0100SCN_long_w) /* piv tilemaps */
AM_RANGE(0xd20000, 0xd2000f) AM_WRITE(TC0100SCN_ctrl_long_w)
ADDRESS_MAP_END
/***********************************************************
INPUT PORTS (dips in eprom)
***********************************************************/
static INPUT_PORTS_START( galastrm )
PORT_START /* IN0 */
PORT_BIT( 0xFFFF, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN1 */
PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_PLAYER(1) /* Freeze input */
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_SPECIAL ) /* reserved for EEROM */
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_SPECIAL ) /* reserved for flamecounter */
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START /* IN2 */
PORT_SERVICE_NO_TOGGLE( 0x0001, IP_ACTIVE_LOW )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_SERVICE1)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(60) PORT_KEYDELTA(15) PORT_PLAYER(1)
PORT_START
PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(60) PORT_KEYDELTA(15) PORT_REVERSE PORT_PLAYER(1)
INPUT_PORTS_END
/***********************************************************
GFX DECODING
**********************************************************/
static const gfx_layout tile16x16_layout =
{
16,16, /* 16*16 sprites */
RGN_FRAC(1,1),
4, /* 4 bits per pixel */
{ 0, 8, 16, 24 },
{ 32, 33, 34, 35, 36, 37, 38, 39, 0, 1, 2, 3, 4, 5, 6, 7 },
{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64,
8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
64*16 /* every sprite takes 128 consecutive bytes */
};
static const gfx_layout charlayout =
{
16,16, /* 16*16 characters */
RGN_FRAC(1,1),
4, /* 4 bits per pixel */
{ 0, 1, 2, 3 },
{ 3*4, 2*4, 7*4, 6*4, 1*4, 0*4, 5*4, 4*4, 11*4, 10*4, 15*4, 14*4, 9*4, 8*4, 13*4, 12*4 },
{ 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
128*8 /* every sprite takes 128 consecutive bytes */
};
static GFXDECODE_START( galastrm )
GFXDECODE_ENTRY( REGION_GFX2, 0x0, tile16x16_layout, 0, 4096 )
GFXDECODE_ENTRY( REGION_GFX1, 0x0, charlayout, 0, 4096 )
GFXDECODE_END
/***********************************************************
MACHINE DRIVERS
***********************************************************/
static MACHINE_RESET( galastrm )
{
taito_f3_soundsystem_reset(machine);
f3_68681_reset();
}
static const UINT8 default_eeprom[128]={
0x45,0x58,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x28,0x00,0x01,0x00,0x00,0x00,0xfa,
0x00,0xec,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
};
static const eeprom_interface galastrm_eeprom_interface =
{
6, /* address bits */
16, /* data bits */
"0110", /* read command */
"0101", /* write command */
"0111", /* erase command */
"0100000000", /* unlock command */
"0100110000", /* lock command */
};
static NVRAM_HANDLER( galastrm )
{
if (read_or_write)
eeprom_save(file);
else {
eeprom_init(&galastrm_eeprom_interface);
if (file)
eeprom_load(file);
else
eeprom_set_data(default_eeprom,128); /* Default the gun setup values */
}
}
/***************************************************************************/
static MACHINE_DRIVER_START( galastrm )
/* basic machine hardware */
MDRV_CPU_ADD(M68EC020, 16000000) /* 16 MHz */
MDRV_CPU_PROGRAM_MAP(galastrm_readmem,galastrm_writemem)
MDRV_CPU_VBLANK_INT("main", galastrm_interrupt) /* VBL */
TAITO_F3_SOUND_SYSTEM_CPU(16000000)
MDRV_MACHINE_RESET(galastrm)
MDRV_NVRAM_HANDLER(galastrm)
/* video hardware */
MDRV_SCREEN_ADD("main", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
MDRV_SCREEN_SIZE(64*8, 50*8)
MDRV_SCREEN_VISIBLE_AREA(0+96, 40*8-1+96, 3*8+60, 32*8-1+60)
MDRV_GFXDECODE(galastrm)
MDRV_PALETTE_LENGTH(4096)
MDRV_VIDEO_START(galastrm)
MDRV_VIDEO_UPDATE(galastrm)
/* sound hardware */
TAITO_F3_SOUND_SYSTEM_ES5505(30476100/2)
MACHINE_DRIVER_END
/***************************************************************************/
ROM_START( galastrm )
ROM_REGION( 0x100000, REGION_CPU1, 0 ) /* for 68020 code (CPU A) */
ROM_LOAD32_BYTE( "c99_15.ic105", 0x00000, 0x40000, CRC(7eae8efd) SHA1(6bbb3da697dfcd93337b53895678e2a4ff2de457) )
ROM_LOAD32_BYTE( "c99_12.ic102", 0x00001, 0x40000, CRC(e059d1ee) SHA1(560951f95f270f0559b5289dda7f4ba74538cfcb) )
ROM_LOAD32_BYTE( "c99_13.ic103", 0x00002, 0x40000, CRC(885fcb35) SHA1(be10e109c461c1f776e98efa1b2a4d588aa0c41c) )
ROM_LOAD32_BYTE( "c99_14.ic104", 0x00003, 0x40000, CRC(457ef6b1) SHA1(06c2613d46addacd380a0f2413cd795b17ac9474) )
ROM_REGION( 0x180000, REGION_CPU2, 0 )
ROM_LOAD16_BYTE( "c99_23.ic8", 0x100000, 0x20000, CRC(5718ee92) SHA1(33cfa60c5bceb1525498f27b598067d2dc620431) )
ROM_LOAD16_BYTE( "c99_22.ic7", 0x100001, 0x20000, CRC(b90f7c42) SHA1(e2fa9ee10ad61ae1a672c3357c0072b79ec7fbcb) )
ROM_REGION( 0x200000, REGION_GFX1, ROMREGION_DISPOSE )
ROM_LOAD16_BYTE( "c99-06.ic2", 0x000000, 0x100000, CRC(812ed3ae) SHA1(775904dd42643d0e3a30890590d5f8eac1fe78db) ) /* SCR 16x16 tiles */
ROM_LOAD16_BYTE( "c99-05.ic1", 0x000001, 0x100000, CRC(a91ffba4) SHA1(467af9646ddad5fbb520b6bc13517ed4deacf479) )
ROM_REGION( 0x400000, REGION_GFX2, ROMREGION_DISPOSE )
ROM_LOAD32_BYTE( "c99-02.ic50", 0x000000, 0x100000, CRC(81e9fc6f) SHA1(4495a7d130b755b5a48eaa814d884d6bb8243bcb) ) /* OBJ 16x16 tiles */
ROM_LOAD32_BYTE( "c99-01.ic51", 0x000001, 0x100000, CRC(9dda1267) SHA1(c639ba064496dcadf5f1e55332a12bb442e9dc86) )
ROM_LOAD32_BYTE( "c99-04.ic66", 0x000002, 0x100000, CRC(a681760f) SHA1(23d4fc7eb778c8a25c4bc7cee1d0c8cdd828a996) )
ROM_LOAD32_BYTE( "c99-03.ic67", 0x000003, 0x100000, CRC(a2807a27) SHA1(977e395ea2ab2fb82807d3cf5fe5f1dbbde99da0) )
ROM_REGION16_LE( 0x80000, REGION_USER1, 0 )
ROM_LOAD16_WORD( "c99-11.ic90", 0x00000, 0x80000, CRC(26a6926c) SHA1(918860e2829131e9ecfe983b2ae3e49e1c9ecd72) ) /* STY, spritemap */
ROM_REGION16_BE( 0x1000000, REGION_SOUND1, ROMREGION_ERASE00 )
ROM_LOAD16_BYTE( "c99-08.ic3", 0x000000, 0x100000, CRC(fedb4187) SHA1(83563e4af795a0dfeb261a62c31b6fed72f45a4d) ) /* Ensoniq samples */
ROM_LOAD16_BYTE( "c99-09.ic4", 0x200000, 0x100000, CRC(ba70b86b) SHA1(ffbb9547d6b6e47a3ef23206b5f40c57f3ea7619) )
ROM_LOAD16_BYTE( "c99-10.ic5", 0x400000, 0x100000, CRC(da016f1e) SHA1(581ef158c6f6576618dd75429b1d3aa92cd3581d) )
ROM_LOAD16_BYTE( "c99-07.ic2", 0x680000, 0x040000, CRC(4cc3136f) SHA1(d9d7556bbe6af161fa0651b1fbd72e7dbf0a8e82) )
ROM_CONTINUE( 0x600000, 0x040000 )
ROM_CONTINUE( 0x780000, 0x040000 )
ROM_CONTINUE( 0x700000, 0x040000 )
ROM_END
GAME( 1992, galastrm, 0, galastrm, galastrm, 0, ROT0, "Taito Corporation", "Galactic Storm (Japan)", GAME_IMPERFECT_GRAPHICS )

View File

@ -1309,6 +1309,7 @@ $(MAMEOBJ)/taito.a: \
$(DRIVERS)/exzisus.o $(VIDEO)/exzisus.o \
$(DRIVERS)/fgoal.o $(VIDEO)/fgoal.o \
$(DRIVERS)/flstory.o $(MACHINE)/flstory.o $(VIDEO)/flstory.o \
$(DRIVERS)/galastrm.o $(VIDEO)/galastrm.o \
$(DRIVERS)/gladiatr.o $(VIDEO)/gladiatr.o \
$(DRIVERS)/grchamp.o $(AUDIO)/grchamp.o $(VIDEO)/grchamp.o \
$(DRIVERS)/groundfx.o $(VIDEO)/groundfx.o \

View File

@ -1714,6 +1714,7 @@ const game_driver * const drivers[] =
DRIVER( wgpjoy ) /* C32 (c) 1989 Taito Corporation (Japan) */
DRIVER( wgpjoya ) /* C32 (c) 1989 Taito Corporation (Japan) */
DRIVER( wgp2 ) /* C73 (c) 1990 Taito Corporation (Japan) */
DRIVER( galastrm ) /* C99 (c) 1992 Taito Corporation */
DRIVER( slapshot ) /* D71 (c) 1994 Taito Corporation (Japan) */
DRIVER( opwolf3 ) /* D74 (c) 1994 Taito */
DRIVER( opwolf3u ) /* D74 (c) 1994 Taito */

587
src/mame/video/galastrm.c Normal file
View File

@ -0,0 +1,587 @@
#include "driver.h"
#include "video/taitoic.h"
#include "video/poly.h"
#define TC0100SCN_GFX_NUM 0
#define TC0480SCP_GFX_NUM 1
#define X_OFFSET 96
#define Y_OFFSET 60
struct tempsprite
{
int gfx;
int code,color;
int flipx,flipy;
int x,y;
int zoomx,zoomy;
int primask;
};
static struct tempsprite *spritelist;
static bitmap_t *tmpbitmaps;
static bitmap_t *polybitmap;
static poly_manager *poly;
INT16 galastrm_tc0610_ctrl_reg[2][8];
typedef struct _poly_extra_data poly_extra_data;
struct _poly_extra_data
{
bitmap_t *texbase;
};
typedef struct _polygon polygon;
struct _polygon
{
float x;
float y;
float z;
};
/******************************************************************/
static void galastrm_exit(running_machine *machine)
{
poly_free(poly);
}
VIDEO_START( galastrm )
{
spritelist = auto_malloc(0x4000 * sizeof(*spritelist));
TC0100SCN_vh_start(machine,1,TC0100SCN_GFX_NUM,48-X_OFFSET,4-Y_OFFSET,0,0,0,0,0);
TC0480SCP_vh_start(machine,TC0480SCP_GFX_NUM,0,56-X_OFFSET,-63+Y_OFFSET,0,0,0,0,0);
tmpbitmaps = video_screen_auto_bitmap_alloc(machine->primary_screen);
polybitmap = video_screen_auto_bitmap_alloc(machine->primary_screen);
poly = poly_alloc(16, sizeof(poly_extra_data), POLYFLAG_ALLOW_QUADS);
add_exit_callback(machine, galastrm_exit);
}
/************************************************************
SPRITE DRAW ROUTINES
We draw a series of small tiles ("chunks") together to
create each big sprite. The spritemap rom provides the lookup
table for this. The game hardware looks up 16x16 sprite chunks
from the spritemap rom, creating a 64x64 sprite like this:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
(where the number is the word offset into the spritemap rom).
It can also create 32x32 sprites.
NB: unused portions of the spritemap rom contain hex FF's.
It is a useful coding check to warn in the log if these
are being accessed. [They can be inadvertently while
spriteram is being tested, take no notice of that.]
Heavy use is made of sprite zooming.
***
Sprite table layout (4 long words per entry)
------------------------------------------
0 | ........ x....... ........ ........ | Flip X
0 | ........ .xxxxxxx ........ ........ | ZoomX
0 | ........ ........ .xxxxxxx xxxxxxxx | Sprite Tile
| |
2 | ........ ....xx.. ........ ........ | Sprite/tile priority [*]
2 | ........ ......xx xxxxxx.. ........ | Palette bank
2 | ........ ........ ......xx xxxxxxxx | X position
| |
3 | ........ .....x.. ........ ........ | Sprite size (0=32x32, 1=64x64)
3 | ........ ......x. ........ ........ | Flip Y
3 | ........ .......x xxxxxx.. ........ | ZoomY
3 | ........ ........ ......xx xxxxxxxx | Y position
------------------------------------------
[* 00=over BG1; 01=BG2; 10=BG3; 11=over text ???]
********************************************************/
static struct tempsprite *sprite_ptr_pre;
static void draw_sprites_pre(running_machine *machine, int x_offs, int y_offs)
{
UINT16 *spritemap = (UINT16 *)memory_region(machine, REGION_USER1);
int offs, data, tilenum, color, flipx, flipy;
int x, y, priority, dblsize, curx, cury;
int sprites_flipscreen = 0;
int zoomx, zoomy, zx, zy;
int sprite_chunk,map_offset,code,j,k,px,py;
int dimension,total_chunks,bad_chunks;
/* pdrawgfx() needs us to draw sprites front to back, so we have to build a list
while processing sprite ram and then draw them all at the end */
sprite_ptr_pre = spritelist;
for (offs = (spriteram_size/4-4);offs >= 0;offs -= 4)
{
data = spriteram32[offs+0];
flipx = (data & 0x00800000) >> 23;
zoomx = (data & 0x007f0000) >> 16;
tilenum = (data & 0x00007fff);
if (!tilenum) continue;
data = spriteram32[offs+2];
priority = (data & 0x000c0000) >> 18;
color = (data & 0x0003fc00) >> 10;
x = (data & 0x000003ff);
data = spriteram32[offs+3];
dblsize = (data & 0x00040000) >> 18;
flipy = (data & 0x00020000) >> 17;
zoomy = (data & 0x0001fc00) >> 10;
y = (data & 0x000003ff);
bad_chunks = 0;
dimension = ((dblsize*2) + 2); // 2 or 4
total_chunks = ((dblsize*3) + 1) << 2; // 4 or 16
map_offset = tilenum << 2;
zoomx += 1;
zoomy += 1;
if (x > 713) x -= 1024; /* 1024x512 */
if (y < 117) y += 512;
y = (-y & 0x3ff);
x -= x_offs;
y += y_offs;
if (flipy) y += (128 - zoomy);
for (sprite_chunk=0;sprite_chunk<total_chunks;sprite_chunk++)
{
j = sprite_chunk / dimension; /* rows */
k = sprite_chunk % dimension; /* chunks per row */
px = k;
py = j;
/* pick tiles back to front for x and y flips */
if (flipx) px = dimension-1-k;
if (flipy) py = dimension-1-j;
code = spritemap[map_offset + px + (py<<(dblsize+1))];
if (code==0xffff)
{
bad_chunks += 1;
continue;
}
curx = x + ((k*zoomx)/dimension);
cury = y + ((j*zoomy)/dimension);
zx= x + (((k+1)*zoomx)/dimension) - curx;
zy= y + (((j+1)*zoomy)/dimension) - cury;
if (sprites_flipscreen)
{
/* -zx/y is there to fix zoomed sprite coords in screenflip.
drawgfxzoom does not know to draw from flip-side of sprites when
screen is flipped; so we must correct the coords ourselves. */
curx = 320 - curx - zx;
cury = 256 - cury - zy;
flipx = !flipx;
flipy = !flipy;
}
sprite_ptr_pre->gfx = 0;
sprite_ptr_pre->code = code;
sprite_ptr_pre->color = color;
sprite_ptr_pre->flipx = !flipx;
sprite_ptr_pre->flipy = flipy;
sprite_ptr_pre->x = curx;
sprite_ptr_pre->y = cury;
sprite_ptr_pre->zoomx = zx << 12;
sprite_ptr_pre->zoomy = zy << 12;
sprite_ptr_pre->primask = priority;
sprite_ptr_pre++;
}
if (bad_chunks)
logerror("Sprite number %04x had %02x invalid chunks\n",tilenum,bad_chunks);
}
}
static void draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, const int *primasks, int priority)
{
struct tempsprite *sprite_ptr = sprite_ptr_pre;
while (sprite_ptr != spritelist)
{
sprite_ptr--;
if ((priority != 0 && sprite_ptr->primask != 0) ||
(priority == 0 && sprite_ptr->primask == 0))
{
pdrawgfxzoom(bitmap,machine->gfx[sprite_ptr->gfx],
sprite_ptr->code,
sprite_ptr->color,
sprite_ptr->flipx,sprite_ptr->flipy,
sprite_ptr->x,sprite_ptr->y,
cliprect,TRANSPARENCY_PEN,0,
sprite_ptr->zoomx,sprite_ptr->zoomy,
primasks[sprite_ptr->primask]);
}
}
}
/**************************************************************
POLYGON RENDERER
**************************************************************/
static void tc0610_draw_scanline(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
{
const poly_extra_data *extra = extradata;
bitmap_t *destmap = dest;
UINT16 *framebuffer = BITMAP_ADDR16(destmap, scanline, 0);
bitmap_t *texbase = extra->texbase;
int startx = extent->startx;
int stopx = extent->stopx;
INT32 u = extent->param[0].start;
INT32 v = extent->param[1].start;
INT32 dudx = extent->param[0].dpdx;
INT32 dvdx = extent->param[1].dpdx;
int x;
for (x = startx; x < stopx; x++)
{
framebuffer[x] = *BITMAP_ADDR16(texbase, v >> 16, u >> 16);
u += dudx;
v += dvdx;
}
}
static void tc0610_rotate_draw(running_machine *machine, bitmap_t *bitmap, bitmap_t *srcbitmap, const rectangle *clip)
{
poly_extra_data *extra = poly_get_extra_data(poly);
poly_draw_scanline_func callback;
poly_vertex vert[4];
int rsx = galastrm_tc0610_ctrl_reg[1][0];
int rsy = galastrm_tc0610_ctrl_reg[1][1];
const int rzx = galastrm_tc0610_ctrl_reg[1][2];
const int rzy = galastrm_tc0610_ctrl_reg[1][3];
const int ryx = galastrm_tc0610_ctrl_reg[1][5];
const int ryy = galastrm_tc0610_ctrl_reg[1][4];
const int lx = srcbitmap->width;
const int ly = srcbitmap->height;
static int rsxb=0, rsyb=0, rsxoffs=0, rsyoffs=0;
int sx, sy, yx, yy, zx, zy, pxx, pxy, pyx, pyy;
float ssn, scs, ysn, ycs, zsn, zcs;
pxx = 0;
pxy = 0;
pyx = 0;
pyy = 0;
zx = 0;
zy = 0;
if (rzx != 0 || rzy != 0)
{
while (sqrt(pow((float)pxx/4096.0, 2.0) + pow((float)pxy/4096.0, 2.0)) < (float)(lx / 2))
{
pxx += rzx;
pxy += rzy;
zx++;
}
while (sqrt(pow((float)pyy/4096.0, 2.0) + pow((float)pyx/4096.0, 2.0)) < (float)(ly / 2))
{
pyy += rzx;
pyx += -rzy;
zy++;
}
}
zsn = ((float)pyx/4096.0) / (float)(ly / 2);
zcs = ((float)pxx/4096.0) / (float)(lx / 2);
if ((rsx == -240 && rsy == 1072) || !galastrm_tc0610_ctrl_reg[1][7])
{
rsxoffs = 0;
rsyoffs = 0;
}
else
{
if (rsx > rsxb && rsxb < 0 && rsx-rsxb > 0x8000)
{
if (rsxoffs == 0)
rsxoffs = -0x10000;
else
rsxoffs = 0;
}
if (rsx < rsxb && rsxb > 0 && rsxb-rsx > 0x8000)
{
if (rsxoffs == 0)
rsxoffs = 0x10000-1;
else
rsxoffs = 0;
}
if (rsy > rsyb && rsyb < 0 && rsy-rsyb > 0x8000)
{
if (rsyoffs == 0)
rsyoffs = -0x10000;
else
rsyoffs = 0;
}
if (rsy < rsyb && rsyb > 0 && rsyb-rsy > 0x8000)
{
if (rsyoffs == 0)
rsyoffs = 0x10000-1;
else
rsyoffs = 0;
}
}
rsxb = rsx;
rsyb = rsy;
if (rsxoffs) rsx += rsxoffs;
if (rsyoffs) rsy += rsyoffs;
if (rsx < -0x14000 || rsx >= 0x14000) rsxoffs = 0;
if (rsy < -0x14000 || rsy >= 0x14000) rsyoffs = 0;
pxx = 0;
pxy = 0;
pyx = 0;
pyy = 0;
sx = 0;
sy = 0;
yx = 0;
yy = 0;
ssn = 0.0;
scs = 0.0;
ysn = 0.0;
ycs = 0.0;
if (galastrm_tc0610_ctrl_reg[1][7])
{
if (ryx != 0 || ryy != 0)
{
while (sqrt(pow((float)pxx/4096.0, 2.0) + pow((float)pxy/4096.0, 2.0)) < (float)(lx / 2))
{
pxx += ryx;
pxy += ryy;
yx++;
}
while (sqrt(pow((float)pyy/4096.0, 2.0) + pow((float)pyx/4096.0, 2.0)) < (float)(ly / 2))
{
pyy += ryx;
pyx += -ryy;
yy++;
}
if (yx >= 0.0)
{
yx = (int)((8.0 - log((double)yx) / log(2.0)) * 6.0);
ysn = sin(DEGREE_TO_RADIAN(yx));
ycs = 1.0 - ysn*ysn;
}
}
pxx = 0;
pxy = 0;
pyx = 0;
pyy = 0;
if (rsx != 0 || rsy != 0)
{
while (sqrt(pow((float)pxx/65536.0, 2.0) + pow((float)pxy/65536.0, 2.0)) < (float)(lx / 2))
{
pxx += rsx;
pxy += rsy;
sx++;
}
while (sqrt(pow((float)pyy/65536.0, 2.0) + pow((float)pyx/65536.0, 2.0)) < (float)(ly / 2))
{
pyy += rsx;
pyx += -rsy;
sy++;
}
}
ssn = ((float)pxy/65536.0) / (float)(lx / 2);
scs = ((float)pyy/65536.0) / (float)(ly / 2);
}
{
polygon tmpz[4];
tmpz[0].x = ((float)(-zx) * zcs) - ((float)(-zy) * zsn);
tmpz[0].y = ((float)(-zx) * zsn) + ((float)(-zy) * zcs);
tmpz[0].z = 0.0;
tmpz[1].x = ((float)(-zx) * zcs) - ((float)(zy-1) * zsn);
tmpz[1].y = ((float)(-zx) * zsn) + ((float)(zy-1) * zcs);
tmpz[1].z = 0.0;
tmpz[2].x = ((float)(zx-1) * zcs) - ((float)(zy-1) * zsn);
tmpz[2].y = ((float)(zx-1) * zsn) + ((float)(zy-1) * zcs);
tmpz[2].z = 0.0;
tmpz[3].x = ((float)(zx-1) * zcs) - ((float)(-zy) * zsn);
tmpz[3].y = ((float)(zx-1) * zsn) + ((float)(-zy) * zcs);
tmpz[3].z = 0.0;
vert[0].x = tmpz[0].x + (float)(lx / 2);
vert[0].y = tmpz[0].y + (float)(ly / 2);
vert[1].x = tmpz[1].x + (float)(lx / 2);
vert[1].y = tmpz[1].y + (float)(ly / 2);
vert[2].x = tmpz[2].x + (float)(lx / 2);
vert[2].y = tmpz[2].y + (float)(ly / 2);
vert[3].x = tmpz[3].x + (float)(lx / 2);
vert[3].y = tmpz[3].y + (float)(ly / 2);
}
vert[0].p[0] = 0.0;
vert[0].p[1] = 0.0;
vert[1].p[0] = 0.0;
vert[1].p[1] = (float)(ly - 1) * 65536.0;
vert[2].p[0] = (float)(lx - 1) * 65536.0;
vert[2].p[1] = (float)(ly - 1) * 65536.0;
vert[3].p[0] = (float)(lx - 1) * 65536.0;
vert[3].p[1] = 0.0;
extra->texbase = srcbitmap;
callback = tc0610_draw_scanline;
poly_render_quad(poly, bitmap, clip, callback, 2, &vert[0], &vert[1], &vert[2], &vert[3]);
}
/**************************************************************
SCREEN REFRESH
**************************************************************/
VIDEO_UPDATE( galastrm )
{
UINT8 layer[5];
UINT8 pivlayer[3];
UINT16 priority;
static const int primasks[4] = {0xfffc, 0xfff0, 0xff00, 0x0};
rectangle clip;
clip.min_x = 0;
clip.min_y = 0;
clip.max_x = video_screen_get_width(screen) -1;
clip.max_y = video_screen_get_height(screen) -1;
TC0100SCN_tilemap_update(screen->machine);
TC0480SCP_tilemap_update(screen->machine);
priority = TC0480SCP_get_bg_priority();
layer[0] = (priority &0xf000) >> 12; /* tells us which bg layer is bottom */
layer[1] = (priority &0x0f00) >> 8;
layer[2] = (priority &0x00f0) >> 4;
layer[3] = (priority &0x000f) >> 0; /* tells us which is top */
layer[4] = 4; /* text layer always over bg layers */
pivlayer[0] = TC0100SCN_bottomlayer(0);
pivlayer[1] = pivlayer[0]^1;
pivlayer[2] = 2;
fillbitmap(bitmap, 0, cliprect);
fillbitmap(priority_bitmap, 0, &clip);
fillbitmap(tmpbitmaps, 0, &clip);
TC0100SCN_tilemap_draw(screen->machine,bitmap,cliprect,0,pivlayer[0],0,0);
TC0100SCN_tilemap_draw(screen->machine,bitmap,cliprect,0,pivlayer[1],0,0);
#if 0
if (layer[0]==0 && layer[1]==3 && layer[2]==2 && layer[3]==1)
{
if (!input_code_pressed(KEYCODE_Z)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[0],0,1);
if (!input_code_pressed(KEYCODE_X)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[1],0,4);
if (!input_code_pressed(KEYCODE_C)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[2],0,4);
if (!input_code_pressed(KEYCODE_V)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[3],0,4);
}
else
{
if (!input_code_pressed(KEYCODE_Z)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[0],0,1);
if (!input_code_pressed(KEYCODE_X)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[1],0,2);
if (!input_code_pressed(KEYCODE_C)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[2],0,4);
if (!input_code_pressed(KEYCODE_V)) TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[3],0,8);
}
if (layer[0]==3 && layer[1]==0 && layer[2]==1 && layer[3]==2)
{
int x,y;
UINT8 *pri;
for (y=0; y < priority_bitmap->height; y++)
{
for (x=0; x < priority_bitmap->width; x++)
{
pri = BITMAP_ADDR8(priority_bitmap, y, x);
if (!(*pri & 0x02) && *BITMAP_ADDR16(tmpbitmaps, y, x))
*pri |= 0x04;
}
}
}
draw_sprites_pre(screen->machine, 42-X_OFFSET, -571+Y_OFFSET);
draw_sprites(screen->machine,tmpbitmaps,&clip,primasks,1);
copybitmap_trans(bitmap,polybitmap,0,0, 0,0,cliprect,0);
fillbitmap(polybitmap, 0, &clip);
tc0610_rotate_draw(screen->machine,polybitmap,tmpbitmaps,cliprect);
fillbitmap(priority_bitmap, 0, cliprect);
draw_sprites(screen->machine,bitmap,cliprect,primasks,0);
if (!input_code_pressed(KEYCODE_B)) TC0480SCP_tilemap_draw(bitmap,cliprect,layer[4],0,0);
if (!input_code_pressed(KEYCODE_M)) TC0100SCN_tilemap_draw(screen->machine,bitmap,cliprect,0,pivlayer[2],0,0);
#else
if (layer[0]==0 && layer[1]==3 && layer[2]==2 && layer[3]==1)
{
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[0],0,1);
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[1],0,4);
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[2],0,4);
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[3],0,4);
}
else
{
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[0],0,1);
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[1],0,2);
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[2],0,4);
TC0480SCP_tilemap_draw(tmpbitmaps,&clip,layer[3],0,8);
}
if (layer[0]==3 && layer[1]==0 && layer[2]==1 && layer[3]==2)
{
int x,y;
UINT8 *pri;
for (y=0; y < priority_bitmap->height; y++)
{
for (x=0; x < priority_bitmap->width; x++)
{
pri = BITMAP_ADDR8(priority_bitmap, y, x);
if (!(*pri & 0x02) && *BITMAP_ADDR16(tmpbitmaps, y, x))
*pri |= 0x04;
}
}
}
draw_sprites_pre(screen->machine, 42-X_OFFSET, -571+Y_OFFSET);
draw_sprites(screen->machine,tmpbitmaps,&clip,primasks,1);
copybitmap_trans(bitmap,polybitmap,0,0, 0,0,cliprect,0);
fillbitmap(polybitmap, 0, &clip);
tc0610_rotate_draw(screen->machine,polybitmap,tmpbitmaps,cliprect);
fillbitmap(priority_bitmap, 0, cliprect);
draw_sprites(screen->machine,bitmap,cliprect,primasks,0);
TC0480SCP_tilemap_draw(bitmap,cliprect,layer[4],0,0);
TC0100SCN_tilemap_draw(screen->machine,bitmap,cliprect,0,pivlayer[2],0,0);
#endif
return 0;
}