Added dual screen output to the Konami GX Type 3/4 games [David Haywood]

-----Messaggio originale-----
Da: David Haywood [mailto:neohaze@nildram.co.uk]
Inviato: martedì 17 novembre 2009 0.44
A: Philip Bennett; Angelo Salese
Oggetto: Konami GX Type3/4 dual output

this starts to add dual screen output to the Koanmi GX Type 3 /4 games.

they're probably missing a sprite base register, because if you turn the
dipswitch for 2nd monitor on they're using the wrong spritelist, even in
Soccer Superstars, but otherwise the games automatically bank the
tilemaps in an appropriate way.

Kale, they seem to trigger extra protection writesi in this mode?

btw, Aaron, is there a way to tell MAME to default to a SINGLE screen
layout, but still give the dual screen layout in the video options, that
would better suit these games than displaying 2 screens by default
(because the 2nd screen only tells you that it's disabled at the moment)
This commit is contained in:
Phil Bennett 2009-11-19 23:10:11 +00:00
parent 5020027c32
commit d433391568
2 changed files with 217 additions and 19 deletions

View File

@ -105,6 +105,7 @@
#include "sound/k054539.h"
#include "konamigx.h"
#include "machine/adc083x.h"
#include "rendlay.h"
#define GX_DEBUG 0
@ -701,6 +702,8 @@ static INTERRUPT_GEN(konamigx_vbinterrupt)
dmastart_callback(0);
}
extern int konamigx_current_frame;
static INTERRUPT_GEN(konamigx_vbinterrupt_type4)
{
// lift idle suspension
@ -712,8 +715,8 @@ static INTERRUPT_GEN(konamigx_vbinterrupt_type4)
// maybe this interupt should only be every 30fps, or maybe there are flags to prevent the game running too fast
// the real hardware should output the display for each screen on alternate frames
if(video_screen_get_frame_number(device->machine->primary_screen) & 1)
// if (1) // gx_syncen & 0x20)
// if(video_screen_get_frame_number(device->machine->primary_screen) & 1)
if (1) // gx_syncen & 0x20)
{
gx_syncen &= ~0x20;
@ -721,9 +724,11 @@ static INTERRUPT_GEN(konamigx_vbinterrupt_type4)
{
gx_syncen &= ~1;
cpu_set_input_line(device, 1, HOLD_LINE);
}
}
dmastart_callback(0);
}
@ -991,12 +996,11 @@ static READ32_HANDLER( type1_roz_r2 )
static READ32_HANDLER( type3_sync_r )
{
if(video_screen_get_frame_number(space->machine->primary_screen) & 1)
return 0xfffffffe | 1;
if(konamigx_current_frame==0)
return -1; // return 0xfffffffe | 1;
else
return 0xfffffffe | 0;
}
return 0;// return 0xfffffffe | 0;
}
static int last_prot_op, last_prot_clk;
/*
@ -1262,8 +1266,8 @@ static ADDRESS_MAP_START( gx_type3_map, ADDRESS_SPACE_PROGRAM, 32 )
//AM_RANGE(0xe20000, 0xe20003) AM_WRITENOP
AM_RANGE(0xe40000, 0xe40003) AM_WRITE(konamigx_type3_psac2_bank_w) AM_BASE(&konamigx_type3_psac2_bank)
AM_RANGE(0xe60000, 0xe60fff) AM_RAM AM_BASE((UINT32**)&K053936_0_linectrl)
AM_RANGE(0xe80000, 0xe83fff) AM_RAM_WRITE(konamigx_555_palette_w) AM_BASE(&paletteram32) // main monitor palette
AM_RANGE(0xea0000, 0xea3fff) AM_RAM_WRITE(konamigx_555_palette2_w) AM_BASE(&gx_subpaletteram32)
AM_RANGE(0xe80000, 0xe83fff) AM_RAM AM_BASE(&paletteram32) // main monitor palette
AM_RANGE(0xea0000, 0xea3fff) AM_RAM AM_BASE(&gx_subpaletteram32)
AM_RANGE(0xec0000, 0xec0003) AM_READ(type3_sync_r)
//AM_RANGE(0xf00000, 0xf07fff) AM_RAM
AM_IMPORT_FROM(gx_base_memmap)
@ -1276,8 +1280,7 @@ static ADDRESS_MAP_START( gx_type4_map, ADDRESS_SPACE_PROGRAM, 32 )
AM_RANGE(0xe20000, 0xe20003) AM_WRITENOP
AM_RANGE(0xe40000, 0xe40003) AM_WRITENOP
AM_RANGE(0xe60000, 0xe60fff) AM_RAM AM_BASE((UINT32**)&K053936_0_linectrl) // 29C & 29G (PSAC2 line control)
AM_RANGE(0xe80000, 0xe87fff) AM_RAM_WRITE(konamigx_palette_w) AM_BASE(&paletteram32) // 11G/13G/15G (main screen palette RAM)
// AM_RANGE(0xea0000, 0xea7fff) AM_RAM_WRITE(konamigx_palette2_w) AM_BASE(&gx_subpaletteram32) // 5G/7G/9G (sub screen palette RAM)
AM_RANGE(0xe80000, 0xe87fff) AM_RAM AM_BASE(&paletteram32) // 11G/13G/15G (main screen palette RAM)
AM_RANGE(0xea0000, 0xea7fff) AM_RAM AM_BASE(&gx_subpaletteram32) // 5G/7G/9G (sub screen palette RAM)
AM_RANGE(0xec0000, 0xec0003) AM_READ(type3_sync_r) // type 4 polls this too
AM_RANGE(0xf00000, 0xf07fff) AM_RAM_WRITE(konamigx_t4_psacmap_w) AM_BASE(&gx_psacram) // PSAC2 tilemap
@ -1570,13 +1573,22 @@ static MACHINE_DRIVER_START( gxtype3 )
MDRV_CPU_PROGRAM_MAP(gx_type3_map)
MDRV_CPU_VBLANK_INT_HACK(konamigx_hbinterrupt, 262)
MDRV_DEFAULT_LAYOUT(layout_dualhsxs)
MDRV_VIDEO_ATTRIBUTES(VIDEO_HAS_SHADOWS | VIDEO_HAS_HIGHLIGHTS | VIDEO_UPDATE_AFTER_VBLANK | VIDEO_ALWAYS_UPDATE)
MDRV_VIDEO_START(konamigx_type3)
MDRV_PALETTE_LENGTH(16384)
MDRV_SCREEN_MODIFY("screen")
MDRV_SCREEN_SIZE(576, 32*8)
// MDRV_SCREEN_VISIBLE_AREA(0, 128*8-1, 0, 32*8-1)
MDRV_SCREEN_VISIBLE_AREA(0, 576-1, 16, 32*8-1-16)
MDRV_SCREEN_ADD("screen2", RASTER)
MDRV_SCREEN_RAW_PARAMS(6000000, 288+16+32+48, 0, 287, 224+16+8+16, 0, 223)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
MDRV_SCREEN_SIZE(576, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0, 576-1, 16, 32*8-1-16)
MDRV_GFXDECODE(type34)
MACHINE_DRIVER_END
@ -1587,12 +1599,20 @@ static MACHINE_DRIVER_START( gxtype4 )
MDRV_CPU_PROGRAM_MAP(gx_type4_map)
MDRV_CPU_VBLANK_INT_HACK(konamigx_hbinterrupt, 262)
MDRV_DEFAULT_LAYOUT(layout_dualhsxs)
MDRV_VIDEO_ATTRIBUTES(VIDEO_HAS_SHADOWS | VIDEO_HAS_HIGHLIGHTS | VIDEO_UPDATE_AFTER_VBLANK | VIDEO_ALWAYS_UPDATE)
MDRV_SCREEN_MODIFY("screen")
MDRV_SCREEN_SIZE(128*8, 32*8)
// MDRV_SCREEN_VISIBLE_AREA(0, 128*8-1, 0, 32*8-1)
// MDRV_SCREEN_VISIBLE_AREA(0, 576-1, 16, 32*8-1-16)
MDRV_SCREEN_VISIBLE_AREA(0, 384-1, 16, 32*8-1-16)
MDRV_SCREEN_ADD("screen2", RASTER)
MDRV_SCREEN_RAW_PARAMS(6000000, 288+16+32+48, 0, 287, 224+16+8+16, 0, 223)
MDRV_SCREEN_FORMAT(BITMAP_FORMAT_RGB32)
MDRV_SCREEN_SIZE(128*8, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0, 384-1, 16, 32*8-1-16)
MDRV_PALETTE_LENGTH(8192)
MDRV_GFXDECODE(type4)
MDRV_VIDEO_START(konamigx_type4)
@ -1601,9 +1621,15 @@ MACHINE_DRIVER_END
static MACHINE_DRIVER_START( gxtype4vsnet )
MDRV_IMPORT_FROM(gxtype4)
MDRV_DEFAULT_LAYOUT(layout_dualhsxs)
MDRV_SCREEN_MODIFY("screen")
MDRV_SCREEN_SIZE(128*8, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0, 576-1, 16, 32*8-1-16)
MDRV_SCREEN_MODIFY("screen2")
MDRV_SCREEN_SIZE(128*8, 32*8)
MDRV_SCREEN_VISIBLE_AREA(0, 576-1, 16, 32*8-1-16)
MACHINE_DRIVER_END
static MACHINE_DRIVER_START( gxtype4sd2 )

View File

@ -33,6 +33,7 @@
static UINT8 *gx_objzbuf, *gx_shdzbuf;
static int layer_colorbase[4];
static INT32 gx_tilebanks[8], gx_oldbanks[8];
static int gx_tilemode, gx_rozenable, psac_colorbase, last_psac_colorbase;
@ -41,6 +42,14 @@ static int gx_rushingheroes_hack;
static tilemap *gx_psac_tilemap, *gx_psac_tilemap2;
extern UINT32 *gx_psacram, *gx_subpaletteram32;
static bitmap_t* type3_roz_temp_bitmap;
static tilemap* gx_psac_tilemap_alt;
static int konamigx_has_dual_screen;
int konamigx_current_frame;
INLINE void set_color_555(running_machine *machine, pen_t color, int rshift, int gshift, int bshift, UINT16 data);
static int konamigx_palformat;
static bitmap_t* dualscreen_left_tempbitmap;
static bitmap_t* dualscreen_right_tempbitmap;
/* On Type-1 the K053936 output is rendered to these temporary bitmaps as raw data
the 'voxel' effect to give the pixels height is a post-process operation on the
@ -1808,12 +1817,13 @@ WRITE32_HANDLER( konamigx_type3_psac2_bank_w )
COMBINE_DATA(&konamigx_type3_psac2_bank[offset]);
konamigx_type3_psac2_actual_bank = (konamigx_type3_psac2_bank[0] & 0x10000000) >> 28;
/* handle this by creating 2 roz tilemaps instead, otherwise performance dies completely on dual screen mode
if (konamigx_type3_psac2_actual_bank!=konamigx_type3_psac2_actual_last_bank)
{
tilemap_mark_all_tiles_dirty (gx_psac_tilemap);
konamigx_type3_psac2_actual_last_bank = konamigx_type3_psac2_actual_bank;
}
*/
}
@ -1826,8 +1836,8 @@ WRITE32_HANDLER( konamigx_type3_psac2_bank_w )
int base_index = tile_index;
if (konamigx_type3_psac2_actual_bank)
base_index+=0x20000/2;
// if (konamigx_type3_psac2_actual_bank)
// base_index+=0x20000/2;
tileno = tmap[base_index*2] | ((tmap[(base_index*2)+1] & 0x0f)<<8);
@ -1840,6 +1850,28 @@ WRITE32_HANDLER( konamigx_type3_psac2_bank_w )
SET_TILE_INFO(0, tileno, colour, flip);
}
static TILE_GET_INFO( get_gx_psac3_alt_tile_info )
{
int tileno, colour, flip;
UINT8 *tmap = memory_region(machine, "gfx4")+0x20000;
int base_index = tile_index;
// if (konamigx_type3_psac2_actual_bank)
// base_index+=0x20000/2;
tileno = tmap[base_index*2] | ((tmap[(base_index*2)+1] & 0x0f)<<8);
colour = (tmap[(base_index*2)+1]&0xc0)>>6;
flip = 0;
if (tmap[(base_index*2)+1] & 0x20) flip |= TILE_FLIPY;
if (tmap[(base_index*2)+1] & 0x10) flip |= TILE_FLIPX;
SET_TILE_INFO(0, tileno, colour, flip);
}
/* PSAC4 */
/* these tilemaps are weird in both format and content, one of them
doesn't really look like it should be displayed? - it's height data */
@ -1975,6 +2007,9 @@ static void _gxcommoninitnosprites(running_machine *machine)
K056832_set_LayerOffset(1, 0, 0);
K056832_set_LayerOffset(2, 2, 0);
K056832_set_LayerOffset(3, 3, 0);
konamigx_has_dual_screen = 0;
konamigx_current_frame = 0;
}
static void _gxcommoninit(running_machine *machine)
@ -2080,9 +2115,14 @@ VIDEO_START(konamigx_type3)
K056832_vh_start(machine, "gfx1", K056832_BPP_6, 0, NULL, konamigx_type2_tile_callback, 1);
K055673_vh_start(machine, "gfx2", K055673_LAYOUT_GX6, -132, -23, konamigx_type2_sprite_callback);
dualscreen_left_tempbitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_RGB32);
dualscreen_right_tempbitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_RGB32);
_gxcommoninitnosprites(machine);
gx_psac_tilemap = tilemap_create(machine, get_gx_psac3_tile_info, tilemap_scan_cols, 16, 16, 256, 256);
gx_psac_tilemap_alt = tilemap_create(machine, get_gx_psac3_alt_tile_info, tilemap_scan_cols, 16, 16, 256, 256);
gx_rozenable = 0;
gx_specialrozenable = 2;
@ -2101,13 +2141,22 @@ VIDEO_START(konamigx_type3)
K056832_set_LayerOffset(1, -48, 0);
K056832_set_LayerOffset(2, -48, 0);
K056832_set_LayerOffset(3, -48, 0);
konamigx_has_dual_screen = 1;
konamigx_palformat = 1;
}
VIDEO_START(konamigx_type4)
{
int width = video_screen_get_width(machine->primary_screen);
int height = video_screen_get_height(machine->primary_screen);
K056832_vh_start(machine, "gfx1", K056832_BPP_8, 0, NULL, konamigx_type2_tile_callback, 0);
K055673_vh_start(machine, "gfx2", K055673_LAYOUT_GX6, -79, -24, konamigx_type2_sprite_callback); // -23 looks better in intro
dualscreen_left_tempbitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_RGB32);
dualscreen_right_tempbitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_RGB32);
_gxcommoninitnosprites(machine);
gx_psac_tilemap = tilemap_create(machine, get_gx_psac_tile_info, tilemap_scan_cols, 16, 16, 128, 128);
@ -2123,13 +2172,22 @@ VIDEO_START(konamigx_type4)
K053936GP_set_offset(0, -36, 1);
gx_rushingheroes_hack = 1;
konamigx_has_dual_screen = 1;
konamigx_palformat = 0;
}
VIDEO_START(konamigx_type4_sd2)
{
int width = video_screen_get_width(machine->primary_screen);
int height = video_screen_get_height(machine->primary_screen);
K056832_vh_start(machine, "gfx1", K056832_BPP_8, 0, NULL, konamigx_type2_tile_callback, 0);
K055673_vh_start(machine, "gfx2", K055673_LAYOUT_GX6, -81, -23, konamigx_type2_sprite_callback);
dualscreen_left_tempbitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_RGB32);
dualscreen_right_tempbitmap = auto_bitmap_alloc(machine, width, height, BITMAP_FORMAT_RGB32);
_gxcommoninitnosprites(machine);
gx_psac_tilemap = tilemap_create(machine, get_gx_psac_tile_info, tilemap_scan_cols, 16, 16, 128, 128);
@ -2147,6 +2205,9 @@ VIDEO_START(konamigx_type4_sd2)
K053936GP_set_offset(0, -36, -1);
gx_rushingheroes_hack = 1;
konamigx_has_dual_screen = 1;
konamigx_palformat = 0;
}
@ -2252,6 +2313,98 @@ VIDEO_START(racinfrc)
VIDEO_UPDATE(konamigx)
{
int i, newbank, newbase, dirty, unchained;
bitmap_t* realbitmap = bitmap;
if (konamigx_has_dual_screen)
{
const device_config *left_screen = devtag_get_device(screen->machine, "screen");
const device_config *right_screen = devtag_get_device(screen->machine, "screen2");
/* the video gets demuxed by a board which plugs into the jamma connector */
if (screen==left_screen)
{
konamigx_current_frame^=1;
if (konamigx_current_frame==1)
{
int offset=0;
if (konamigx_palformat==1)
{
for (offset=0;offset<0x4000/4;offset++)
{
UINT32 coldat = paletteram32[offset];
set_color_555(screen->machine, offset*2, 0, 5, 10,coldat >> 16);
set_color_555(screen->machine, offset*2+1, 0, 5, 10,coldat & 0xffff);
}
}
else
{
for (offset=0;offset<0x8000/4;offset++)
{
int r,g,b;
r = (paletteram32[offset] >>16) & 0xff;
g = (paletteram32[offset] >> 8) & 0xff;
b = (paletteram32[offset] >> 0) & 0xff;
palette_set_color(screen->machine,offset,MAKE_RGB(r,g,b));
}
}
bitmap = dualscreen_left_tempbitmap;
// draw
}
else
{
copybitmap(bitmap, dualscreen_left_tempbitmap, 0, 0, 0, 0, cliprect);
return 0;
}
}
else if (screen==right_screen)
{
if (konamigx_current_frame==1)
{
copybitmap(bitmap, dualscreen_right_tempbitmap, 0, 0, 0, 0, cliprect);
return 0;
}
else
{
int offset=0;
if (konamigx_palformat==1)
{
for (offset=0;offset<0x4000/4;offset++)
{
UINT32 coldat = gx_subpaletteram32[offset];
set_color_555(screen->machine, offset*2, 0, 5, 10,coldat >> 16);
set_color_555(screen->machine, offset*2+1, 0, 5, 10,coldat & 0xffff);
}
}
else
{
for (offset=0;offset<0x8000/4;offset++)
{
int r,g,b;
r = (gx_subpaletteram32[offset] >>16) & 0xff;
g = (gx_subpaletteram32[offset] >> 8) & 0xff;
b = (gx_subpaletteram32[offset] >> 0) & 0xff;
palette_set_color(screen->machine,offset,MAKE_RGB(r,g,b));
}
}
bitmap = dualscreen_right_tempbitmap;
// draw
}
}
}
/* if any banks are different from last render, we need to flush the planes */
for (dirty = 0, i = 0; i < 8; i++)
@ -2325,8 +2478,11 @@ VIDEO_UPDATE(konamigx)
temprect.min_y = cliprect->min_y;
temprect.max_y = cliprect->max_y;
K053936_0_zoom_draw(type3_roz_temp_bitmap, &temprect,gx_psac_tilemap, 0,0,0); // soccerss playfield
konamigx_mixer(screen->machine, bitmap, cliprect, 0, 0, 0, 0, 0, type3_roz_temp_bitmap, gx_rushingheroes_hack);
if (konamigx_type3_psac2_actual_bank == 1) K053936_0_zoom_draw(type3_roz_temp_bitmap, &temprect,gx_psac_tilemap_alt, 0,0,0); // soccerss playfield
else K053936_0_zoom_draw(type3_roz_temp_bitmap, &temprect,gx_psac_tilemap, 0,0,0); // soccerss playfield
konamigx_mixer(screen->machine, bitmap, cliprect, 0, 0, 0, 0, 0, type3_roz_temp_bitmap, gx_rushingheroes_hack);
}
else
{
@ -2370,6 +2526,21 @@ VIDEO_UPDATE(konamigx)
}
if (konamigx_has_dual_screen)
{
const device_config *left_screen = devtag_get_device(screen->machine, "screen");
const device_config *right_screen = devtag_get_device(screen->machine, "screen2");
if (screen==left_screen)
{
copybitmap(realbitmap, dualscreen_left_tempbitmap, 0, 0, 0, 0, cliprect);
}
else if (screen==right_screen)
{
copybitmap(realbitmap, dualscreen_right_tempbitmap, 0, 0, 0, 0, cliprect);
}
}
return 0;
}
@ -2432,6 +2603,7 @@ WRITE32_HANDLER( konamigx_555_palette2_w )
set_color_555(space->machine, offset*2+1, 0, 5, 10,coldat & 0xffff);
}
WRITE32_HANDLER( konamigx_tilebank_w )
{
if (ACCESSING_BITS_24_31)