diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 52d2c93..00280fa 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -60,6 +60,8 @@ void linearFree(void* mem); RETRO_HW_RENDER_INTEFACE_GSKIT_PS2 *ps2 = NULL; #endif +extern void FCEU_ZapperSetTolerance(int t); + static retro_video_refresh_t video_cb = NULL; static retro_input_poll_t poll_cb = NULL; static retro_input_state_t input_cb = NULL; @@ -1300,6 +1302,16 @@ static void check_variables(bool startup) else zappermode = RetroLightgun; /*default setting*/ } + var.key = "fceumm_zapper_tolerance"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + FCEU_ZapperSetTolerance(atoi(var.value)); + } + + var.key = "fceumm_region"; + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + var.key = "fceumm_show_crosshair"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) diff --git a/src/drivers/libretro/libretro_core_options.h b/src/drivers/libretro/libretro_core_options.h index 35ce4c9..16660f0 100644 --- a/src/drivers/libretro/libretro_core_options.h +++ b/src/drivers/libretro/libretro_core_options.h @@ -232,6 +232,48 @@ struct retro_core_option_definition option_defs_common[] = { }, "enabled", }, + { + "fceumm_zapper_tolerance", + "Zapper Tolerance", + "Sets how many pixels from target area is on target.", + { + { "0", NULL }, + { "1", NULL }, + { "2", NULL }, + { "3", NULL }, + { "4", NULL }, + { "5", NULL }, + { "6", NULL }, + { "7", NULL }, + { "8", NULL }, + { "9", NULL }, + { "10", NULL }, + { "11", NULL }, + { "12", NULL }, + { "13", NULL }, + { "14", NULL }, + { "15", NULL }, + { "16", NULL }, + { "17", NULL }, + { "18", NULL }, + { "19", NULL }, + { "20", NULL }, + { "21", NULL }, + { "22", NULL }, + { "23", NULL }, + { "24", NULL }, + { "25", NULL }, + { "26", NULL }, + { "27", NULL }, + { "28", NULL }, + { "29", NULL }, + { "30", NULL }, + { "31", NULL }, + { "32", NULL }, + { NULL, NULL }, + }, + "6", + }, { "fceumm_sndquality", "Sound Quality", diff --git a/src/input/zapper.c b/src/input/zapper.c index 07c6b4b..7656cd5 100644 --- a/src/input/zapper.c +++ b/src/input/zapper.c @@ -23,6 +23,13 @@ #include "share.h" +#define ROUNDED_TARGET +#ifdef ROUNDED_TARGET +#define MAX_TOLERANCE 32 +static uint32 targetExpansion[MAX_TOLERANCE+1]; +#endif +static int tolerance; + typedef struct { uint32 mzx, mzy, mzb; int zap_readbit; @@ -49,11 +56,19 @@ static void FP_FASTAPASS(3) ZapperFrapper(int w, uint8 * bg, uint8 * spr, uint32 if (xe > 256) xe = 256; - if (scanline >= (zy - 4) && scanline <= (zy + 4)) { + if (scanline >= (zy - tolerance) && scanline <= (zy + tolerance)) { +#ifdef ROUNDED_TARGET + int dy = scanline - zy; + if (dy < 0) + dy = -dy; + int spread = targetExpansion[dy]; +#else + int spread = tolerance; +#endif while (xs < xe) { uint8 a1, a2; uint32 sum; - if (xs <= (zx + 4) && xs >= (zx - 4)) { + if (xs <= (zx + spread) && xs >= (zx - spread)) { a1 = bg[xs]; if (spr) { a2 = spr[xs]; @@ -140,6 +155,24 @@ static void FP_FASTAPASS(3) UpdateZapper(int w, void *data, int arg) { static INPUTC ZAPC = { ReadZapper, 0, 0, UpdateZapper, ZapperFrapper, DrawZapper }; static INPUTC ZAPVSC = { ReadZapperVS, 0, StrobeZapperVS, UpdateZapper, ZapperFrapper, DrawZapper }; +#ifdef ROUNDED_TARGET +static uint32 InefficientSqrt(uint32 z) { + uint32 i; + for (i = 0 ; i * i <= z ; i++) ; + return i-1; +} +#endif + +void FCEU_ZapperSetTolerance(int t) { +#ifdef ROUNDED_TARGET + tolerance = t <= MAX_TOLERANCE ? t : MAX_TOLERANCE; + for (uint32 y = 0 ; y <= tolerance ; y++) + targetExpansion[y] = InefficientSqrt(tolerance*tolerance-y*y); +#else + tolerance = t; +#endif +} + INPUTC *FCEU_InitZapper(int w) { memset(&ZD[w], 0, sizeof(ZAPPER)); if (GameInfo->type == GIT_VSUNI) @@ -148,4 +181,3 @@ INPUTC *FCEU_InitZapper(int w) { return(&ZAPC); } -