From 7026a8445eed8b2cfd716c7e7ea120316f32ff0b Mon Sep 17 00:00:00 2001 From: EkeEke Date: Fri, 16 Nov 2012 01:46:38 +0100 Subject: [PATCH 1/2] * added automatic detection for CD games with Justifier/Menacer support * improved Justifier/Menacer emulation * [Wii only] fixed screen rendering when borders are disabled --- source/cart_hw/md_cart.c | 102 +--------------------- source/gx/gx_video.c | 30 ++++--- source/input_hw/input.h | 4 +- source/input_hw/lightgun.c | 35 +++++--- source/loadrom.c | 172 ++++++++++++++++++++++++++++++++++++- 5 files changed, 216 insertions(+), 127 deletions(-) diff --git a/source/cart_hw/md_cart.c b/source/cart_hw/md_cart.c index eb9897d..e57e0a1 100644 --- a/source/cart_hw/md_cart.c +++ b/source/cart_hw/md_cart.c @@ -350,108 +350,10 @@ void md_cart_init(void) m68k.memory_map[0x3a].read16 = svp_read_cell_2; } - /********************************************** - SPECIFIC PERIPHERAL SUPPORT - ***********************************************/ - - /* default GUN settings */ - input.x_offset = 0x00; - input.y_offset = 0x00; - - /* SEGA Menacer */ - if (strstr(rominfo.international,"MENACER") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) - { - old_system[0] = input.system[0]; - } - if (old_system[1] == -1) - { - old_system[1] = input.system[1]; - } - - input.system[0] = SYSTEM_MD_GAMEPAD; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x52; - input.y_offset = 0x00; - } - else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) - { - old_system[0] = input.system[0]; - } - if (old_system[1] == -1) - { - old_system[1] = input.system[1]; - } - - input.system[0] = SYSTEM_MD_GAMEPAD; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x84; - input.y_offset = 0x08; - } - else if (strstr(rominfo.international,"BODY COUNT") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) - { - old_system[0] = input.system[0]; - } - if (old_system[1] == -1) - { - old_system[1] = input.system[1]; - } - - input.system[0] = SYSTEM_MOUSE; - input.system[1] = SYSTEM_MENACER; - input.x_offset = 0x44; - input.y_offset = 0x18; - } - - /* KONAMI Justifiers */ - else if (strstr(rominfo.international,"LETHAL ENFORCERSII") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) - { - old_system[0] = input.system[0]; - } - if (old_system[1] == -1) - { - old_system[1] = input.system[1]; - } - - input.system[0] = SYSTEM_MD_GAMEPAD; - input.system[1] = SYSTEM_JUSTIFIER; - input.x_offset = 0x18; - input.y_offset = 0x00; - } - else if (strstr(rominfo.international,"LETHAL ENFORCERS") != NULL) - { - /* save current setting */ - if (old_system[0] == -1) - { - old_system[0] = input.system[0]; - } - if (old_system[1] == -1) - { - old_system[1] = input.system[1]; - } - - input.system[0] = SYSTEM_MD_GAMEPAD; - input.system[1] = SYSTEM_JUSTIFIER; - input.x_offset = 0x00; - input.y_offset = 0x00; - } - - cart.special = 0; - /********************************************** J-CART ***********************************************/ + cart.special = 0; if (((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x168b)) || /* Super Skidmarks, Micro Machines Military */ ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0x165e)) || /* Pete Sampras Tennis (1991), Micro Machines 96 */ ((strstr(rominfo.product,"00000000") != NULL) && (rominfo.checksum == 0xcee0)) || /* Micro Machines Military (bad) */ @@ -465,7 +367,7 @@ void md_cart_init(void) { cart.special |= HW_J_CART; - /* set default port 1 setting */ + /* force port 1 setting */ if (input.system[1] != SYSTEM_WAYPLAY) { old_system[1] = input.system[1]; diff --git a/source/gx/gx_video.c b/source/gx/gx_video.c index 3e8ee41..211bf8d 100644 --- a/source/gx/gx_video.c +++ b/source/gx/gx_video.c @@ -659,6 +659,23 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y) { if (texture->data) { + /* EFB scale & shift */ + int xwidth = square[3] - square[9]; + int ywidth = square[4] - square[10]; + int xshift = (square[3] + square[9]) / 2; + int yshift = (square[4] + square[10]) / 2; + + /* adjust texture dimensions to XFB->VI scaling */ + int w = (texture->width * rmode->fbWidth) / (rmode->viWidth); + int h = (texture->height * rmode->efbHeight) / (rmode->viHeight); + + /* adjust texture coordinates to EFB */ + x = (((x + bitmap.viewport.x) * xwidth) / (bitmap.viewport.w + 2*bitmap.viewport.x)) - w/2 - (xwidth/2) + xshift; + y = (((y + bitmap.viewport.y) * ywidth) / (bitmap.viewport.h + 2*bitmap.viewport.y)) - h/2 - (ywidth/2) + yshift; + + /* reset GX rendering */ + gxResetRendering(1); + /* load texture object */ GXTexObj texObj; GX_InitTexObj(&texObj, texture->data, texture->width, texture->height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); @@ -666,19 +683,6 @@ static void gxDrawCrosshair(gx_texture *texture, int x, int y) GX_LoadTexObj(&texObj, GX_TEXMAP0); GX_InvalidateTexAll(); - /* reset GX rendering */ - gxResetRendering(1); - - /* adjust texture dimensions to XFB->VI scaling */ - int w = (texture->width * rmode->fbWidth) / (rmode->viWidth); - int h = (texture->height * rmode->efbHeight) / (rmode->viHeight); - - /* adjust texture coordinates to EFB */ - int fb_w = square[3] - square[9]; - int fb_h = square[4] - square[10]; - x = (((x + bitmap.viewport.x) * fb_w) / (bitmap.viewport.w + 2*bitmap.viewport.x)) - w/2 - (fb_w/2); - y = (((y + bitmap.viewport.y) * fb_h) / (bitmap.viewport.h + 2*bitmap.viewport.y)) - h/2 - (fb_h/2); - /* Draw textured quad */ GX_Begin(GX_QUADS, GX_VTXFMT0, 4); GX_Position2s16(x,y+h); diff --git a/source/input_hw/input.h b/source/input_hw/input.h index 56e07c3..9798154 100644 --- a/source/input_hw/input.h +++ b/source/input_hw/input.h @@ -133,8 +133,8 @@ typedef struct uint8 dev[MAX_DEVICES]; /* can be one of the DEVICE_* values */ uint16 pad[MAX_DEVICES]; /* digital inputs (any of INPUT_* values) */ int16 analog[MAX_DEVICES][2]; /* analog inputs (x/y) */ - uint8 x_offset; /* gun horizontal offset */ - uint8 y_offset; /* gun vertical offset */ + int x_offset; /* gun horizontal offset */ + int y_offset; /* gun vertical offset */ } t_input; /* Global variables */ diff --git a/source/input_hw/lightgun.c b/source/input_hw/lightgun.c index 9c2e894..7f6b5d4 100644 --- a/source/input_hw/lightgun.c +++ b/source/input_hw/lightgun.c @@ -92,8 +92,6 @@ static struct void lightgun_reset(int port) { - input.analog[port][0] = bitmap.viewport.w >> 1; - input.analog[port][1] = bitmap.viewport.h >> 1; lightgun.State = 0x40; lightgun.Port = 4; } @@ -103,32 +101,47 @@ void lightgun_refresh(int port) /* Check that lightgun is enabled */ if (port == lightgun.Port) { + /* screen Y position */ + int y = (input.analog[port][1] + lines_per_frame + input.y_offset) % lines_per_frame; + /* check if line falls within current gun Y position */ - if ((input.analog[port][1] == v_counter + input.y_offset)) + if (v_counter == y) { /* HL enabled ? */ if (io_reg[5] & 0x80) { + /* screen X position */ + int x = input.analog[port][0]; + + /* Sega Menacer specific */ + if (input.system[1] == SYSTEM_MENACER) + { + /* raw position is scaled up by games */ + if (system_hw == SYSTEM_MCD) + { + x = (x * 304) / 320; + } + else + { + x = (x * 289) / 320; + } + } + /* External Interrupt ? */ if (reg[11] & 0x08) { m68k_update_irq(2); } - /* HV Counter Latch: - 1) some games does not enable HVC latch but instead use bigger X offset - --> we force the HV counter value read by the gun routine - 2) for games using H40 mode, the gun routine scales up the Hcounter value - --> H-Counter range is approx. 290 dot clocks - */ + /* force HV Counter Latch (some games does not lock HV Counter but instead use larger offset value) */ hvc_latch = 0x10000 | (v_counter << 8); if (reg[12] & 1) { - hvc_latch |= hc_320[((input.analog[port][0] * 290) / (2 * 320) + input.x_offset) % 210]; + hvc_latch |= hc_320[((x / 2) + input.x_offset) % 210]; } else { - hvc_latch |= hc_256[(input.analog[port][0] / 2 + input.x_offset) % 171]; + hvc_latch |= hc_256[((x / 2) + input.x_offset) % 171]; } } } diff --git a/source/loadrom.c b/source/loadrom.c index 95a2f86..e1d942c 100644 --- a/source/loadrom.c +++ b/source/loadrom.c @@ -74,7 +74,7 @@ #define PMOUSE 8192 #define MAXCOMPANY 64 -#define MAXPERIPHERALS 14 +#define MAXPERIPHERALS 15 typedef struct { @@ -190,6 +190,7 @@ static const PERIPHERALINFO peripheralinfo[MAXPERIPHERALS] = {"V", "Paddle"}, {"C", "CD-ROM"}, {"M", "Mega Mouse"}, + {"G", "Menacer"}, }; /*************************************************************************** @@ -771,6 +772,175 @@ int load_rom(char *filename) input.system[1] = old_system[1]; } + /* default gun settings */ + input.x_offset = (input.system[1] == SYSTEM_MENACER) ? 64 : 0; + input.y_offset = 0; + + /* autodetect gun support */ + if (strstr(rominfo.international,"MENACER") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 82; + input.y_offset = 0; + } + else if (strstr(rominfo.international,"T2 ; THE ARCADE GAME") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 133; + input.y_offset = -8; + } + else if (strstr(rominfo.international,"BODY COUNT") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MOUSE+MENACER configuration */ + input.system[0] = SYSTEM_MOUSE; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 68; + input.y_offset = -24; + } + else if (strstr(rominfo.international,"CORPSE KILLER") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 64; + input.y_offset = -8; + } + else if (strstr(rominfo.international,"CRIME PATROL") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 61; + input.y_offset = 0; + } + else if (strstr(rominfo.international,"MAD DOG II THE LOST GOLD") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 70; + input.y_offset = 18; + } + else if (strstr(rominfo.international,"MAD DOG MCCREE") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 49; + input.y_offset = 0; + } + else if (strstr(rominfo.international,"WHO SHOT JOHNNY ROCK?") != NULL) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force MENACER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_MENACER; + input.x_offset = 60; + input.y_offset = 30; + } + else if ((strstr(rominfo.international,"LETHAL ENFORCERS") != NULL) || + (strstr(rominfo.international,"SNATCHER") != NULL)) + { + /* save current setting */ + if (old_system[0] == -1) + { + old_system[0] = input.system[0]; + } + if (old_system[1] == -1) + { + old_system[1] = input.system[1]; + } + + /* force JUSTIFIER configuration */ + input.system[0] = SYSTEM_MD_GAMEPAD; + input.system[1] = SYSTEM_JUSTIFIER; + input.x_offset = (strstr(rominfo.international,"GUN FIGHTERS") != NULL) ? 24 : 0; + input.y_offset = 0; + } + return(1); } From 4d142b2e9cfe06cb53eafd086bcf685ec67cb5ef Mon Sep 17 00:00:00 2001 From: EkeEke Date: Fri, 16 Nov 2012 01:53:02 +0100 Subject: [PATCH 2/2] better keep gun initial position centered for when using analog sticks --- source/input_hw/lightgun.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/input_hw/lightgun.c b/source/input_hw/lightgun.c index 7f6b5d4..294c460 100644 --- a/source/input_hw/lightgun.c +++ b/source/input_hw/lightgun.c @@ -92,6 +92,8 @@ static struct void lightgun_reset(int port) { + input.analog[port][0] = bitmap.viewport.w / 2; + input.analog[port][1] = bitmap.viewport.h / 2; lightgun.State = 0x40; lightgun.Port = 4; }