metro.c: added driver data class [Fabio Priuli]

vmetal: added driver data class and save states [Fabio Priuli]

no save states in metro.c (yet) because some games like 3kokushi have serious glitches when loading a state. any help is welcome...
This commit is contained in:
Fabio Priuli 2010-03-17 16:38:26 +00:00
parent c02b195ede
commit b7d6cf77c1
5 changed files with 1666 additions and 1391 deletions

1
.gitattributes vendored
View File

@ -2658,6 +2658,7 @@ src/mame/includes/megazone.h svneol=native#text/plain
src/mame/includes/mermaid.h svneol=native#text/plain
src/mame/includes/metalmx.h svneol=native#text/plain
src/mame/includes/metlclsh.h svneol=native#text/plain
src/mame/includes/metro.h svneol=native#text/plain
src/mame/includes/mexico86.h svneol=native#text/plain
src/mame/includes/mhavoc.h svneol=native#text/plain
src/mame/includes/micro3d.h svneol=native#text/plain

File diff suppressed because it is too large Load Diff

View File

@ -79,32 +79,20 @@ cleanup
#include "cpu/m68000/m68000.h"
#include "sound/okim6295.h"
#include "sound/es8712.h"
static UINT16 *vmetal_texttileram;
static UINT16 *vmetal_mid1tileram;
static UINT16 *vmetal_mid2tileram;
static UINT16 *vmetal_tlookup;
static UINT16 *vmetal_videoregs;
static tilemap_t *vmetal_texttilemap;
static tilemap_t *vmetal_mid1tilemap;
static tilemap_t *vmetal_mid2tilemap;
/* video/metro.c */
extern UINT16 *metro_videoregs;
void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect);
#include "includes/metro.h"
static READ16_HANDLER ( varia_crom_read )
{
/* game reads the cgrom, result is 7772, verified to be correct on the real board */
metro_state *state = (metro_state *)space->machine->driver_data;
UINT8 *cgrom = memory_region(space->machine, "gfx1");
UINT16 retdat;
offset = offset << 1;
offset |= (vmetal_videoregs[0x0ab/2]&0x7f) << 16;
retdat = ((cgrom[offset] <<8)| (cgrom[offset+1]));
// popmessage("varia romread offset %06x data %04x",offset, retdat);
offset |= (state->vmetal_videoregs[0x0ab / 2] & 0x7f) << 16;
retdat = ((cgrom[offset] << 8) | (cgrom[offset + 1]));
// popmessage("varia romread offset %06x data %04x", offset, retdat);
return retdat;
}
@ -117,30 +105,36 @@ static READ16_HANDLER ( varia_random )
static void get_vmetal_tlookup(UINT16 data, UINT16 *tileno, UINT16 *color)
static void get_vmetal_tlookup(running_machine *machine, UINT16 data, UINT16 *tileno, UINT16 *color)
{
int idx = ((data & 0x7fff) >> 4)*2;
UINT32 lookup = (vmetal_tlookup[idx]<<16) | vmetal_tlookup[idx+1];
*tileno = (data & 0xf) | ((lookup>>2) & 0xfff0);
*color = (lookup>>20) & 0xff;
metro_state *state = (metro_state *)machine->driver_data;
int idx = ((data & 0x7fff) >> 4) * 2;
UINT32 lookup = (state->vmetal_tlookup[idx] << 16) | state->vmetal_tlookup[idx + 1];
*tileno = (data & 0xf) | ((lookup >> 2) & 0xfff0);
*color = (lookup >> 20) & 0xff;
}
static WRITE16_HANDLER( vmetal_texttileram_w )
{
COMBINE_DATA(&vmetal_texttileram[offset]);
tilemap_mark_tile_dirty(vmetal_texttilemap,offset);
metro_state *state = (metro_state *)space->machine->driver_data;
COMBINE_DATA(&state->vmetal_texttileram[offset]);
tilemap_mark_tile_dirty(state->vmetal_texttilemap, offset);
}
static WRITE16_HANDLER( vmetal_mid1tileram_w )
{
COMBINE_DATA(&vmetal_mid1tileram[offset]);
tilemap_mark_tile_dirty(vmetal_mid1tilemap,offset);
metro_state *state = (metro_state *)space->machine->driver_data;
COMBINE_DATA(&state->vmetal_mid1tileram[offset]);
tilemap_mark_tile_dirty(state->vmetal_mid1tilemap, offset);
}
static WRITE16_HANDLER( vmetal_mid2tileram_w )
{
COMBINE_DATA(&vmetal_mid2tileram[offset]);
tilemap_mark_tile_dirty(vmetal_mid2tilemap,offset);
metro_state *state = (metro_state *)space->machine->driver_data;
COMBINE_DATA(&state->vmetal_mid2tileram[offset]);
tilemap_mark_tile_dirty(state->vmetal_mid2tilemap, offset);
}
@ -157,10 +151,10 @@ static WRITE8_DEVICE_HANDLER( vmetal_control_w )
{
/* Lower nibble is the coin control bits shown in
service mode, but in game mode they're different */
coin_counter_w(device->machine, 0,data & 0x04);
coin_counter_w(device->machine, 1,data & 0x08); /* 2nd coin schute activates coin 0 counter in game mode?? */
// coin_lockout_w(device->machine, 0,data & 0x01); /* always on in game mode?? */
coin_lockout_w(device->machine, 1,data & 0x02); /* never activated in game mode?? */
coin_counter_w(device->machine, 0, data & 0x04);
coin_counter_w(device->machine, 1, data & 0x08); /* 2nd coin schute activates coin 0 counter in game mode?? */
// coin_lockout_w(device->machine, 0, data & 0x01); /* always on in game mode?? */
coin_lockout_w(device->machine, 1, data & 0x02); /* never activated in game mode?? */
if ((data & 0x40) == 0)
device->reset();
@ -209,45 +203,45 @@ static WRITE8_DEVICE_HANDLER( vmetal_es8712_w )
*/
es8712_w(device, offset, data);
logerror("%s:Writing %04x to ES8712 offset %02x\n",cpuexec_describe_context(device->machine),data,offset);
logerror("%s:Writing %04x to ES8712 offset %02x\n", cpuexec_describe_context(device->machine), data, offset);
}
static ADDRESS_MAP_START( varia_program_map, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x11ffff) AM_RAM_WRITE(vmetal_texttileram_w) AM_BASE(&vmetal_texttileram)
AM_RANGE(0x120000, 0x13ffff) AM_RAM_WRITE(vmetal_mid1tileram_w) AM_BASE(&vmetal_mid1tileram)
AM_RANGE(0x140000, 0x15ffff) AM_RAM_WRITE(vmetal_mid2tileram_w) AM_BASE(&vmetal_mid2tileram)
AM_RANGE(0x100000, 0x11ffff) AM_RAM_WRITE(vmetal_texttileram_w) AM_BASE_MEMBER(metro_state, vmetal_texttileram)
AM_RANGE(0x120000, 0x13ffff) AM_RAM_WRITE(vmetal_mid1tileram_w) AM_BASE_MEMBER(metro_state, vmetal_mid1tileram)
AM_RANGE(0x140000, 0x15ffff) AM_RAM_WRITE(vmetal_mid2tileram_w) AM_BASE_MEMBER(metro_state, vmetal_mid2tileram)
AM_RANGE(0x160000, 0x16ffff) AM_READ(varia_crom_read) // cgrom read window ..
AM_RANGE(0x170000, 0x173fff) AM_RAM_WRITE(paletteram16_GGGGGRRRRRBBBBBx_word_w) AM_BASE_GENERIC(paletteram) // Palette
AM_RANGE(0x174000, 0x174fff) AM_RAM AM_BASE_SIZE_GENERIC(spriteram)
AM_RANGE(0x174000, 0x174fff) AM_RAM AM_BASE_SIZE_MEMBER(metro_state, spriteram, spriteram_size)
AM_RANGE(0x175000, 0x177fff) AM_RAM
AM_RANGE(0x178000, 0x1787ff) AM_RAM AM_BASE(&vmetal_tlookup)
AM_RANGE(0x178800, 0x1796ff) AM_RAM AM_BASE(&vmetal_videoregs)
AM_RANGE(0x179700, 0x179713) AM_WRITEONLY AM_BASE(&metro_videoregs ) // Video Registers
AM_RANGE(0x178000, 0x1787ff) AM_RAM AM_BASE_MEMBER(metro_state, vmetal_tlookup)
AM_RANGE(0x178800, 0x1796ff) AM_RAM AM_BASE_MEMBER(metro_state, vmetal_videoregs)
AM_RANGE(0x179700, 0x179713) AM_WRITEONLY AM_BASE_MEMBER(metro_state, videoregs) // Video Registers
AM_RANGE(0x200000, 0x200001) AM_READ_PORT("P1_P2") AM_DEVWRITE8("essnd", vmetal_control_w, 0x00ff)
AM_RANGE(0x200002, 0x200003) AM_READ_PORT("SYSTEM")
/* i have no idea whats meant to be going on here .. it seems to read one bit of the dips from some of them, protection ??? */
AM_RANGE(0x30fffe, 0x30ffff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x317ffe, 0x317fff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31bffe, 0x31bfff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31dffe, 0x31dfff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31effe, 0x31efff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31f7fe, 0x31f7ff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31fbfe, 0x31fbff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31fdfe, 0x31fdff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x31fefe, 0x31feff) AM_READ(varia_dips_bit8_r ) // 0x40 = dip1-8 , 0x80 = dip2-8
AM_RANGE(0x31ff7e, 0x31ff7f) AM_READ(varia_dips_bit7_r ) // 0x40 = dip1-7 , 0x80 = dip2-7
AM_RANGE(0x31ffbe, 0x31ffbf) AM_READ(varia_dips_bit6_r ) // 0x40 = dip1-6 , 0x80 = dip2-6
AM_RANGE(0x31ffde, 0x31ffdf) AM_READ(varia_dips_bit5_r ) // 0x40 = dip1-5 , 0x80 = dip2-5
AM_RANGE(0x31ffee, 0x31ffef) AM_READ(varia_dips_bit4_r ) // 0x40 = dip1-4 , 0x80 = dip2-4
AM_RANGE(0x31fff6, 0x31fff7) AM_READ(varia_dips_bit3_r ) // 0x40 = dip1-3 , 0x80 = dip2-3
AM_RANGE(0x31fffa, 0x31fffb) AM_READ(varia_dips_bit2_r ) // 0x40 = dip1-2 , 0x80 = dip2-2
AM_RANGE(0x31fffc, 0x31fffd) AM_READ(varia_dips_bit1_r ) // 0x40 = dip1-1 , 0x80 = dip2-1
AM_RANGE(0x30fffe, 0x30ffff) AM_READ(varia_random) // nothing?
AM_RANGE(0x317ffe, 0x317fff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31bffe, 0x31bfff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31dffe, 0x31dfff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31effe, 0x31efff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31f7fe, 0x31f7ff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31fbfe, 0x31fbff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31fdfe, 0x31fdff) AM_READ(varia_random) // nothing?
AM_RANGE(0x31fefe, 0x31feff) AM_READ(varia_dips_bit8_r) // 0x40 = dip1-8 , 0x80 = dip2-8
AM_RANGE(0x31ff7e, 0x31ff7f) AM_READ(varia_dips_bit7_r) // 0x40 = dip1-7 , 0x80 = dip2-7
AM_RANGE(0x31ffbe, 0x31ffbf) AM_READ(varia_dips_bit6_r) // 0x40 = dip1-6 , 0x80 = dip2-6
AM_RANGE(0x31ffde, 0x31ffdf) AM_READ(varia_dips_bit5_r) // 0x40 = dip1-5 , 0x80 = dip2-5
AM_RANGE(0x31ffee, 0x31ffef) AM_READ(varia_dips_bit4_r) // 0x40 = dip1-4 , 0x80 = dip2-4
AM_RANGE(0x31fff6, 0x31fff7) AM_READ(varia_dips_bit3_r) // 0x40 = dip1-3 , 0x80 = dip2-3
AM_RANGE(0x31fffa, 0x31fffb) AM_READ(varia_dips_bit2_r) // 0x40 = dip1-2 , 0x80 = dip2-2
AM_RANGE(0x31fffc, 0x31fffd) AM_READ(varia_dips_bit1_r) // 0x40 = dip1-1 , 0x80 = dip2-1
AM_RANGE(0x31fffe, 0x31ffff) AM_READ(varia_random ) // nothing?
AM_RANGE(0x400000, 0x400001) AM_DEVREADWRITE8("oki", okim6295_r, okim6295_w, 0x00ff )
@ -260,7 +254,7 @@ ADDRESS_MAP_END
static INPUT_PORTS_START( varia )
PORT_START("P1_P2") /* IN0 */
PORT_START("P1_P2")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
@ -278,7 +272,7 @@ static INPUT_PORTS_START( varia )
PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START1 )
PORT_START("SYSTEM") /* IN1 */
PORT_START("SYSTEM")
PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_TILT )
@ -286,7 +280,7 @@ static INPUT_PORTS_START( varia )
PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_SERVICE2 ) // 'Test'
PORT_BIT( 0xffe0, IP_ACTIVE_LOW, IPT_UNKNOWN ) // unused?
PORT_START("DSW1") /* Dips 1 */
PORT_START("DSW1")
PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
PORT_DIPSETTING( 0x0005, DEF_STR( 3C_1C ) )
PORT_DIPSETTING( 0x0006, DEF_STR( 2C_1C ) )
@ -312,7 +306,7 @@ static INPUT_PORTS_START( varia )
PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
PORT_START("DSW2") /* Dips 2 */
PORT_START("DSW2")
PORT_DIPNAME( 0x0001, 0x0001, DEF_STR( Unknown ))
PORT_DIPSETTING( 0x0001, DEF_STR( Off ) )
PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
@ -368,68 +362,95 @@ GFXDECODE_END
static TILE_GET_INFO( get_vmetal_texttilemap_tile_info )
{
metro_state *state = (metro_state *)machine->driver_data;
UINT32 tile;
UINT16 color, data = vmetal_texttileram[tile_index];
int idx = ((data & 0x7fff) >> 4)*2;
UINT32 lookup = (vmetal_tlookup[idx]<<16) | vmetal_tlookup[idx+1];
UINT16 color, data = state->vmetal_texttileram[tile_index];
int idx = ((data & 0x7fff) >> 4) * 2;
UINT32 lookup = (state->vmetal_tlookup[idx] << 16) | state->vmetal_tlookup[idx + 1];
tile = (data & 0xf) | (lookup & 0x7fff0);
color = ((lookup>>20) & 0x1f)+0xe0;
if (data & 0x8000) tile = 0;
color = ((lookup >> 20) & 0x1f) + 0xe0;
if (data & 0x8000)
tile = 0;
SET_TILE_INFO(1, tile, color, TILE_FLIPYX(0x0));
}
static TILE_GET_INFO( get_vmetal_mid1tilemap_tile_info )
{
UINT16 tile, color, data = vmetal_mid1tileram[tile_index];
get_vmetal_tlookup(data, &tile, &color);
if (data & 0x8000) tile = 0;
metro_state *state = (metro_state *)machine->driver_data;
UINT16 tile, color, data = state->vmetal_mid1tileram[tile_index];
get_vmetal_tlookup(machine, data, &tile, &color);
if (data & 0x8000)
tile = 0;
SET_TILE_INFO(0, tile, color, TILE_FLIPYX(0x0));
}
static TILE_GET_INFO( get_vmetal_mid2tilemap_tile_info )
{
UINT16 tile, color, data = vmetal_mid2tileram[tile_index];
get_vmetal_tlookup(data, &tile, &color);
if (data & 0x8000) tile = 0;
metro_state *state = (metro_state *)machine->driver_data;
UINT16 tile, color, data = state->vmetal_mid2tileram[tile_index];
get_vmetal_tlookup(machine, data, &tile, &color);
if (data & 0x8000)
tile = 0;
SET_TILE_INFO(0, tile, color, TILE_FLIPYX(0x0));
}
static VIDEO_START(varia)
{
vmetal_texttilemap = tilemap_create(machine, get_vmetal_texttilemap_tile_info,tilemap_scan_rows, 8, 8, 256,256);
vmetal_mid1tilemap = tilemap_create(machine, get_vmetal_mid1tilemap_tile_info,tilemap_scan_rows,16,16, 256,256);
vmetal_mid2tilemap = tilemap_create(machine, get_vmetal_mid2tilemap_tile_info,tilemap_scan_rows,16,16, 256,256);
tilemap_set_transparent_pen(vmetal_texttilemap,15);
tilemap_set_transparent_pen(vmetal_mid1tilemap,15);
tilemap_set_transparent_pen(vmetal_mid2tilemap,15);
metro_state *state = (metro_state *)machine->driver_data;
state->vmetal_texttilemap = tilemap_create(machine, get_vmetal_texttilemap_tile_info, tilemap_scan_rows, 8, 8, 256, 256);
state->vmetal_mid1tilemap = tilemap_create(machine, get_vmetal_mid1tilemap_tile_info, tilemap_scan_rows, 16, 16, 256, 256);
state->vmetal_mid2tilemap = tilemap_create(machine, get_vmetal_mid2tilemap_tile_info, tilemap_scan_rows, 16, 16, 256, 256);
tilemap_set_transparent_pen(state->vmetal_texttilemap, 15);
tilemap_set_transparent_pen(state->vmetal_mid1tilemap, 15);
tilemap_set_transparent_pen(state->vmetal_mid2tilemap, 15);
}
static VIDEO_UPDATE(varia)
{
metro_state *state = (metro_state *)screen->machine->driver_data;
bitmap_fill(bitmap, cliprect, get_black_pen(screen->machine));
bitmap_fill(screen->machine->priority_bitmap,cliprect,0);
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
tilemap_set_scrollx(vmetal_mid2tilemap,0, vmetal_videoregs[0x06a/2]-64 /*+ vmetal_videoregs[0x066/2]*/);
tilemap_set_scrollx(vmetal_mid1tilemap,0, vmetal_videoregs[0x07a/2]-64 /*+ vmetal_videoregs[0x076/2]*/);
tilemap_set_scrollx(vmetal_texttilemap,0, -64 /*+ vmetal_videoregs[0x076/2]*/);
tilemap_set_scrollx(state->vmetal_mid2tilemap, 0, state->vmetal_videoregs[0x06a/2]-64 /*+ state->vmetal_videoregs[0x066/2]*/);
tilemap_set_scrollx(state->vmetal_mid1tilemap, 0, state->vmetal_videoregs[0x07a/2]-64 /*+ state->vmetal_videoregs[0x076/2]*/);
tilemap_set_scrollx(state->vmetal_texttilemap, 0, -64 /*+ state->vmetal_videoregs[0x076/2]*/);
tilemap_set_scrolly(vmetal_mid2tilemap,0, -64 );
tilemap_set_scrolly(vmetal_mid1tilemap,0, -64 );
tilemap_set_scrolly(vmetal_texttilemap,0, -64 );
tilemap_set_scrolly(state->vmetal_mid2tilemap, 0, -64);
tilemap_set_scrolly(state->vmetal_mid1tilemap, 0, -64);
tilemap_set_scrolly(state->vmetal_texttilemap, 0, -64);
tilemap_draw(bitmap,cliprect,vmetal_mid1tilemap,0,0);
tilemap_draw(bitmap,cliprect,vmetal_mid2tilemap,0,0);
metro_draw_sprites(screen->machine, bitmap,cliprect);
tilemap_draw(bitmap,cliprect,vmetal_texttilemap,0,0);
tilemap_draw(bitmap, cliprect, state->vmetal_mid1tilemap, 0, 0);
tilemap_draw(bitmap, cliprect, state->vmetal_mid2tilemap, 0, 0);
metro_draw_sprites(screen->machine, bitmap, cliprect);
tilemap_draw(bitmap, cliprect, state->vmetal_texttilemap, 0, 0);
return 0;
}
static MACHINE_DRIVER_START( varia )
/* driver data */
MDRV_DRIVER_DATA(metro_state)
/* basic machine hardware */
MDRV_CPU_ADD("maincpu", M68000, 16000000)
MDRV_CPU_PROGRAM_MAP(varia_program_map)
MDRV_CPU_VBLANK_INT("screen", irq1_line_hold) // also level 3
/* video hardware */
MDRV_SCREEN_ADD("screen", RASTER)
MDRV_SCREEN_REFRESH_RATE(60)
MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
@ -443,6 +464,7 @@ static MACHINE_DRIVER_START( varia )
MDRV_VIDEO_START(varia)
MDRV_VIDEO_UPDATE(varia)
/* sound hardware */
MDRV_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
MDRV_SOUND_ADD("oki", OKIM6295, 1320000)
@ -494,5 +516,5 @@ ROM_START( vmetaln )
ROM_LOAD( "7.u12", 0x00000, 0x200000, CRC(a88c52f1) SHA1(d74a5a11f84ba6b1042b33a2c156a1071b6fbfe1) )
ROM_END
GAME( 1995, vmetal, 0, varia, varia, 0, ROT270, "Excellent System", "Varia Metal", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS )
GAME( 1995, vmetaln, vmetal, varia, varia, 0, ROT270, "[Excellent System] New Ways Trading Co.", "Varia Metal (New Ways Trading Co.)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS )
GAME( 1995, vmetal, 0, varia, varia, 0, ROT270, "Excellent System", "Varia Metal", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )
GAME( 1995, vmetaln, vmetal, varia, varia, 0, ROT270, "[Excellent System] New Ways Trading Co.", "Varia Metal (New Ways Trading Co.)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_SUPPORTS_SAVE )

100
src/mame/includes/metro.h Normal file
View File

@ -0,0 +1,100 @@
/*************************************************************************
Metro Games
*************************************************************************/
class metro_state
{
public:
static void *alloc(running_machine &machine) { return auto_alloc_clear(&machine, metro_state(machine)); }
metro_state(running_machine &machine) { }
/* memory pointers */
UINT16 * vram_0;
UINT16 * vram_1;
UINT16 * vram_2;
UINT16 * spriteram;
UINT16 * tiletable;
UINT16 * tiletable_old;
UINT16 * blitter_regs;
UINT16 * scroll;
UINT16 * window;
UINT16 * irq_enable;
UINT16 * irq_levels;
UINT16 * irq_vectors;
UINT16 * rombank;
UINT16 * videoregs;
UINT16 * screenctrl;
UINT16 * input_sel;
UINT16 * k053936_ram;
UINT8 * dirtyindex;
UINT8 * empty_tiles;
size_t spriteram_size;
size_t tiletable_size;
// UINT16 * paletteram; // currently this uses generic palette handling
/* video-related */
tilemap_t *k053936_tilemap;
tilemap_t *bg_tilemap[3];
tilemap_t *tilemap_16x16[3];
int support_8bpp, support_16x16;
int has_zoom;
int sprite_xoffs, sprite_yoffs;
/* blitter */
int blitter_bit;
/* irq_related */
int irq_line;
UINT8 requested_int[8];
emu_timer *mouja_irq_timer;
/* sound related */
UINT16 soundstatus;
int porta, portb, busy_sndcpu;
/* misc */
int gakusai_oki_bank_lo, gakusai_oki_bank_hi;
/* used by vmetal.c */
UINT16 *vmetal_texttileram;
UINT16 *vmetal_mid1tileram;
UINT16 *vmetal_mid2tileram;
UINT16 *vmetal_tlookup;
UINT16 *vmetal_videoregs;
tilemap_t *vmetal_texttilemap;
tilemap_t *vmetal_mid1tilemap;
tilemap_t *vmetal_mid2tilemap;
/* devices */
running_device *maincpu;
running_device *audiocpu;
running_device *oki;
running_device *ymsnd;
running_device *k053936;
};
/*----------- defined in video/metro.c -----------*/
WRITE16_HANDLER( metro_window_w );
WRITE16_HANDLER( metro_vram_0_w );
WRITE16_HANDLER( metro_vram_1_w );
WRITE16_HANDLER( metro_vram_2_w );
WRITE16_HANDLER( metro_k053936_w );
VIDEO_START( metro_14100 );
VIDEO_START( metro_14220 );
VIDEO_START( metro_14300 );
VIDEO_START( blzntrnd );
VIDEO_START( gstrik2 );
VIDEO_UPDATE( metro );
void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect);

View File

@ -52,32 +52,14 @@ Note: if MAME_DEBUG is defined, pressing Z with:
***************************************************************************/
#include "emu.h"
#include "includes/metro.h"
#include "video/konicdev.h"
/* Variables that driver has access to: */
UINT16 *metro_videoregs;
UINT16 *metro_screenctrl;
UINT16 *metro_scroll;
UINT16 *metro_tiletable;
size_t metro_tiletable_size;
UINT16 *metro_vram_0,*metro_vram_1,*metro_vram_2;
UINT16 *metro_window;
static int support_8bpp,support_16x16;
static int has_zoom;
UINT16 *metro_K053936_ram;
static tilemap_t *metro_K053936_tilemap;
static UINT16 *metro_tiletable_old;
static UINT8 *dirtyindex;
static TILE_GET_INFO( metro_K053936_get_tile_info )
static TILE_GET_INFO( metro_k053936_get_tile_info )
{
int code = metro_K053936_ram[tile_index];
metro_state *state = (metro_state *)machine->driver_data;
int code = state->k053936_ram[tile_index];
SET_TILE_INFO(
2,
@ -86,9 +68,10 @@ static TILE_GET_INFO( metro_K053936_get_tile_info )
0);
}
static TILE_GET_INFO( metro_K053936_gstrik2_get_tile_info )
static TILE_GET_INFO( metro_k053936_gstrik2_get_tile_info )
{
int code = metro_K053936_ram[tile_index];
metro_state *state = (metro_state *)machine->driver_data;
int code = state->k053936_ram[tile_index];
SET_TILE_INFO(
2,
@ -97,10 +80,11 @@ static TILE_GET_INFO( metro_K053936_gstrik2_get_tile_info )
0);
}
WRITE16_HANDLER( metro_K053936_w )
WRITE16_HANDLER( metro_k053936_w )
{
COMBINE_DATA(&metro_K053936_ram[offset]);
tilemap_mark_tile_dirty(metro_K053936_tilemap,offset);
metro_state *state = (metro_state *)space->machine->driver_data;
COMBINE_DATA(&state->k053936_ram[offset]);
tilemap_mark_tile_dirty(state->k053936_tilemap, offset);
}
static TILEMAP_MAPPER( tilemap_scan_gstrik2 )
@ -108,10 +92,10 @@ static TILEMAP_MAPPER( tilemap_scan_gstrik2 )
/* logical (col,row) -> memory offset */
int val;
val = (row&0x3f)*(256*2) + (col*2);
val = (row & 0x3f) * (256 * 2) + (col * 2);
if (row&0x40) val+=1;
if (row&0x80) val+=256;
if (row & 0x40) val += 1;
if (row & 0x80) val += 256;
return val;
}
@ -129,7 +113,7 @@ static TILEMAP_MAPPER( tilemap_scan_gstrik2 )
WRITE16_HANDLER( metro_paletteram_w )
{
data = COMBINE_DATA(&space->machine->generic.paletteram.u16[offset]);
palette_set_color_rgb(space->machine,offset,pal5bit(data >> 6),pal5bit(data >> 11),pal5bit(data >> 1));
palette_set_color_rgb(space->machine, offset, pal5bit(data >> 6), pal5bit(data >> 11), pal5bit(data >> 1));
}
#endif
@ -163,46 +147,41 @@ WRITE16_HANDLER( metro_paletteram_w )
***************************************************************************/
static tilemap_t *bg_tilemap[3];
static tilemap_t *tilemap_16x16[3];
static UINT8 *empty_tiles;
/* A 2048 x 2048 virtual tilemap */
#define BIG_NX (0x100)
#define BIG_NY (0x100)
#define BIG_NX 0x100
#define BIG_NY 0x100
/* A smaller 512 x 256 window defines the actual tilemap */
#define WIN_NX (0x40)
#define WIN_NY (0x20)
//#define WIN_NX (0x40+1)
//#define WIN_NY (0x20+1)
#define WIN_NX 0x40
#define WIN_NY 0x20
//#define WIN_NX 0x40 + 1
//#define WIN_NY 0x20 + 1
/* 8x8x4 tiles only */
INLINE void get_tile_info(running_machine *machine,tile_data *tileinfo,int tile_index,int layer,UINT16 *vram)
INLINE void get_tile_info( running_machine *machine, tile_data *tileinfo, int tile_index, int layer, UINT16 *vram )
{
metro_state *state = (metro_state *)machine->driver_data;
UINT16 code;
int table_index;
UINT32 tile;
int table_index;
UINT32 tile;
/* The actual tile index depends on the window */
tile_index = ((tile_index / WIN_NX + metro_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX +
((tile_index % WIN_NX + metro_window[layer * 2 + 1] / 8) % BIG_NX);
tile_index = ((tile_index / WIN_NX + state->window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX +
((tile_index % WIN_NX + state->window[layer * 2 + 1] / 8) % BIG_NX);
/* Fetch the code */
code = vram[ tile_index ];
code = vram[tile_index];
/* Use it as an index into the tiles set table */
table_index = ( (code & 0x1ff0) >> 4 ) * 2;
tile = (metro_tiletable[table_index + 0] << 16 ) +
metro_tiletable[table_index + 1];
table_index = ((code & 0x1ff0) >> 4) * 2;
tile = (state->tiletable[table_index + 0] << 16) + state->tiletable[table_index + 1];
if (code & 0x8000) /* Special: draw a tile of a single color (i.e. not from the gfx ROMs) */
{
int _code = code & 0x000f;
tileinfo->pen_data = empty_tiles + _code*16*16;
tileinfo->pen_data = state->empty_tiles + _code * 16 * 16;
tileinfo->palette_base = ((code & 0x0ff0)) + 0x1000;
tileinfo->flags = 0;
tileinfo->group = 0;
@ -221,33 +200,33 @@ INLINE void get_tile_info(running_machine *machine,tile_data *tileinfo,int tile_
/* 8x8x4 or 8x8x8 tiles. It's the tile's color that decides: if its low 4
bits are high ($f,$1f,$2f etc) the tile is 8bpp, otherwise it's 4bpp */
INLINE void get_tile_info_8bit(running_machine *machine,tile_data *tileinfo,int tile_index,int layer,UINT16 *vram)
INLINE void get_tile_info_8bit( running_machine *machine, tile_data *tileinfo, int tile_index, int layer, UINT16 *vram )
{
metro_state *state = (metro_state *)machine->driver_data;
UINT16 code;
int table_index;
UINT32 tile;
int table_index;
UINT32 tile;
/* The actual tile index depends on the window */
tile_index = ((tile_index / WIN_NX + metro_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX +
((tile_index % WIN_NX + metro_window[layer * 2 + 1] / 8) % BIG_NX);
tile_index = ((tile_index / WIN_NX + state->window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX +
((tile_index % WIN_NX + state->window[layer * 2 + 1] / 8) % BIG_NX);
/* Fetch the code */
code = vram[ tile_index ];
code = vram[tile_index];
/* Use it as an index into the tiles set table */
table_index = ( (code & 0x1ff0) >> 4 ) * 2;
tile = (metro_tiletable[table_index + 0] << 16 ) +
metro_tiletable[table_index + 1];
table_index = ((code & 0x1ff0) >> 4) * 2;
tile = (state->tiletable[table_index + 0] << 16) + state->tiletable[table_index + 1];
if (code & 0x8000) /* Special: draw a tile of a single color (i.e. not from the gfx ROMs) */
{
int _code = code & 0x000f;
tileinfo->pen_data = empty_tiles + _code*16*16;
tileinfo->pen_data = state->empty_tiles + _code * 16 * 16;
tileinfo->palette_base = ((code & 0x0ff0)) + 0x1000;
tileinfo->flags = 0;
tileinfo->group = 0;
}
else if ((tile & 0x00f00000)==0x00f00000) /* draw tile as 8bpp */
else if ((tile & 0x00f00000) == 0x00f00000) /* draw tile as 8bpp */
{
tileinfo->group = 1;
SET_TILE_INFO(
@ -269,33 +248,33 @@ INLINE void get_tile_info_8bit(running_machine *machine,tile_data *tileinfo,int
/* 16x16x4 or 16x16x8 tiles. It's the tile's color that decides: if its low 4
bits are high ($f,$1f,$2f etc) the tile is 8bpp, otherwise it's 4bpp */
INLINE void get_tile_info_16x16_8bit(running_machine *machine,tile_data *tileinfo,int tile_index,int layer,UINT16 *vram)
INLINE void get_tile_info_16x16_8bit( running_machine *machine, tile_data *tileinfo, int tile_index, int layer, UINT16 *vram )
{
metro_state *state = (metro_state *)machine->driver_data;
UINT16 code;
int table_index;
UINT32 tile;
int table_index;
UINT32 tile;
/* The actual tile index depends on the window */
tile_index = ((tile_index / WIN_NX + metro_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX +
((tile_index % WIN_NX + metro_window[layer * 2 + 1] / 8) % BIG_NX);
tile_index = ((tile_index / WIN_NX + state->window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX +
((tile_index % WIN_NX + state->window[layer * 2 + 1] / 8) % BIG_NX);
/* Fetch the code */
code = vram[ tile_index ];
code = vram[tile_index];
/* Use it as an index into the tiles set table */
table_index = ( (code & 0x1ff0) >> 4 ) * 2;
tile = (metro_tiletable[table_index + 0] << 16 ) +
metro_tiletable[table_index + 1];
table_index = ((code & 0x1ff0) >> 4) * 2;
tile = (state->tiletable[table_index + 0] << 16) + state->tiletable[table_index + 1];
if (code & 0x8000) /* Special: draw a tile of a single color (i.e. not from the gfx ROMs) */
{
int _code = code & 0x000f;
tileinfo->pen_data = empty_tiles + _code*16*16;
tileinfo->pen_data = state->empty_tiles + _code * 16 * 16;
tileinfo->palette_base = ((code & 0x0ff0)) + 0x1000;
tileinfo->flags = 0;
tileinfo->group = 0;
}
else if ((tile & 0x00f00000)==0x00f00000) /* draw tile as 8bpp */
else if ((tile & 0x00f00000) == 0x00f00000) /* draw tile as 8bpp */
{
tileinfo->group = 1;
SET_TILE_INFO(
@ -317,55 +296,58 @@ INLINE void get_tile_info_16x16_8bit(running_machine *machine,tile_data *tileinf
}
INLINE void metro_vram_w(offs_t offset,UINT16 data,UINT16 mem_mask,int layer,UINT16 *vram)
INLINE void metro_vram_w( running_machine *machine, offs_t offset, UINT16 data, UINT16 mem_mask, int layer, UINT16 *vram )
{
metro_state *state = (metro_state *)machine->driver_data;
COMBINE_DATA(&vram[offset]);
{
/* Account for the window */
int col = (offset % BIG_NX) - ((metro_window[layer * 2 + 1] / 8) % BIG_NX);
int row = (offset / BIG_NX) - ((metro_window[layer * 2 + 0] / 8) % BIG_NY);
int col = (offset % BIG_NX) - ((state->window[layer * 2 + 1] / 8) % BIG_NX);
int row = (offset / BIG_NX) - ((state->window[layer * 2 + 0] / 8) % BIG_NY);
if (col < -(BIG_NX-WIN_NX)) col += (BIG_NX-WIN_NX) + WIN_NX;
if (row < -(BIG_NY-WIN_NY)) row += (BIG_NY-WIN_NY) + WIN_NY;
if ( (col >= 0) && (col < WIN_NX) &&
(row >= 0) && (row < WIN_NY) )
if ((col >= 0) && (col < WIN_NX) && (row >= 0) && (row < WIN_NY))
{
tilemap_mark_tile_dirty(bg_tilemap[layer], row * WIN_NX + col );
if (tilemap_16x16[layer])
tilemap_mark_tile_dirty(tilemap_16x16[layer], row * WIN_NX + col );
tilemap_mark_tile_dirty(state->bg_tilemap[layer], row * WIN_NX + col);
if (state->tilemap_16x16[layer])
tilemap_mark_tile_dirty(state->tilemap_16x16[layer], row * WIN_NX + col);
}
}
}
static TILE_GET_INFO( get_tile_info_0 ) { get_tile_info(machine,tileinfo,tile_index,0,metro_vram_0); }
static TILE_GET_INFO( get_tile_info_1 ) { get_tile_info(machine,tileinfo,tile_index,1,metro_vram_1); }
static TILE_GET_INFO( get_tile_info_2 ) { get_tile_info(machine,tileinfo,tile_index,2,metro_vram_2); }
static TILE_GET_INFO( get_tile_info_0 ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info(machine, tileinfo, tile_index, 0, state->vram_0); }
static TILE_GET_INFO( get_tile_info_1 ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info(machine, tileinfo, tile_index, 1, state->vram_1); }
static TILE_GET_INFO( get_tile_info_2 ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info(machine, tileinfo, tile_index, 2, state->vram_2); }
static TILE_GET_INFO( get_tile_info_0_8bit ) { get_tile_info_8bit(machine,tileinfo,tile_index,0,metro_vram_0); }
static TILE_GET_INFO( get_tile_info_1_8bit ) { get_tile_info_8bit(machine,tileinfo,tile_index,1,metro_vram_1); }
static TILE_GET_INFO( get_tile_info_2_8bit ) { get_tile_info_8bit(machine,tileinfo,tile_index,2,metro_vram_2); }
static TILE_GET_INFO( get_tile_info_0_8bit ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info_8bit(machine, tileinfo, tile_index, 0, state->vram_0); }
static TILE_GET_INFO( get_tile_info_1_8bit ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info_8bit(machine, tileinfo, tile_index, 1, state->vram_1); }
static TILE_GET_INFO( get_tile_info_2_8bit ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info_8bit(machine, tileinfo, tile_index, 2, state->vram_2); }
static TILE_GET_INFO( get_tile_info_0_16x16_8bit ) { get_tile_info_16x16_8bit(machine,tileinfo,tile_index,0,metro_vram_0); }
static TILE_GET_INFO( get_tile_info_1_16x16_8bit ) { get_tile_info_16x16_8bit(machine,tileinfo,tile_index,1,metro_vram_1); }
static TILE_GET_INFO( get_tile_info_2_16x16_8bit ) { get_tile_info_16x16_8bit(machine,tileinfo,tile_index,2,metro_vram_2); }
static TILE_GET_INFO( get_tile_info_0_16x16_8bit ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info_16x16_8bit(machine, tileinfo, tile_index, 0, state->vram_0); }
static TILE_GET_INFO( get_tile_info_1_16x16_8bit ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info_16x16_8bit(machine, tileinfo, tile_index, 1, state->vram_1); }
static TILE_GET_INFO( get_tile_info_2_16x16_8bit ) { metro_state *state = (metro_state *)machine->driver_data; get_tile_info_16x16_8bit(machine, tileinfo, tile_index, 2, state->vram_2); }
WRITE16_HANDLER( metro_vram_0_w ) { metro_vram_w(offset,data,mem_mask,0,metro_vram_0); }
WRITE16_HANDLER( metro_vram_1_w ) { metro_vram_w(offset,data,mem_mask,1,metro_vram_1); }
WRITE16_HANDLER( metro_vram_2_w ) { metro_vram_w(offset,data,mem_mask,2,metro_vram_2); }
WRITE16_HANDLER( metro_vram_0_w ) { metro_state *state = (metro_state *)space->machine->driver_data; metro_vram_w(space->machine, offset, data, mem_mask, 0, state->vram_0); }
WRITE16_HANDLER( metro_vram_1_w ) { metro_state *state = (metro_state *)space->machine->driver_data; metro_vram_w(space->machine, offset, data, mem_mask, 1, state->vram_1); }
WRITE16_HANDLER( metro_vram_2_w ) { metro_state *state = (metro_state *)space->machine->driver_data; metro_vram_w(space->machine, offset, data, mem_mask, 2, state->vram_2); }
/* Dirty the relevant tilemap when its window changes */
WRITE16_HANDLER( metro_window_w )
{
UINT16 olddata = metro_window[offset];
UINT16 newdata = COMBINE_DATA( &metro_window[offset] );
if ( newdata != olddata )
metro_state *state = (metro_state *)space->machine->driver_data;
UINT16 olddata = state->window[offset];
UINT16 newdata = COMBINE_DATA(&state->window[offset]);
if (newdata != olddata)
{
offset /= 2;
tilemap_mark_all_tiles_dirty(bg_tilemap[offset]);
if (tilemap_16x16[offset]) tilemap_mark_all_tiles_dirty(tilemap_16x16[offset]);
tilemap_mark_all_tiles_dirty(state->bg_tilemap[offset]);
if (state->tilemap_16x16[offset])
tilemap_mark_all_tiles_dirty(state->tilemap_16x16[offset]);
}
}
@ -387,144 +369,198 @@ WRITE16_HANDLER( metro_window_w )
the tile's sizes to be known at startup - which we don't!
*/
static int metro_sprite_xoffs, metro_sprite_yoffs;
static void alloc_empty_tiles(running_machine *machine)
/* Dirty tilemaps when the tiles set changes */
static void dirty_tiles( running_machine *machine, int layer, UINT16 *vram )
{
int code,i;
metro_state *state = (metro_state *)machine->driver_data;
int col, row;
empty_tiles = auto_alloc_array(machine, UINT8, 16*16*16);
for (row = 0; row < WIN_NY; row++)
{
for (col = 0; col < WIN_NX; col++)
{
int offset = (col + state->window[layer * 2 + 1] / 8) % BIG_NX +
((row + state->window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX;
UINT16 code = vram[offset];
for (code = 0;code < 0x10;code++)
for (i = 0;i < 16*16;i++)
empty_tiles[16*16*code + i] = code;
if (!(code & 0x8000) && state->dirtyindex[(code & 0x1ff0) >> 4])
{
tilemap_mark_tile_dirty(state->bg_tilemap[layer], row * WIN_NX + col);
if (state->tilemap_16x16[layer])
tilemap_mark_tile_dirty(state->tilemap_16x16[layer], row * WIN_NX + col);
}
}
}
}
static STATE_POSTLOAD( metro_tile_dirty_postload )
{
metro_state *state = (metro_state *)machine->driver_data;
/* FIXME: this is still not enough in some games (e.g. 3kokushi) */
memset(state->dirtyindex, 1, state->tiletable_size / 4);
dirty_tiles(machine, 0, state->vram_0);
dirty_tiles(machine, 1, state->vram_1);
dirty_tiles(machine, 2, state->vram_2);
memcpy(state->tiletable_old, state->tiletable, state->tiletable_size);
}
static void alloc_empty_tiles( running_machine *machine )
{
metro_state *state = (metro_state *)machine->driver_data;
int code, i;
state->empty_tiles = auto_alloc_array(machine, UINT8, 16 * 16 * 16);
for (code = 0; code < 0x10; code++)
for (i = 0; i < 16 * 16; i++)
state->empty_tiles[16 * 16 * code + i] = code;
}
VIDEO_START( metro_14100 )
{
support_8bpp = 0;
support_16x16 = 0;
has_zoom = 0;
metro_state *state = (metro_state *)machine->driver_data;
state->support_8bpp = 0;
state->support_16x16 = 0;
state->has_zoom = 0;
alloc_empty_tiles(machine);
metro_tiletable_old = auto_alloc_array(machine, UINT16, metro_tiletable_size/2);
dirtyindex = auto_alloc_array(machine, UINT8, metro_tiletable_size/4);
bg_tilemap[0] = tilemap_create(machine, get_tile_info_0,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
bg_tilemap[1] = tilemap_create(machine, get_tile_info_1,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
bg_tilemap[2] = tilemap_create(machine, get_tile_info_2,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
state->tiletable_old = auto_alloc_array(machine, UINT16, state->tiletable_size / 2);
state->dirtyindex = auto_alloc_array(machine, UINT8, state->tiletable_size / 4);
tilemap_16x16[0] = NULL;
tilemap_16x16[1] = NULL;
tilemap_16x16[2] = NULL;
state->bg_tilemap[0] = tilemap_create(machine, get_tile_info_0, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
state->bg_tilemap[1] = tilemap_create(machine, get_tile_info_1, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
state->bg_tilemap[2] = tilemap_create(machine, get_tile_info_2, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
tilemap_map_pen_to_layer(bg_tilemap[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
state->tilemap_16x16[0] = NULL;
state->tilemap_16x16[1] = NULL;
state->tilemap_16x16[2] = NULL;
tilemap_map_pen_to_layer(bg_tilemap[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
state_save_register_global_pointer(machine, state->tiletable_old, state->tiletable_size / 2);
state_save_register_postload(machine, metro_tile_dirty_postload, NULL);
}
VIDEO_START( metro_14220 )
{
support_8bpp = 1;
support_16x16 = 0;
has_zoom = 0;
metro_state *state = (metro_state *)machine->driver_data;
state->support_8bpp = 1;
state->support_16x16 = 0;
state->has_zoom = 0;
alloc_empty_tiles(machine);
metro_tiletable_old = auto_alloc_array(machine, UINT16, metro_tiletable_size/2);
dirtyindex = auto_alloc_array(machine, UINT8, metro_tiletable_size/4);
bg_tilemap[0] = tilemap_create(machine, get_tile_info_0_8bit,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
bg_tilemap[1] = tilemap_create(machine, get_tile_info_1_8bit,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
bg_tilemap[2] = tilemap_create(machine, get_tile_info_2_8bit,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
state->tiletable_old = auto_alloc_array(machine, UINT16, state->tiletable_size / 2);
state->dirtyindex = auto_alloc_array(machine, UINT8, state->tiletable_size / 4);
tilemap_16x16[0] = NULL;
tilemap_16x16[1] = NULL;
tilemap_16x16[2] = NULL;
state->bg_tilemap[0] = tilemap_create(machine, get_tile_info_0_8bit, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
state->bg_tilemap[1] = tilemap_create(machine, get_tile_info_1_8bit, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
state->bg_tilemap[2] = tilemap_create(machine, get_tile_info_2_8bit, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
tilemap_map_pen_to_layer(bg_tilemap[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
state->tilemap_16x16[0] = NULL;
state->tilemap_16x16[1] = NULL;
state->tilemap_16x16[2] = NULL;
tilemap_map_pen_to_layer(bg_tilemap[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_set_scrolldx(bg_tilemap[0], -2, 2);
tilemap_set_scrolldx(bg_tilemap[1], -2, 2);
tilemap_set_scrolldx(bg_tilemap[2], -2, 2);
tilemap_map_pen_to_layer(state->bg_tilemap[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_set_scrolldx(state->bg_tilemap[0], -2, 2);
tilemap_set_scrolldx(state->bg_tilemap[1], -2, 2);
tilemap_set_scrolldx(state->bg_tilemap[2], -2, 2);
state_save_register_global_pointer(machine, state->tiletable_old, state->tiletable_size / 2);
state_save_register_postload(machine, metro_tile_dirty_postload, NULL);
}
VIDEO_START( metro_14300 )
{
support_8bpp = 1;
support_16x16 = 1;
has_zoom = 0;
metro_state *state = (metro_state *)machine->driver_data;
state->support_8bpp = 1;
state->support_16x16 = 1;
state->has_zoom = 0;
alloc_empty_tiles(machine);
metro_tiletable_old = auto_alloc_array(machine, UINT16, metro_tiletable_size/2);
dirtyindex = auto_alloc_array(machine, UINT8, metro_tiletable_size/4);
bg_tilemap[0] = tilemap_create(machine, get_tile_info_0_8bit,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
bg_tilemap[1] = tilemap_create(machine, get_tile_info_1_8bit,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
bg_tilemap[2] = tilemap_create(machine, get_tile_info_2_8bit,tilemap_scan_rows,8,8,WIN_NX,WIN_NY);
state->tiletable_old = auto_alloc_array(machine, UINT16, state->tiletable_size / 2);
state->dirtyindex = auto_alloc_array(machine, UINT8, state->tiletable_size / 4);
tilemap_16x16[0] = tilemap_create(machine, get_tile_info_0_16x16_8bit,tilemap_scan_rows,16,16,WIN_NX,WIN_NY);
tilemap_16x16[1] = tilemap_create(machine, get_tile_info_1_16x16_8bit,tilemap_scan_rows,16,16,WIN_NX,WIN_NY);
tilemap_16x16[2] = tilemap_create(machine, get_tile_info_2_16x16_8bit,tilemap_scan_rows,16,16,WIN_NX,WIN_NY);
state->bg_tilemap[0] = tilemap_create(machine, get_tile_info_0_8bit, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
state->bg_tilemap[1] = tilemap_create(machine, get_tile_info_1_8bit, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
state->bg_tilemap[2] = tilemap_create(machine, get_tile_info_2_8bit, tilemap_scan_rows, 8, 8, WIN_NX, WIN_NY);
tilemap_map_pen_to_layer(bg_tilemap[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
state->tilemap_16x16[0] = tilemap_create(machine, get_tile_info_0_16x16_8bit, tilemap_scan_rows, 16, 16, WIN_NX, WIN_NY);
state->tilemap_16x16[1] = tilemap_create(machine, get_tile_info_1_16x16_8bit, tilemap_scan_rows, 16, 16, WIN_NX, WIN_NY);
state->tilemap_16x16[2] = tilemap_create(machine, get_tile_info_2_16x16_8bit, tilemap_scan_rows, 16, 16, WIN_NX, WIN_NY);
tilemap_map_pen_to_layer(bg_tilemap[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(bg_tilemap[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->bg_tilemap[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(tilemap_16x16[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(tilemap_16x16[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->tilemap_16x16[0], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->tilemap_16x16[0], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(tilemap_16x16[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(tilemap_16x16[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->tilemap_16x16[1], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->tilemap_16x16[1], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(tilemap_16x16[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(tilemap_16x16[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->tilemap_16x16[2], 0, 15, TILEMAP_PIXEL_TRANSPARENT);
tilemap_map_pen_to_layer(state->tilemap_16x16[2], 1, 255, TILEMAP_PIXEL_TRANSPARENT);
state_save_register_global_pointer(machine, state->tiletable_old, state->tiletable_size / 2);
state_save_register_postload(machine, metro_tile_dirty_postload, NULL);
}
VIDEO_START( blzntrnd )
{
metro_state *state = (metro_state *)machine->driver_data;
VIDEO_START_CALL(metro_14220);
has_zoom = 1;
state->has_zoom = 1;
metro_K053936_tilemap = tilemap_create(machine, metro_K053936_get_tile_info, tilemap_scan_rows, 8,8, 256, 512 );
state->k053936_tilemap = tilemap_create(machine, metro_k053936_get_tile_info, tilemap_scan_rows, 8, 8, 256, 512);
tilemap_set_scrolldx(bg_tilemap[0], 8, -8);
tilemap_set_scrolldx(bg_tilemap[1], 8, -8);
tilemap_set_scrolldx(bg_tilemap[2], 8, -8);
tilemap_set_scrolldx(state->bg_tilemap[0], 8, -8);
tilemap_set_scrolldx(state->bg_tilemap[1], 8, -8);
tilemap_set_scrolldx(state->bg_tilemap[2], 8, -8);
}
VIDEO_START( gstrik2 )
{
metro_state *state = (metro_state *)machine->driver_data;
VIDEO_START_CALL(metro_14220);
has_zoom = 1;
state->has_zoom = 1;
metro_K053936_tilemap = tilemap_create(machine, metro_K053936_gstrik2_get_tile_info, tilemap_scan_gstrik2, 16,16, 128, 256 );
state->k053936_tilemap = tilemap_create(machine, metro_k053936_gstrik2_get_tile_info, tilemap_scan_gstrik2, 16, 16, 128, 256);
tilemap_set_scrolldx(bg_tilemap[0], 8, -8);
tilemap_set_scrolldx(bg_tilemap[1], 0, 0);
tilemap_set_scrolldx(bg_tilemap[2], 8, -8);
tilemap_set_scrolldx(state->bg_tilemap[0], 8, -8);
tilemap_set_scrolldx(state->bg_tilemap[1], 0, 0);
tilemap_set_scrolldx(state->bg_tilemap[2], 8, -8);
}
/***************************************************************************
@ -589,21 +625,22 @@ VIDEO_START( gstrik2 )
/* Draw sprites */
void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect)
void metro_draw_sprites( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect )
{
UINT8 *base_gfx = memory_region(machine, "gfx1");
UINT8 *gfx_max = base_gfx + memory_region_length(machine, "gfx1");
metro_state *state = (metro_state *)machine->driver_data;
UINT8 *base_gfx = memory_region(machine, "gfx1");
UINT8 *gfx_max = base_gfx + memory_region_length(machine, "gfx1");
int max_x = video_screen_get_width(machine->primary_screen);
int max_y = video_screen_get_height(machine->primary_screen);
int max_sprites = machine->generic.spriteram_size / 8;
int sprites = metro_videoregs[0x00/2] % max_sprites;
int max_sprites = state->spriteram_size / 8;
int sprites = state->videoregs[0x00/2] % max_sprites;
int color_start = ((metro_videoregs[0x08/2] & 0xf) << 4 ) + 0x100;
int color_start = ((state->videoregs[0x08/2] & 0x0f) << 4) + 0x100;
int i, j, pri;
static const int primask[4] = { 0x0000, 0xff00, 0xff00|0xf0f0, 0xff00|0xf0f0|0xcccc };
static const int primask[4] = { 0x0000, 0xff00, 0xff00 | 0xf0f0, 0xff00 | 0xf0f0 | 0xcccc };
UINT16 *src;
int inc;
@ -611,22 +648,22 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
if (sprites == 0)
return;
for (i=0; i<0x20; i++)
for (i = 0; i < 0x20; i++)
{
gfx_element gfx;
if (!(metro_videoregs[0x02/2] & 0x8000))
if (!(state->videoregs[0x02/2] & 0x8000))
{
src = machine->generic.spriteram.u16 + (sprites - 1) * (8/2);
inc = -(8/2);
src = state->spriteram + (sprites - 1) * (8 / 2);
inc = -(8 / 2);
} else {
src = machine->generic.spriteram.u16;
inc = (8/2);
src = state->spriteram;
inc = (8 / 2);
}
for (j=0; j<sprites; j++)
for (j = 0; j < sprites; j++)
{
int x,y, attr,code,color,flipx,flipy, zoom, curr_pri,width,height;
int x, y, attr, code, color, flipx, flipy, zoom, curr_pri, width, height;
UINT8 *gfxdata;
/* Exponential zoom table extracted from daitoride */
@ -640,8 +677,8 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
0x0A0,0x09C,0x098,0x094,0x090,0x08C,0x088,0x080,
0x078,0x070,0x068,0x060,0x058,0x050,0x048,0x040 };
x = src[ 0 ];
curr_pri = (x & 0xf800) >> 11;
x = src[0];
curr_pri = (x & 0xf800) >> 11;
if ((curr_pri == 0x1f) || (curr_pri != i))
{
@ -649,31 +686,31 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
continue;
}
pri = (metro_videoregs[0x02/2] & 0x0300) >> 8;
pri = (state->videoregs[0x02/2] & 0x0300) >> 8;
if (!(metro_videoregs[0x02/2] & 0x8000))
if (!(state->videoregs[0x02/2] & 0x8000))
{
if (curr_pri > (metro_videoregs[0x02/2] & 0x1f))
pri = (metro_videoregs[0x02/2] & 0x0c00) >> 10;
if (curr_pri > (state->videoregs[0x02/2] & 0x1f))
pri = (state->videoregs[0x02/2] & 0x0c00) >> 10;
}
y = src[ 1 ];
attr = src[ 2 ];
code = src[ 3 ];
y = src[1];
attr = src[2];
code = src[3];
flipx = attr & 0x8000;
flipy = attr & 0x4000;
color = (attr & 0xf0) >> 4;
flipx = attr & 0x8000;
flipy = attr & 0x4000;
color = (attr & 0xf0) >> 4;
zoom = zoomtable[(y & 0xfc00) >> 10] << (16-8);
zoom = zoomtable[(y & 0xfc00) >> 10] << (16 - 8);
x = (x & 0x07ff) - metro_sprite_xoffs;
y = (y & 0x03ff) - metro_sprite_yoffs;
x = (x & 0x07ff) - state->sprite_xoffs;
y = (y & 0x03ff) - state->sprite_yoffs;
width = (( (attr >> 11) & 0x7 ) + 1 ) * 8;
height = (( (attr >> 8) & 0x7 ) + 1 ) * 8;
width = (((attr >> 11) & 0x7) + 1) * 8;
height = (((attr >> 8) & 0x7) + 1) * 8;
gfxdata = base_gfx + (8*8*4/8) * (((attr & 0x000f) << 16) + code);
gfxdata = base_gfx + (8 * 8 * 4 / 8) * (((attr & 0x000f) << 16) + code);
if (flip_screen_get(machine))
{
@ -681,10 +718,10 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
flipy = !flipy; y = max_y - y - height;
}
if (support_8bpp && color == 0xf) /* 8bpp */
if (state->support_8bpp && color == 0xf) /* 8bpp */
{
/* Bounds checking */
if ( (gfxdata + width * height - 1) >= gfx_max )
if ((gfxdata + width * height - 1) >= gfx_max)
continue;
gfx_element_build_temporary(&gfx, machine, gfxdata, width, height, width, 0, 256, 0);
@ -700,7 +737,7 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
else
{
/* Bounds checking */
if ( (gfxdata + width/2 * height - 1) >= gfx_max )
if ((gfxdata + width / 2 * height - 1) >= gfx_max)
continue;
gfx_element_build_temporary(&gfx, machine, gfxdata, width, height, width/2, 0, 16, GFX_ELEMENT_PACKED);
@ -716,7 +753,7 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
#if 0
{ /* Display priority + zoom on each sprite */
char buf[80];
sprintf(buf, "%02X %02X",((src[ 0 ] & 0xf800) >> 11)^0x1f,((src[ 1 ] & 0xfc00) >> 10) );
sprintf(buf, "%02X %02X", ((src[0] & 0xf800) >> 11) ^ 0x1f, ((src[1] & 0xfc00) >> 10));
ui_draw_text(buf, x, y);
}
#endif
@ -735,43 +772,43 @@ void metro_draw_sprites(running_machine *machine, bitmap_t *bitmap, const rectan
***************************************************************************/
static void draw_tilemap(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, tilemap_t *tmap, UINT32 flags, UINT32 priority,
int sx, int sy, int wx, int wy) // scroll & window values
static void draw_tilemap( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, tilemap_t *tmap, UINT32 flags, UINT32 priority,
int sx, int sy, int wx, int wy ) // scroll & window values
{
#if 1
tilemap_set_scrollx(tmap, 0, sx - wx + (wx & 7));
tilemap_set_scrolly(tmap, 0, sy - wy + (wy & 7));
tilemap_draw(bitmap,cliprect,tmap, flags, priority);
tilemap_draw(bitmap, cliprect, tmap, flags, priority);
#else
int x,y,i;
int x, y, i;
const rectangle *visarea = video_screen_get_visible_area(machine->primary_screen);
/* sub tile placement */
// sx = sx - (wx & ~7) + (wx & 7);
sx = sx - wx;
sx = ( (sx & 0x7fff) - (sx & 0x8000) ) % ((WIN_NX-1)*8);
// sx = sx - (wx & ~7) + (wx & 7);
sx = sx - wx;
sx = ((sx & 0x7fff) - (sx & 0x8000)) % ((WIN_NX - 1) * 8);
// sy = sy - (wy & ~7) + (wy & 7);
sy = sy - wy;
sy = ( (sy & 0x7fff) - (sy & 0x8000) ) % ((WIN_NY-1)*8);
// sy = sy - (wy & ~7) + (wy & 7);
sy = sy - wy;
sy = ((sy & 0x7fff) - (sy & 0x8000)) % ((WIN_NY - 1) * 8);
/* splitting point */
x = (WIN_NX-1)*8 - sx;
x = (WIN_NX - 1) * 8 - sx;
y = (WIN_NY-1)*8 - sy;
y = (WIN_NY - 1) * 8 - sy;
for ( i = 0; i < 4 ; i++ )
for (i = 0; i < 4 ; i++)
{
rectangle clip;
tilemap_set_scrollx(tmap, 0, sx + ((i & 1) ? -x : 0));
tilemap_set_scrolly(tmap, 0, sy + ((i & 2) ? -y : 0));
clip.min_x = x - ((i & 1) ? 0 : (WIN_NX-1)*8);
clip.min_y = y - ((i & 2) ? 0 : (WIN_NY-1)*8);
clip.min_x = x - ((i & 1) ? 0 : (WIN_NX - 1) * 8);
clip.min_y = y - ((i & 2) ? 0 : (WIN_NY - 1) * 8);
clip.max_x = clip.min_x + (WIN_NX-1)*8 - 1;
clip.max_y = clip.min_y + (WIN_NY-1)*8 - 1;
clip.max_x = clip.min_x + (WIN_NX - 1) * 8 - 1;
clip.max_y = clip.min_y + (WIN_NY - 1) * 8 - 1;
if (clip.min_x > visarea->max_x) continue;
if (clip.min_y > visarea->max_y) continue;
@ -789,32 +826,34 @@ static void draw_tilemap(running_machine *machine, bitmap_t *bitmap, const recta
This fact renderes the function useless, as far as
we are concerned! */
tilemap_set_clip(tmap, &clip);
tilemap_draw(bitmap,cliprect,tmap, flags, priority);
tilemap_draw(bitmap, cliprect, tmap, flags, priority);
}
#endif
}
/* Draw all the layers that match the given priority */
static void draw_layers(running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int pri, int layers_ctrl)
static void draw_layers( running_machine *machine, bitmap_t *bitmap, const rectangle *cliprect, int pri, int layers_ctrl )
{
UINT16 layers_pri = metro_videoregs[0x10/2];
metro_state *state = (metro_state *)machine->driver_data;
UINT16 layers_pri = state->videoregs[0x10 / 2];
int layer;
/* Draw all the layers with priority == pri */
for (layer = 2; layer >= 0; layer--) // tilemap[2] below?
{
if ( pri == ((layers_pri >> (layer*2)) & 3) )
if (pri == ((layers_pri >> (layer * 2)) & 3))
{
/* Scroll and Window values */
UINT16 sy = metro_scroll[layer * 2 + 0]; UINT16 sx = metro_scroll[layer * 2 + 1];
UINT16 wy = metro_window[layer * 2 + 0]; UINT16 wx = metro_window[layer * 2 + 1];
UINT16 sy = state->scroll[layer * 2 + 0]; UINT16 sx = state->scroll[layer * 2 + 1];
UINT16 wy = state->window[layer * 2 + 0]; UINT16 wx = state->window[layer * 2 + 1];
if (layers_ctrl & (1<<layer)) // for debug
if (BIT(layers_ctrl, layer)) // for debug
{
/* Only *one* of tilemap_16x16 & tilemap is enabled at any given time! */
draw_tilemap(machine, bitmap,cliprect,bg_tilemap[layer], 0, 1<<(3-pri), sx, sy, wx, wy);
if (tilemap_16x16[layer]) draw_tilemap(machine, bitmap,cliprect,tilemap_16x16[layer], 0, 1<<(3-pri), sx, sy, wx, wy);
draw_tilemap(machine, bitmap, cliprect, state->bg_tilemap[layer], 0, 1 << (3 - pri), sx, sy, wx, wy);
if (state->tilemap_16x16[layer])
draw_tilemap(machine, bitmap, cliprect, state->tilemap_16x16[layer], 0, 1 << (3 - pri), sx, sy, wx, wy);
}
}
}
@ -822,67 +861,43 @@ static void draw_layers(running_machine *machine, bitmap_t *bitmap, const rectan
/* Dirty tilemaps when the tiles set changes */
static void dirty_tiles(int layer,UINT16 *vram)
{
int col,row;
for (row = 0;row < WIN_NY;row++)
{
for (col = 0;col < WIN_NX;col++)
{
int offset = (col + metro_window[layer * 2 + 1] / 8) % BIG_NX +
((row + metro_window[layer * 2 + 0] / 8) % BIG_NY) * BIG_NX;
UINT16 code = vram[offset];
if (!(code & 0x8000) && dirtyindex[(code & 0x1ff0) >> 4])
{
tilemap_mark_tile_dirty(bg_tilemap[layer], row * WIN_NX + col );
if (tilemap_16x16[layer])
tilemap_mark_tile_dirty(tilemap_16x16[layer], row * WIN_NX + col );
}
}
}
}
VIDEO_UPDATE( metro )
{
running_device *k053936 = devtag_get_device(screen->machine, "k053936");
int i,pri,layers_ctrl = -1;
UINT16 screenctrl = *metro_screenctrl;
metro_state *state = (metro_state *)screen->machine->driver_data;
int i, pri, layers_ctrl = -1;
UINT16 screenctrl = *state->screenctrl;
{
int dirty = 0;
memset(dirtyindex,0,metro_tiletable_size/4);
for (i = 0;i < metro_tiletable_size/4;i++)
memset(state->dirtyindex, 0, state->tiletable_size / 4);
for (i = 0; i < state->tiletable_size / 4; i++)
{
UINT32 tile_new = (metro_tiletable[2*i + 0] << 16 ) + metro_tiletable[2*i + 1];
UINT32 tile_old = (metro_tiletable_old[2*i + 0] << 16 ) + metro_tiletable_old[2*i + 1];
UINT32 tile_new = (state->tiletable[2 * i + 0] << 16 ) + state->tiletable[2 * i + 1];
UINT32 tile_old = (state->tiletable_old[2 * i + 0] << 16 ) + state->tiletable_old[2 * i + 1];
if ((tile_new ^ tile_old) & 0x0fffffff)
{
dirtyindex[i] = 1;
state->dirtyindex[i] = 1;
dirty = 1;
}
}
memcpy(metro_tiletable_old,metro_tiletable,metro_tiletable_size);
memcpy(state->tiletable_old, state->tiletable, state->tiletable_size);
if (dirty)
{
dirty_tiles(0,metro_vram_0);
dirty_tiles(1,metro_vram_1);
dirty_tiles(2,metro_vram_2);
dirty_tiles(screen->machine, 0, state->vram_0);
dirty_tiles(screen->machine, 1, state->vram_1);
dirty_tiles(screen->machine, 2, state->vram_2);
}
}
metro_sprite_xoffs = metro_videoregs[0x06/2] - video_screen_get_width(screen) / 2;
metro_sprite_yoffs = metro_videoregs[0x04/2] - video_screen_get_height(screen) / 2;
state->sprite_xoffs = state->videoregs[0x06 / 2] - video_screen_get_width(screen) / 2;
state->sprite_yoffs = state->videoregs[0x04 / 2] - video_screen_get_height(screen) / 2;
/* The background color is selected by a register */
bitmap_fill(screen->machine->priority_bitmap,cliprect,0);
bitmap_fill(bitmap,cliprect,((metro_videoregs[0x12/2] & 0x0fff)) + 0x1000);
bitmap_fill(screen->machine->priority_bitmap, cliprect, 0);
bitmap_fill(bitmap, cliprect, ((state->videoregs[0x12/2] & 0x0fff)) + 0x1000);
/* Screen Control Register:
@ -895,22 +910,24 @@ VIDEO_UPDATE( metro )
---- ---- ---4 32--
---- ---- ---- --1- ? Blank Screen
---- ---- ---- ---0 Flip Screen */
if (screenctrl & 2) return 0;
if (screenctrl & 2)
return 0;
flip_screen_set(screen->machine, screenctrl & 1);
/* If the game supports 16x16 tiles, make sure that the
16x16 and 8x8 tilemaps of a given layer are not simultaneously
enabled! */
if (support_16x16)
if (state->support_16x16)
{
int layer;
for (layer = 0;layer < 3;layer++)
for (layer = 0; layer < 3; layer++)
{
int big = screenctrl & (0x0020 << layer);
tilemap_set_enable(bg_tilemap[layer],!big);
tilemap_set_enable(tilemap_16x16[layer],big);
tilemap_set_enable(state->bg_tilemap[layer],!big);
tilemap_set_enable(state->tilemap_16x16[layer], big);
}
}
@ -925,24 +942,24 @@ if (input_code_pressed(screen->machine, KEYCODE_Z))
if (input_code_pressed(screen->machine, KEYCODE_A)) msk |= 8;
if (msk != 0)
{
bitmap_fill(bitmap,cliprect,0);
bitmap_fill(bitmap, cliprect, 0);
layers_ctrl &= msk;
}
popmessage("l %x-%x-%x r %04x %04x %04x",
(metro_videoregs[0x10/2]&0x30)>>4,(metro_videoregs[0x10/2]&0xc)>>2,metro_videoregs[0x10/2]&3,
metro_videoregs[0x02/2], metro_videoregs[0x12/2],
*metro_screenctrl);
(state->videoregs[0x10/2] & 0x30) >> 4, (state->videoregs[0x10/2] & 0xc) >> 2, state->videoregs[0x10/2] & 3,
state->videoregs[0x02/2], state->videoregs[0x12/2],
*state->screenctrl);
}
#endif
if (has_zoom)
k053936_zoom_draw(k053936, bitmap, cliprect, metro_K053936_tilemap, 0, 0, 1);
if (state->has_zoom)
k053936_zoom_draw(state->k053936, bitmap, cliprect, state->k053936_tilemap, 0, 0, 1);
for (pri = 3; pri >= 0; pri--)
draw_layers(screen->machine, bitmap,cliprect,pri,layers_ctrl);
draw_layers(screen->machine, bitmap, cliprect, pri, layers_ctrl);
if (layers_ctrl & 0x08)
metro_draw_sprites(screen->machine, bitmap,cliprect);
metro_draw_sprites(screen->machine, bitmap, cliprect);
return 0;
}