From 5263e0a22abee70d0ecd11d0fc0d60bccc8758bd Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Sat, 2 May 2020 15:33:57 +0800 Subject: [PATCH 1/4] ines.c: Simplify rom info logs and cleanup --- src/ines.c | 82 ++++++++++++++++++++++-------------------------------- 1 file changed, 33 insertions(+), 49 deletions(-) diff --git a/src/ines.c b/src/ines.c index 18e8503..6d811a0 100644 --- a/src/ines.c +++ b/src/ines.c @@ -415,7 +415,7 @@ typedef struct { #define INES_BOARD_BEGIN() static BMAPPINGLocal bmap[] = { #define INES_BOARD_END() { (uint8_t*)"", 0, NULL} }; -#define INES_BOARD(a, b, c) { a, b, c }, +#define INES_BOARD(a, b, c) { (uint8_t*)a, b, c }, INES_BOARD_BEGIN() INES_BOARD( "NROM", 0, NROM_Init ) @@ -841,6 +841,7 @@ static void rom_load_ines2(void) { } int iNESLoad(const char *name, FCEUFILE *fp) { + const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" }; struct md5_context md5; char* mappername = NULL; uint64 filesize = FCEU_fgetsize(fp); @@ -946,38 +947,49 @@ int iNESLoad(const char *name, FCEUFILE *fp) { } } + if (iNESCart.iNES2 == 0) { + if (strstr(name, "(E)") || strstr(name, "(e)") || + strstr(name, "(Europe)") || strstr(name, "(PAL)") || + strstr(name, "(F)") || strstr(name, "(f)") || + strstr(name, "(G)") || strstr(name, "(g)") || + strstr(name, "(I)") || strstr(name, "(i)") || + strstr(name, "(S)") || strstr(name, "(s)") || + strstr(name, "(France)") || strstr(name, "(Germany)") || + strstr(name, "(Italy)") || strstr(name, "(Spain)") || + strstr(name, "(Sweden)") || strstr(name, "(Sw)") || + strstr(name, "(Australia)") || strstr(name, "(A)") || + strstr(name, "(a)")) { + iNESCart.region = 1; + } + } + FCEU_printf(" PRG-ROM CRC32: 0x%08X\n", iNESCart.PRGCRC32); FCEU_printf(" PRG+CHR CRC32: 0x%08X\n", iNESCart.CRC32); FCEU_printf(" PRG+CHR MD5: 0x%s\n", md5_asciistr(iNESCart.MD5)); FCEU_printf(" PRG-ROM: %3d x 16KiB\n", ROM_size); FCEU_printf(" CHR-ROM: %3d x 8KiB\n", VROM_size); + FCEU_printf(" Mapper #: %3d\n", iNESCart.mapper); + FCEU_printf(" Mapper name: %s\n", mappername); + FCEU_printf(" Mirroring: %s\n", iNESCart.mirror == 2 ? "None (Four-screen)" : iNESCart.mirror ? "Vertical" : "Horizontal"); + FCEU_printf(" Battery: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); + FCEU_printf(" System: %s\n", tv_region[iNESCart.region]); + FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); if (iNESCart.iNES2) { - const char *tv_region[] = { "NTSC", "PAL", "Multi-region", "Dendy" }; unsigned PRGRAM = iNESCart.PRGRamSize + iNESCart.PRGRamSaveSize; unsigned CHRRAM = iNESCart.CHRRamSize + iNESCart.CHRRamSaveSize; FCEU_printf(" NES 2.0 extended iNES.\n"); - FCEU_printf(" Mapper #: %3d\n", iNESCart.mapper); FCEU_printf(" Sub Mapper #: %3d\n", iNESCart.submapper); - FCEU_printf(" Mapper name: %s\n", mappername); if (PRGRAM || CHRRAM) { - FCEU_printf(" PRG RAM: %d KB\n", PRGRAM / 1024); - FCEU_printf(" CHR RAM: %d KB\n", CHRRAM / 1024); if (head.ROM_type & 0x02) { - FCEU_printf(" PRG RAM backed by battery: %d KiB\n", iNESCart.PRGRamSaveSize / 1024); - FCEU_printf(" CHR RAM backed by battery: %d KiB\n", iNESCart.CHRRamSaveSize / 1024); + FCEU_printf(" PRG RAM: %d KB (%d KB battery-backed)\n", PRGRAM / 1024, iNESCart.PRGRamSaveSize / 1024); + FCEU_printf(" CHR RAM: %d KB (%d KB battery-backed)\n", CHRRAM / 1024, iNESCart.CHRRamSaveSize / 1024); + } else { + FCEU_printf(" PRG RAM: %d KB\n", PRGRAM / 1024); + FCEU_printf(" CHR RAM: %d KB\n", CHRRAM / 1024); } - } - FCEU_printf(" Mirroring: %s\n", iNESCart.mirror == 2 ? "None (Four-screen)" : iNESCart.mirror ? "Vertical" : "Horizontal"); - FCEU_printf(" System: %s\n", tv_region[iNESCart.region]); - FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); - } else { - FCEU_printf(" Mapper #: %3d\n", iNESCart.mapper); - FCEU_printf(" Mapper name: %s\n", mappername); - FCEU_printf(" Mirroring: %s\n", iNESCart.mirror == 2 ? "None (Four-screen)" : iNESCart.mirror ? "Vertical" : "Horizontal"); - FCEU_printf(" Battery-backed: %s\n", (head.ROM_type & 2) ? "Yes" : "No"); - FCEU_printf(" Trained: %s\n", (head.ROM_type & 4) ? "Yes" : "No"); + } } ResetCartMapping(); @@ -1035,40 +1047,12 @@ int iNESLoad(const char *name, FCEUFILE *fp) { GameInterface = iNESGI; - /* if not ines2 header and no region override was set, then use filename keywords to set cpu/ppu timing */ - if (iNESCart.iNES2 == 0 && iNESCart.region == 0) { - if (strstr(name, "(E)") || strstr(name, "(e)") || - strstr(name, "(Europe)") || strstr(name, "(PAL)") || - strstr(name, "(F)") || strstr(name, "(f)") || - strstr(name, "(G)") || strstr(name, "(g)") || - strstr(name, "(I)") || strstr(name, "(i)") || - strstr(name, "(S)") || strstr(name, "(s)") || - strstr(name, "(France)") || strstr(name, "(Germany)") || - strstr(name, "(Italy)") || strstr(name, "(Spain)") || - strstr(name, "(Sweden)") || strstr(name, "(Sw)") || - strstr(name, "(Australia)") || strstr(name, "(A)") || - strstr(name, "(a)")) { - iNESCart.region = 1; - } - } - - switch (iNESCart.region) { /* 0: RP2C02 ("NTSC NES") * 1: RP2C07 ("Licensed PAL NES") * 2: Multiple-region - * 3: UMC 6527P ("Dendy") - */ - case 1: - FCEUI_SetVidSystem(1); - break; - case 3: - dendy = 1; - /* fallthrough */ - case 0: - case 2: - FCEUI_SetVidSystem(0); - break; - } + * 3: UMC 6527P ("Dendy") */ + if (iNESCart.region == 3) dendy = 1; + FCEUI_SetVidSystem((iNESCart.region == 1) ? 1 : 0); return 1; } From 122cc30a96617071377fe4248715734f5c06eba1 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 5 May 2020 09:07:55 +0800 Subject: [PATCH 2/4] Ntsc: Remove height doubling/scanline effect - We just use shaders for scanline if needed. ntsc + height doubling causes performance hit for some slow devices. Any decent platform should be able to handle scanline effect shaders at least. --- src/drivers/libretro/libretro.c | 134 +++++-------------- src/drivers/libretro/libretro_core_options.h | 13 -- 2 files changed, 36 insertions(+), 111 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index b818990..63c27e3 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -31,13 +31,6 @@ #include "libretro-common/include/streams/memory_stream.h" #include "libretro_dipswitch.h" -#ifdef HAVE_NTSC_FILTER -#define NTSC_SCANLINES /* enables scanline effect and doubles height(required) */ -#if defined(VITA) /* do no disable double-height for these devices */ -#undef NTSC_SCANLINES -#endif -#endif - #include "libretro_core_options.h" #define MAX_PLAYERS 4 /* max supported players */ @@ -595,7 +588,6 @@ struct st_palettes palettes[] = { #define NTSC_WIDTH 602 static unsigned use_ntsc = 0; -static unsigned use_ntsc_scanlines = 0; static unsigned burst_phase; static nes_ntsc_t nes_ntsc; static nes_ntsc_setup_t ntsc_setup; @@ -926,28 +918,17 @@ void retro_get_system_info(struct retro_system_info *info) void retro_get_system_av_info(struct retro_system_av_info *info) { - unsigned width, height, maxwidth, maxheight; #ifdef PSP - width = NES_WIDTH - (use_overscan ? 16 : 0); - height = NES_HEIGHT - (use_overscan ? 16 : 0); + unsigned width = NES_WIDTH - (use_overscan ? 16 : 0); + unsigned height = NES_HEIGHT - (use_overscan ? 16 : 0); #else - width = NES_WIDTH - (overscan_h ? 16 : 0); - height = NES_HEIGHT - (overscan_v ? 16 : 0); -#endif -#ifdef HAVE_NTSC_FILTER - maxwidth = NTSC_WIDTH; - maxheight = NES_HEIGHT; -#ifdef NTSC_SCANLINES - maxheight = NES_HEIGHT * 2; -#endif -#else - maxwidth = NES_WIDTH; - maxheight = NES_HEIGHT; + unsigned width = NES_WIDTH - (overscan_h ? 16 : 0); + unsigned height = NES_HEIGHT - (overscan_v ? 16 : 0); #endif info->geometry.base_width = width; info->geometry.base_height = height; - info->geometry.max_width = maxwidth; - info->geometry.max_height = maxheight; + info->geometry.max_width = (use_ntsc ? NTSC_WIDTH : NES_WIDTH); + info->geometry.max_height = NES_HEIGHT; info->geometry.aspect_ratio = (float)(use_par ? NES_8_7_PAR : NES_4_3); info->timing.sample_rate = (float)sndsamplerate; if (FSettings.PAL || dendy) @@ -1126,8 +1107,7 @@ static void set_apu_channels(int chan) static void check_variables(bool startup) { struct retro_variable var = {0}; - struct retro_system_av_info av_info; - bool geometry_update = false; + int audio_video_updated = 0; bool palette_updated = false; char key[256]; int i, enable_apu; @@ -1161,21 +1141,8 @@ static void check_variables(bool startup) else if (strcmp(var.value, "monochrome") == 0) use_ntsc = NTSC_MONOCHROME; if (use_ntsc != orig_value) - palette_updated = true; + audio_video_updated = 2; } - -#ifdef NTSC_SCANLINES - var.key = "fceumm_ntsc_scanlines"; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - unsigned orig_value = use_ntsc_scanlines; - if (strcmp(var.value, "enabled") == 0) - use_ntsc_scanlines = 1; - else - use_ntsc_scanlines = 0; - } -#endif /* NTSC_SCANLINES */ #endif /* HAVE_NTSC_FILTER */ var.key = "fceumm_palette"; @@ -1224,12 +1191,12 @@ static void check_variables(bool startup) current_palette = 15; if (current_palette != orig_value) - palette_updated = true; + { + audio_video_updated = 1; + ResetPalette(); + } } - if (palette_updated) - ResetPalette(); - var.key = "fceumm_up_down_allowed"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -1328,7 +1295,7 @@ static void check_variables(bool startup) if (newval != overscan_h) { overscan_h = newval; - geometry_update = true; + audio_video_updated = 1; } } @@ -1340,10 +1307,21 @@ static void check_variables(bool startup) if (newval != overscan_v) { overscan_v = newval; - geometry_update = true; + audio_video_updated = 1; } } #endif + var.key = "fceumm_aspect"; + + if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) + { + bool newval = (!strcmp(var.value, "8:7 PAR")); + if (newval != use_par) + { + use_par = newval; + audio_video_updated = 1; + } + } var.key = "fceumm_turbo_enable"; @@ -1392,18 +1370,6 @@ static void check_variables(bool startup) FCEUD_RegionOverride(opt_region); } - var.key = "fceumm_aspect"; - - if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - bool newval = (!strcmp(var.value, "8:7 PAR")); - if (newval != use_par) - { - use_par = newval; - geometry_update = true; - } - } - var.key = "fceumm_sndquality"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -1428,10 +1394,14 @@ static void check_variables(bool startup) FCEUD_SoundToggle(); } - if (geometry_update) + if (audio_video_updated && !startup) { + struct retro_system_av_info av_info; retro_get_system_av_info(&av_info); - environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info); + if (audio_video_updated == 2) + environ_cb(RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO, &av_info); + else + environ_cb(RETRO_ENVIRONMENT_SET_GEOMETRY, &av_info); } var.key = "fceumm_swapduty"; @@ -1867,7 +1837,7 @@ static void retro_run_blit(uint8_t *gfx) if (ntsc_setup.merge_fields) burst_phase = 0; - nes_ntsc_blit(&nes_ntsc, (NES_NTSC_IN_T *)gfx, (NES_NTSC_IN_T *)XDBuf, + nes_ntsc_blit(&nes_ntsc, (NES_NTSC_IN_T const*)gfx, (NES_NTSC_IN_T *)XDBuf, NES_WIDTH, burst_phase, NES_WIDTH, NES_HEIGHT, ntsc_video_out, NTSC_WIDTH * sizeof(uint16)); @@ -1877,9 +1847,6 @@ static void retro_run_blit(uint8_t *gfx) height = overscan_v ? 224 : 240; pitch = width * sizeof(uint16_t); -#ifdef NTSC_SCANLINES - if (use_ntsc_scanlines == 0) -#endif { const uint16_t *in = ntsc_video_out + h_offset + NTSC_WIDTH * v_offset; uint16_t *out = fceu_video_out; @@ -1892,31 +1859,6 @@ static void retro_run_blit(uint8_t *gfx) out += width; } } -#ifdef NTSC_SCANLINES - else - { - int y; - height <<= 1; - for (y = (NES_HEIGHT - v_offset); --y >= v_offset;) - { - uint16_t const *in = ntsc_video_out + y * NTSC_WIDTH; - uint16_t *out = fceu_video_out + (y - v_offset) * 2 * width; - int n; - for (n = width; n; --n) - { - unsigned prev = *(in + h_offset); - unsigned next = *(in + h_offset + NTSC_WIDTH); - /* mix 16-bit rgb without losing low bits */ - unsigned mixed = prev + next + ((prev ^ next) & 0x0821); - /* darken by 12% */ - *out = prev; - *(out + width) = (mixed >> 1) - (mixed >> 4 & 0x18E3); - in++; - out++; - } - } - } -#endif /* NTSC_SCANLINES */ } else #endif /* HAVE_NTSC_FILTER */ @@ -2381,15 +2323,11 @@ bool retro_load_game(const struct retro_game_info *game) fceu_video_out = (uint16_t*)linearMemAlign(256 * 240 * sizeof(uint16_t), 128); #elif !defined(PSP) #ifdef HAVE_NTSC_FILTER -#define FB_WIDTH 602 -#ifdef NTSC_SCANLINES -#define FB_HEIGHT 480 -#else -#define FB_HEIGHT 240 -#endif +#define FB_WIDTH NTSC_WIDTH +#define FB_HEIGHT NES_HEIGHT #else /* !HAVE_NTSC_FILTER */ -#define FB_WIDTH 256 -#define FB_HEIGHT 240 +#define FB_WIDTH NES_WIDTH +#define FB_HEIGHT NES_HEIGHT #endif fceu_video_out = (uint16_t*)malloc(FB_WIDTH * FB_HEIGHT * sizeof(uint16_t)); #endif diff --git a/src/drivers/libretro/libretro_core_options.h b/src/drivers/libretro/libretro_core_options.h index 3d37d07..35ce4c9 100644 --- a/src/drivers/libretro/libretro_core_options.h +++ b/src/drivers/libretro/libretro_core_options.h @@ -92,19 +92,6 @@ struct retro_core_option_definition option_defs_common[] = { }, "disabled" }, -#ifdef NTSC_SCANLINES - { - "fceumm_ntsc_scanlines", - "NTSC Scanlines", - "Enable scanlines when using NTSC filters.", - { - { "disabled", NULL }, - { "enabled", NULL }, - { NULL, NULL }, - }, - "disabled" - }, -#endif /* NTSC_SCANLINES */ #endif { "fceumm_palette", From 99347130c30323eb95f3ffc1a761f68ffe0d8408 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 5 May 2020 09:24:24 +0800 Subject: [PATCH 3/4] Fix timing when changing from PAL/Dendy to NTSC - Happens when starting with PAL/Dendy region and changing to NTSC can cause frame to get stuck in 50 Hz - using RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO should remedy this. --- src/drivers/libretro/libretro.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 63c27e3..7ddfd1f 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -1107,11 +1107,14 @@ static void set_apu_channels(int chan) static void check_variables(bool startup) { struct retro_variable var = {0}; - int audio_video_updated = 0; bool palette_updated = false; char key[256]; int i, enable_apu; + /* 1 = Performs only geometry update: e.g. overscans */ + /* 2 = Performs video/geometry update when needed and timing changes: e.g. region and filter change */ + int audio_video_updated = 0; + var.key = "fceumm_ramstate"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -1141,7 +1144,10 @@ static void check_variables(bool startup) else if (strcmp(var.value, "monochrome") == 0) use_ntsc = NTSC_MONOCHROME; if (use_ntsc != orig_value) + { + ResetPalette(); audio_video_updated = 2; + } } #endif /* HAVE_NTSC_FILTER */ @@ -1282,7 +1288,7 @@ static void check_variables(bool startup) if (newval != use_overscan) { use_overscan = newval; - geometry_update = true; + audio_video_updated = 1; } } @@ -1367,7 +1373,10 @@ static void check_variables(bool startup) else if (!strcmp(var.value, "Dendy")) opt_region = 3; if (opt_region != oldval) + { FCEUD_RegionOverride(opt_region); + audio_video_updated = 2; + } } var.key = "fceumm_sndquality"; From 048d9d9c822ca6f0df694bdba097a41b0f9117b4 Mon Sep 17 00:00:00 2001 From: negativeExponent Date: Tue, 5 May 2020 13:35:30 +0800 Subject: [PATCH 4/4] libretro.c: Input updates - some assorted libretro-related input updates and refactoring --- Makefile.libretro | 2 +- src/drivers/libretro/libretro.c | 206 +++++++++++++++----------------- 2 files changed, 100 insertions(+), 108 deletions(-) diff --git a/Makefile.libretro b/Makefile.libretro index b71d0a4..42f51bc 100644 --- a/Makefile.libretro +++ b/Makefile.libretro @@ -726,7 +726,7 @@ ifneq (,$(findstring msvc,$(platform))) COREDEFINES += -DINLINE=_inline endif -CFLAGS += -DWANT_GRIFFIN +CFLAGS += -DWANT_GRIFFIN -Werror=implicit-function-declaration OBJECTS := $(SOURCES_C:.c=.o) OBJECTS += $(RETROARCH_OBJECTS) diff --git a/src/drivers/libretro/libretro.c b/src/drivers/libretro/libretro.c index 7ddfd1f..52d2c93 100644 --- a/src/drivers/libretro/libretro.c +++ b/src/drivers/libretro/libretro.c @@ -5,6 +5,9 @@ #include #include +#include +#include +#include #include "../../fceu.h" #include "../../fceu-endian.h" @@ -28,11 +31,6 @@ #include "libretro-common/include/libretro_gskit_ps2.h" #endif -#include "libretro-common/include/streams/memory_stream.h" -#include "libretro_dipswitch.h" - -#include "libretro_core_options.h" - #define MAX_PLAYERS 4 /* max supported players */ #define MAX_PORTS 2 /* max controller ports, * port 0 for player 1/3, port 1 for player 2/4 */ @@ -73,16 +71,67 @@ static bool use_overscan; static bool overscan_h; static bool overscan_v; #endif -static bool up_down_allowed = false; + static bool use_raw_palette; static bool use_par; -static bool enable_4player = false; -static unsigned turbo_enabler[MAX_PLAYERS] = {0}; -static unsigned turbo_delay = 0; -static unsigned input_type[MAX_PLAYERS + 1] = {0}; /* 4-players + famicom expansion */ + +/* + * Flags to keep track of whether turbo + * buttons toggled on or off. + * + * There are two values in array + * for Turbo A and Turbo B for + * each player + */ + +#define MAX_BUTTONS 8 +#define TURBO_BUTTONS 2 +unsigned char turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; + +typedef struct +{ + unsigned retro; + unsigned nes; +} keymap; + +static const keymap turbomap[] = { + { RETRO_DEVICE_ID_JOYPAD_X, JOY_A }, + { RETRO_DEVICE_ID_JOYPAD_Y, JOY_B }, +}; + +static const keymap bindmap[] = { + { RETRO_DEVICE_ID_JOYPAD_A, JOY_A }, + { RETRO_DEVICE_ID_JOYPAD_B, JOY_B }, + { RETRO_DEVICE_ID_JOYPAD_SELECT, JOY_SELECT }, + { RETRO_DEVICE_ID_JOYPAD_START, JOY_START }, + { RETRO_DEVICE_ID_JOYPAD_UP, JOY_UP }, + { RETRO_DEVICE_ID_JOYPAD_DOWN, JOY_DOWN }, + { RETRO_DEVICE_ID_JOYPAD_LEFT, JOY_LEFT }, + { RETRO_DEVICE_ID_JOYPAD_RIGHT, JOY_RIGHT }, +}; + +typedef struct { + bool enable_4player; /* four-score / 4-player adapter used */ + bool up_down_allowed; /* disabled simultaneous up+down and left+right dpad combinations */ + + /* turbo related */ + uint32_t turbo_enabler[MAX_PLAYERS]; + uint32_t turbo_delay; + + uint32_t type[MAX_PLAYERS + 1]; /* 4-players + famicom expansion */ + + /* input data */ + uint8_t JSReturn[MAX_PLAYERS]; /* 1-4 player data */ + uint32_t MouseData[MAX_PORTS][3]; /* nes mouse data */ + uint32_t FamicomData; /* Famicom expansion port data */ +} NES_INPUT_T; + +static NES_INPUT_T nes_input = { 0 }; enum RetroZapperInputModes{RetroLightgun, RetroMouse, RetroPointer}; static enum RetroZapperInputModes zappermode = RetroLightgun; +static bool libretro_supports_bitmasks = false; + /* emulator-specific variables */ const size_t PPU_BIT = 1ULL << 31ULL; @@ -126,12 +175,8 @@ static unsigned sndvolume; unsigned swapDuty; static int32_t *sound = 0; -static uint32_t JSReturn = 0; static uint32_t Dummy = 0; -static uint32_t MouseData[MAX_PORTS][3] = { {0} }; -static uint32_t fc_MouseData[3] = {0}; static uint32_t current_palette = 0; - static unsigned serialize_size; int PPUViewScanline=0; @@ -653,8 +698,6 @@ static void ResetPalette(void) #endif } -static bool libretro_supports_bitmasks = false; - unsigned retro_api_version(void) { return RETRO_API_VERSION; @@ -685,7 +728,7 @@ void retro_set_input_state(retro_input_state_t cb) static void update_nes_controllers(unsigned port, unsigned device) { - input_type[port] = device; + nes_input.type[port] = device; if (port < 4) { @@ -696,17 +739,17 @@ static void update_nes_controllers(unsigned port, unsigned device) FCEU_printf(" Player %u: None Connected\n", port + 1); break; case RETRO_DEVICE_ZAPPER: - FCEUI_SetInput(port, SI_ZAPPER, MouseData[port], 1); + FCEUI_SetInput(port, SI_ZAPPER, nes_input.MouseData[port], 1); FCEU_printf(" Player %u: Zapper\n", port + 1); break; case RETRO_DEVICE_ARKANOID: - FCEUI_SetInput(port, SI_ARKANOID, MouseData[port], 0); + FCEUI_SetInput(port, SI_ARKANOID, nes_input.MouseData[port], 0); FCEU_printf(" Player %u: Arkanoid\n", port + 1); break; case RETRO_DEVICE_GAMEPAD: default: - input_type[port] = RETRO_DEVICE_GAMEPAD; - FCEUI_SetInput(port, SI_GAMEPAD, &JSReturn, 0); + nes_input.type[port] = RETRO_DEVICE_GAMEPAD; + FCEUI_SetInput(port, SI_GAMEPAD, (uint32_t*)nes_input.JSReturn, 0); FCEU_printf(" Player %u: Gamepad\n", port + 1); break; } @@ -717,19 +760,19 @@ static void update_nes_controllers(unsigned port, unsigned device) switch (device) { case RETRO_DEVICE_FC_ARKANOID: - FCEUI_SetInputFC(SIFC_ARKANOID, fc_MouseData, 0); + FCEUI_SetInputFC(SIFC_ARKANOID, &nes_input.FamicomData, 0); FCEU_printf(" Famicom Expansion: Arkanoid\n"); break; case RETRO_DEVICE_FC_SHADOW: - FCEUI_SetInputFC(SIFC_SHADOW, fc_MouseData, 1); + FCEUI_SetInputFC(SIFC_SHADOW, &nes_input.FamicomData, 1); FCEU_printf(" Famicom Expansion: (Bandai) Hyper Shot\n"); break; case RETRO_DEVICE_FC_OEKAKIDS: - FCEUI_SetInputFC(SIFC_OEKAKIDS, fc_MouseData, 1); + FCEUI_SetInputFC(SIFC_OEKAKIDS, &nes_input.FamicomData, 1); FCEU_printf(" Famicom Expansion: Oeka Kids Tablet\n"); break; case RETRO_DEVICE_FC_4PLAYERS: - FCEUI_SetInputFC(SIFC_4PLAYER, &JSReturn, 0); + FCEUI_SetInputFC(SIFC_4PLAYER, (uint32_t*)nes_input.JSReturn, 0); FCEU_printf(" Famicom Expansion: Famicom 4-Player Adapter\n"); break; case RETRO_DEVICE_NONE: @@ -797,18 +840,18 @@ void retro_set_controller_port_device(unsigned port, unsigned device) /* This section automatically enables 4players support * when player 3 or 4 used */ - input_type[port] = RETRO_DEVICE_NONE; + nes_input.type[port] = RETRO_DEVICE_NONE; if (device == RETRO_DEVICE_AUTO) { - if (enable_4player) - input_type[port] = RETRO_DEVICE_GAMEPAD; + if (nes_input.enable_4player) + nes_input.type[port] = RETRO_DEVICE_GAMEPAD; } else if (device == RETRO_DEVICE_GAMEPAD) - input_type[port] = RETRO_DEVICE_GAMEPAD; + nes_input.type[port] = RETRO_DEVICE_GAMEPAD; FCEU_printf(" Player %u: %s\n", port + 1, - (input_type[port] == RETRO_DEVICE_NONE) ? "None Connected" : "Gamepad"); + (nes_input.type[port] == RETRO_DEVICE_NONE) ? "None Connected" : "Gamepad"); } else /* do famicom controllers here */ { @@ -818,14 +861,14 @@ void retro_set_controller_port_device(unsigned port, unsigned device) update_nes_controllers(4, fc_to_libretro(GameInfo->inputfc)); } - if (input_type[2] == RETRO_DEVICE_GAMEPAD - || input_type[3] == RETRO_DEVICE_GAMEPAD) + if (nes_input.type[2] == RETRO_DEVICE_GAMEPAD + || nes_input.type[3] == RETRO_DEVICE_GAMEPAD) FCEUI_DisableFourScore(0); else FCEUI_DisableFourScore(1); /* check if famicom 4player adapter is used */ - if (input_type[4] == RETRO_DEVICE_FC_4PLAYERS) + if (nes_input.type[4] == RETRO_DEVICE_FC_4PLAYERS) FCEUI_DisableFourScore(1); } } @@ -1083,18 +1126,6 @@ void retro_reset(void) ResetNES(); } -typedef struct -{ - unsigned retro; - unsigned nes; -} keymap; - - -static const keymap turbomap[] = { - { RETRO_DEVICE_ID_JOYPAD_X, JOY_A }, - { RETRO_DEVICE_ID_JOYPAD_Y, JOY_B }, -}; - static void set_apu_channels(int chan) { FSettings.SquareVolume[1] = (chan & 1) ? 256 : 0; @@ -1206,11 +1237,9 @@ static void check_variables(bool startup) var.key = "fceumm_up_down_allowed"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - up_down_allowed = (!strcmp(var.value, "enabled")) ? true : false; - } + nes_input.up_down_allowed = (!strcmp(var.value, "enabled")) ? true : false; else - up_down_allowed = false; + nes_input.up_down_allowed = false; var.key = "fceumm_nospritelimit"; @@ -1333,32 +1362,24 @@ static void check_variables(bool startup) if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { - turbo_enabler[0] = 0; - turbo_enabler[1] = 0; + nes_input.turbo_enabler[0] = 0; + nes_input.turbo_enabler[1] = 0; if (!strcmp(var.value, "Player 1")) - { - turbo_enabler[0] = 1; - turbo_enabler[1] = 0; - } + nes_input.turbo_enabler[0] = 1; else if (!strcmp(var.value, "Player 2")) - { - turbo_enabler[0] = 0; - turbo_enabler[1] = 1; - } + nes_input.turbo_enabler[1] = 1; else if (!strcmp(var.value, "Both")) { - turbo_enabler[0] = 1; - turbo_enabler[1] = 1; + nes_input.turbo_enabler[0] = 1; + nes_input.turbo_enabler[1] = 1; } } var.key = "fceumm_turbo_delay"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) - { - turbo_delay = atoi(var.value); - } + nes_input.turbo_delay = atoi(var.value); var.key = "fceumm_region"; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) @@ -1419,9 +1440,7 @@ static void check_variables(bool startup) { bool newval = (!strcmp(var.value, "enabled")); if (newval != swapDuty) - { swapDuty = newval; - } } var.key = key; @@ -1434,9 +1453,7 @@ static void check_variables(bool startup) key[strlen("fceumm_apu_")] = '1' + i; var.value = NULL; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && !strcmp(var.value, "disabled")) - { enable_apu &= ~(1 << i); - } } set_apu_channels(enable_apu); @@ -1602,33 +1619,18 @@ void get_mouse_input(unsigned port, uint32_t *zapdata) } } -/* - * Flags to keep track of whether turbo - * buttons toggled on or off. - * - * There are two values in array - * for Turbo A and Turbo B for - * each player - */ - -#define MAX_BUTTONS 8 -#define TURBO_BUTTONS 2 -unsigned char turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS] = { {0} }; - static void FCEUD_UpdateInput(void) { unsigned player, port; poll_cb(); - JSReturn = 0; - /* nes gamepad */ for (player = 0; player < MAX_PLAYERS; player++) { int i = 0; uint8_t input_buf = 0; - int player_enabled = (input_type[player] == RETRO_DEVICE_GAMEPAD) || (input_type[player] == RETRO_DEVICE_JOYPAD); + int player_enabled = (nes_input.type[player] == RETRO_DEVICE_GAMEPAD) || (nes_input.type[player] == RETRO_DEVICE_JOYPAD); if (player_enabled) { @@ -1657,16 +1659,6 @@ static void FCEUD_UpdateInput(void) } else { - static const keymap bindmap[] = { - { RETRO_DEVICE_ID_JOYPAD_A, JOY_A }, - { RETRO_DEVICE_ID_JOYPAD_B, JOY_B }, - { RETRO_DEVICE_ID_JOYPAD_SELECT, JOY_SELECT }, - { RETRO_DEVICE_ID_JOYPAD_START, JOY_START }, - { RETRO_DEVICE_ID_JOYPAD_UP, JOY_UP }, - { RETRO_DEVICE_ID_JOYPAD_DOWN, JOY_DOWN }, - { RETRO_DEVICE_ID_JOYPAD_LEFT, JOY_LEFT }, - { RETRO_DEVICE_ID_JOYPAD_RIGHT, JOY_RIGHT }, - }; for (i = 0; i < MAX_BUTTONS; i++) input_buf |= input_cb(player, RETRO_DEVICE_JOYPAD, 0, bindmap[i].retro) ? bindmap[i].nes : 0; @@ -1683,7 +1675,7 @@ static void FCEUD_UpdateInput(void) * been reached. */ - if (turbo_enabler[player]) + if (nes_input.turbo_enabler[player]) { /* Handle Turbo A & B buttons */ for (i = 0; i < TURBO_BUTTONS; i++) @@ -1693,7 +1685,7 @@ static void FCEUD_UpdateInput(void) if (!turbo_button_toggle[player][i]) input_buf |= turbomap[i].nes; turbo_button_toggle[player][i]++; - turbo_button_toggle[player][i] %= turbo_delay + 1; + turbo_button_toggle[player][i] %= nes_input.turbo_delay + 1; } else /* If the button is not pressed, just reset the toggle */ @@ -1702,7 +1694,7 @@ static void FCEUD_UpdateInput(void) } } - if (!up_down_allowed) + if (!nes_input.up_down_allowed) { if (input_buf & (JOY_UP)) if (input_buf & (JOY_DOWN)) @@ -1712,28 +1704,28 @@ static void FCEUD_UpdateInput(void) input_buf &= ~((JOY_LEFT ) | (JOY_RIGHT)); } - JSReturn |= (input_buf & 0xff) << (player << 3); + nes_input.JSReturn[player] = input_buf; } /* other inputs*/ for (port = 0; port < MAX_PORTS; port++) { - switch (input_type[port]) + switch (nes_input.type[port]) { case RETRO_DEVICE_ARKANOID: case RETRO_DEVICE_ZAPPER: - get_mouse_input(port, MouseData[port]); + get_mouse_input(port, nes_input.MouseData[port]); break; } } /* famicom inputs */ - switch (input_type[4]) + switch (nes_input.type[4]) { case RETRO_DEVICE_FC_ARKANOID: case RETRO_DEVICE_FC_OEKAKIDS: case RETRO_DEVICE_FC_SHADOW: - get_mouse_input(0, fc_MouseData); + get_mouse_input(0, &nes_input.FamicomData); break; } @@ -2370,8 +2362,8 @@ bool retro_load_game(const struct retro_game_info *game) } for (i = 0; i < MAX_PORTS; i++) { - FCEUI_SetInput(i, SI_GAMEPAD, &JSReturn, 0); - input_type[i] = RETRO_DEVICE_JOYPAD; + FCEUI_SetInput(i, SI_GAMEPAD, (uint32_t*)nes_input.JSReturn, 0); + nes_input.type[i] = RETRO_DEVICE_JOYPAD; } external_palette_exist = ipalette; @@ -2396,7 +2388,7 @@ bool retro_load_game(const struct retro_game_info *game) if (fourscore_db_list[i].crc == iNESCart.CRC32) { FCEUI_DisableFourScore(0); - enable_4player = true; + nes_input.enable_4player = true; break; } } @@ -2406,8 +2398,8 @@ bool retro_load_game(const struct retro_game_info *game) if (famicom_4p_db_list[i].crc == iNESCart.CRC32) { GameInfo->inputfc = SIFC_4PLAYER; - FCEUI_SetInputFC(SIFC_4PLAYER, &JSReturn, 0); - enable_4player = true; + FCEUI_SetInputFC(SIFC_4PLAYER, (uint32_t*)nes_input.JSReturn, 0); + nes_input.enable_4player = true; break; } }