From 66ea86b46aeb034c837c2c9208364560003c606d Mon Sep 17 00:00:00 2001 From: M4xw Date: Mon, 4 Feb 2019 14:11:08 +0100 Subject: [PATCH] [WIP] Add mupen64plus-core minimal changes Platform buildfix - is this accurate enough? WIP Dynarec Speed workaround at perf cost C89 fix Remove dummy_rsp Fix awk Fix savestates, some ground work for cheats cleanup Transition fixes (CBFD etc) Fix cheats Fix Savefiles [LIBNX] Small dynarec perf hack ASM defines for android, currently not generated. Libnx transition cleanup Add Fullspeed Core option (simliar to ParaLLEl) Add CountPerScanlineOverride (VI Refresh Overclock) Similar to ParaLLEl new_dynarec: add assembler defines for ARM platform * Right now if the platform generates them they will pop up in `asm_defines` and that takes priority over the backend folders, so lets just commit them for the time being (m4xw). Fix deinit Potential mitigation for Indiana Jones (aarch64) Only relevant with new GLideN64 Check inputs using poll callback. [NXJIT] Cleanup, use RW/RX bases Still missing Horizon ver. detection GLideN64 needed changes (WIP) Minor cleanup stop_after_jal for all but libnx Added core option: ForceDisableExtraMem N64DD Support via Subsystems Fix new_dynarec uncached code execution Add alternative loading of DD image files - Relevant for broken Subsystem on static Platforms, like Switch Add CXD4. ParallelRSP Preperations Implement angrylion core-options and multi-plugin handling Co-authored-by: twinaphex First revision of new Core options - Deprecated GLN header for Core options - Add Hybrid Filter Core option - Add Dithering Pattern Core option - Add Dithering Quantization Core option - Add RDRAM Image Dithering Mode Core option - Additional thanks to Tatsuya79 and dmrlawson Update & Revert to Stock INI Headers - Removes OoT Subscreen fix, might've caused Issues [GLN64] Implement Threaded Renderer [NX] Test JIT Changes - Lowers platform requirements [Core] Remove CountPerOp=1 for Quake 2 and Goldfinger - This cripples perf on Switch and Android with GLN64 - No regression has been found so far Remove Bone displacement fix after testing for DK64, update INI headers Add IgnoreTLBExceptions Options - Current workaround for the tricky Dynarec Issue for OoT - Added 3 Modes, one only skips if the game doesn't use TLB, one always skips (useful for GdbStub) and one is upstream behaviour Integrate paraLLEl-RDP. Fix build without new_dynarec Better handling for dynarec tlb exception filter Add GET_CLEAR_ALL_THREAD_WAITS_CB, fixes all freezes with thr on several platforms. Also force early polling instead of late for it. Update pre-created asm defines for aarch64 Only relevant for Android Backport 07f09151 to arm/x64/x86 dynarec backends Add asm defines for Android x86 / x86_64 and allow Android x86_64 core to be built Fix macro after libretro-common rebase [Fixme] Remove all baked headers Liberate rdram_size after rebase again [Squash me] Fixes after rebase Experimental transferpak Experimental netplay Hacky expose fast fwd w/o env cb (needs v/a sync off) Fix storage sharing for netplay Fast fwd extension (unreleased, amend and remove libretro.h later) Fix PIC for x86 new_dynarec, enable Android x86 TODO: Try ndk bump Trivial perf improvement on initial recompilation Use original delta method for android, fallback to new method for nasm Explicitly declare fPIC flags Misc fixes & disable netplay support Add asm_defines headers for Android Add sys/types.h for u_int declaration Fixes after rebase Cleanup & Update INI Headers Placeholder for DD disk saves Update asm_defines for Android Fix file_storage_save Strdup all globals and let the inner core handle their lifetime Cleanup global paths garbage collection, add cleanup_global_paths Use ifile_storage_ro handler for save types Lower logs in dd_controller Note: Maybe causes netplay shenanigans as-is, verify DD disk name shenanigans Move mempak filestorage to readonly (handled via libretro) Sanity checks Add CountPerOpDenomPot (Overclock) Cache flush optimization for pointer invalidation TODO: Port to ARMv7 Update asm_defines headers for Android Build on OSX arm64 --- data/mupen64plus.ini | 3 - src/api/frontend.c | 85 +-- src/api/vidext.c | 9 - src/backends/file_storage.c | 22 +- .../plugins_compat/audio_plugin_compat.c | 13 +- .../plugins_compat/input_plugin_compat.c | 15 +- src/device/controllers/paks/biopak.c | 7 +- src/device/dd/dd_controller.c | 20 +- src/device/dd/disk.c | 10 +- src/device/memory/memory.c | 8 +- src/device/r4300/fpu.h | 6 +- .../r4300/new_dynarec/arm/asm_defines_gas.h | 35 + .../r4300/new_dynarec/arm/asm_defines_nasm.h | 35 + .../r4300/new_dynarec/arm64/asm_defines_gas.h | 35 + .../new_dynarec/arm64/asm_defines_nasm.h | 35 + .../r4300/new_dynarec/arm64/assem_arm64.c | 15 +- .../r4300/new_dynarec/arm64/assem_arm64.h | 1 + src/device/r4300/new_dynarec/new_dynarec.c | 27 +- .../r4300/new_dynarec/x64/asm_defines_gas.h | 35 + .../r4300/new_dynarec/x64/asm_defines_nasm.h | 35 + .../r4300/new_dynarec/x86/asm_defines_gas.h | 35 + .../r4300/new_dynarec/x86/asm_defines_nasm.h | 35 + src/device/r4300/new_dynarec/x86/assem_x86.c | 4 + .../r4300/new_dynarec/x86/linkage_x86.asm | 13 +- src/device/r4300/tlb.c | 31 +- src/device/rcp/vi/vi_controller.c | 23 +- src/main/cheat.c | 40 +- src/main/eventloop.c | 3 - src/main/main.c | 717 ++++++------------ src/main/netplay.c | 51 +- src/main/netplay.h | 2 +- src/main/savestates.c | 177 ++++- src/main/savestates.h | 8 + src/main/sdl_key_converter.h | 5 +- src/plugin/plugin.c | 522 ++++++------- src/plugin/plugin.h | 5 + 36 files changed, 1129 insertions(+), 993 deletions(-) create mode 100644 src/device/r4300/new_dynarec/arm/asm_defines_gas.h create mode 100644 src/device/r4300/new_dynarec/arm/asm_defines_nasm.h create mode 100644 src/device/r4300/new_dynarec/arm64/asm_defines_gas.h create mode 100644 src/device/r4300/new_dynarec/arm64/asm_defines_nasm.h create mode 100644 src/device/r4300/new_dynarec/x64/asm_defines_gas.h create mode 100644 src/device/r4300/new_dynarec/x64/asm_defines_nasm.h create mode 100644 src/device/r4300/new_dynarec/x86/asm_defines_gas.h create mode 100644 src/device/r4300/new_dynarec/x86/asm_defines_nasm.h diff --git a/data/mupen64plus.ini b/data/mupen64plus.ini index 78c15776..a83be182 100644 --- a/data/mupen64plus.ini +++ b/data/mupen64plus.ini @@ -11,7 +11,6 @@ CRC=B2242748 FFBD61DA Status=1 Rumble=Yes Players=4 -CountPerOp=1 [34AB1DEA3111A233A8B5C5679DE22E83] GoodName=007 - The World is Not Enough (E) (M3) [!] @@ -12886,7 +12885,6 @@ Players=4 SaveType=None Mempak=Yes Rumble=Yes -CountPerOp=1 [55A789C553827114306E29D71E26E5DC] GoodName=Quake II (E) [h1C] @@ -12900,7 +12898,6 @@ Players=4 SaveType=None Mempak=Yes Rumble=Yes -CountPerOp=1 [920FAACCE1F8A80022433ACFD5CD2BC3] GoodName=Quake II (U) [f1] (PAL) diff --git a/src/api/frontend.c b/src/api/frontend.c index d9cc1523..ce76e60f 100644 --- a/src/api/frontend.c +++ b/src/api/frontend.c @@ -19,20 +19,18 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - + /* This file contains the Core front-end functions which will be exported * outside of the core library. */ -#include #include #include #include -#include #define M64P_CORE_PROTOTYPES 1 #include "callbacks.h" -#include "config.h" +#include "api/config.h" #include "m64p_config.h" #include "m64p_frontend.h" #include "m64p_types.h" @@ -43,8 +41,8 @@ #include "main/savestates.h" #include "main/util.h" #include "main/version.h" +#include "main/cheat.h" #include "main/workqueue.h" -#include "main/screenshot.h" #include "main/netplay.h" #include "plugin/plugin.h" #include "vidext.h" @@ -64,7 +62,7 @@ EXPORT m64p_error CALL CoreStartup(int APIVersion, const char *ConfigPath, const return M64ERR_ALREADY_INIT; /* check wether the caller has already initialized SDL */ - l_CallerUsingSDL = (SDL_WasInit(0) != 0); + l_CallerUsingSDL = 1; //(SDL_WasInit(0) != 0); /* very first thing is to set the callback functions for debug info and state changing*/ SetDebugCallback(DebugCallback, Context); @@ -81,25 +79,6 @@ EXPORT m64p_error CALL CoreStartup(int APIVersion, const char *ConfigPath, const /* Initialize the main device structure to all zeros */ memset(&g_dev, 0, sizeof(struct device)); - /* set up the default (dummy) plugins */ - plugin_connect(M64PLUGIN_GFX, NULL); - plugin_connect(M64PLUGIN_AUDIO, NULL); - plugin_connect(M64PLUGIN_INPUT, NULL); - plugin_connect(M64PLUGIN_CORE, NULL); - - savestates_init(); - - /* next, start up the configuration handling code by loading and parsing the config file */ - if (ConfigInit(ConfigPath, DataPath) != M64ERR_SUCCESS) - return M64ERR_INTERNAL; - - /* set default configuration parameter values for Core */ - if (ConfigOpenSection("Core", &g_CoreConfig) != M64ERR_SUCCESS || g_CoreConfig == NULL) - return M64ERR_INTERNAL; - - if (!main_set_core_defaults()) - return M64ERR_INTERNAL; - /* allocate base memory */ g_mem_base = init_mem_base(); if (g_mem_base == NULL) { @@ -126,10 +105,6 @@ EXPORT m64p_error CALL CoreShutdown(void) workqueue_shutdown(); savestates_deinit(); - /* if the calling code is using SDL, don't shut it down */ - if (!l_CallerUsingSDL) - SDL_Quit(); - /* deallocate base memory */ release_mem_base(g_mem_base); g_mem_base = NULL; @@ -143,32 +118,12 @@ EXPORT m64p_error CALL CoreShutdown(void) EXPORT m64p_error CALL CoreAttachPlugin(m64p_plugin_type PluginType, m64p_dynlib_handle PluginLibHandle) { - m64p_error rval; - - if (!l_CoreInit) - return M64ERR_NOT_INIT; - if (g_EmulatorRunning || (!l_ROMOpen && !l_DiskOpen)) - return M64ERR_INVALID_STATE; - - rval = plugin_connect(PluginType, PluginLibHandle); - if (rval != M64ERR_SUCCESS) - return rval; - - rval = plugin_start(PluginType); - if (rval != M64ERR_SUCCESS) - return rval; - return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreDetachPlugin(m64p_plugin_type PluginType) { - if (!l_CoreInit) - return M64ERR_NOT_INIT; - if (g_EmulatorRunning) - return M64ERR_INVALID_STATE; - - return plugin_connect(PluginType, NULL); + return M64ERR_SUCCESS; } EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *ParamPtr) @@ -193,7 +148,6 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P if (rval == M64ERR_SUCCESS) { l_ROMOpen = 1; - ScreenshotRomOpen(); cheat_init(&g_cheat_ctx); } return rval; @@ -235,7 +189,7 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P return M64ERR_INVALID_STATE; if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; - if ((int)sizeof(m64p_rom_header) < ParamInt) + if (sizeof(m64p_rom_header) < ParamInt) ParamInt = sizeof(m64p_rom_header); memcpy(ParamPtr, &ROM_HEADER, ParamInt); // Mupen64Plus used to keep a m64p_rom_header with a clean ROM name @@ -251,7 +205,7 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P return M64ERR_INVALID_STATE; if (ParamPtr == NULL) return M64ERR_INPUT_ASSERT; - if ((int)sizeof(m64p_rom_settings) < ParamInt) + if (sizeof(m64p_rom_settings) < ParamInt) ParamInt = sizeof(m64p_rom_settings); memcpy(ParamPtr, &ROM_SETTINGS, ParamInt); return M64ERR_SUCCESS; @@ -267,8 +221,6 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P case M64CMD_EXECUTE: if (g_EmulatorRunning || (!l_ROMOpen && !l_DiskOpen)) return M64ERR_INVALID_STATE; - /* print out plugin-related warning messages */ - plugin_check(); /* the main_run() function will not return until the player has quit the game */ rval = main_run(); return rval; @@ -294,14 +246,12 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P return M64ERR_INPUT_ASSERT; return main_core_state_set((m64p_core_param) ParamInt, *((int *)ParamPtr)); case M64CMD_STATE_LOAD: - main_state_load((char *) ParamPtr); return M64ERR_SUCCESS; case M64CMD_STATE_SAVE: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; if (ParamPtr != NULL && (ParamInt < 1 || ParamInt > 3)) return M64ERR_INPUT_INVALID; - main_state_save(ParamInt, (char *) ParamPtr); return M64ERR_SUCCESS; case M64CMD_STATE_SET_SLOT: if (ParamInt < 0 || ParamInt > 9) @@ -312,31 +262,20 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P return M64ERR_INVALID_STATE; keysym = ParamInt & 0xffff; keymod = (ParamInt >> 16) & 0xffff; - event_sdl_keydown(keysym, keymod); return M64ERR_SUCCESS; case M64CMD_SEND_SDL_KEYUP: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; keysym = ParamInt & 0xffff; keymod = (ParamInt >> 16) & 0xffff; - event_sdl_keyup(keysym, keymod); return M64ERR_SUCCESS; case M64CMD_SET_FRAME_CALLBACK: - *(void**)&g_FrameCallback = ParamPtr; + g_FrameCallback = (m64p_frame_callback) ParamPtr; return M64ERR_SUCCESS; case M64CMD_TAKE_NEXT_SCREENSHOT: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; - main_take_next_screenshot(); return M64ERR_SUCCESS; - case M64CMD_READ_SCREEN: - if (!g_EmulatorRunning) - return M64ERR_INVALID_STATE; - if (ParamPtr == NULL) - return M64ERR_INPUT_ASSERT; - if (ParamInt < 0 || ParamInt > 1) - return M64ERR_INPUT_INVALID; - return main_read_screen(ParamPtr, ParamInt); case M64CMD_RESET: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; @@ -346,12 +285,6 @@ EXPORT m64p_error CALL CoreDoCommand(m64p_command Command, int ParamInt, void *P case M64CMD_ADVANCE_FRAME: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; - main_advance_one(); - return M64ERR_SUCCESS; - case M64CMD_SET_MEDIA_LOADER: - if (ParamInt != sizeof(m64p_media_loader) || ParamPtr == NULL) - return M64ERR_INPUT_INVALID; - g_media_loader = *(m64p_media_loader*)ParamPtr; return M64ERR_SUCCESS; case M64CMD_NETPLAY_INIT: if (ParamInt < 1 || ParamPtr == NULL) @@ -433,7 +366,7 @@ EXPORT m64p_error CALL CoreGetRomSettings(m64p_rom_settings *RomSettings, int Ro return M64ERR_NOT_INIT; if (RomSettings == NULL) return M64ERR_INPUT_ASSERT; - if (RomSettingsLength < (int)sizeof(m64p_rom_settings)) + if (RomSettingsLength < sizeof(m64p_rom_settings)) return M64ERR_INPUT_INVALID; /* Look up this ROM in the .ini file and fill in goodname, etc */ diff --git a/src/api/vidext.c b/src/api/vidext.c index 82cc1088..9566876d 100644 --- a/src/api/vidext.c +++ b/src/api/vidext.c @@ -23,15 +23,6 @@ * outside of the core library. */ -#include -/* we need at least SDL 2.0.6 for vulkan */ -#if !SDL_VERSION_ATLEAST(2,0,6) - #undef VIDEXT_VULKAN -#endif -#ifdef VIDEXT_VULKAN -#include -#include -#endif #include #include diff --git a/src/backends/file_storage.c b/src/backends/file_storage.c index 0b5d4a83..313102fe 100644 --- a/src/backends/file_storage.c +++ b/src/backends/file_storage.c @@ -30,6 +30,9 @@ #include "main/util.h" #include "main/netplay.h" +#include +#include + int open_file_storage(struct file_storage* fstorage, size_t size, const char* filename) { /* ! Take ownership of filename ! */ @@ -73,8 +76,17 @@ int open_rom_file_storage(struct file_storage* fstorage, const char* filename) void close_file_storage(struct file_storage* fstorage) { - free((void*)fstorage->data); - free((void*)fstorage->filename); + if(fstorage->data) + { + free((void*)fstorage->data); + fstorage->data = NULL; + } + + if(fstorage->filename) + { + free((void*)fstorage->filename); + fstorage->filename = NULL; + } } @@ -94,7 +106,7 @@ static void file_storage_save(void* storage, size_t start, size_t size) { if (netplay_is_init() && netplay_get_controller(0) == -1) return; - + struct file_storage* fstorage = (struct file_storage*)storage; file_status_t err; @@ -112,10 +124,10 @@ static void file_storage_save(void* storage, size_t start, size_t size) switch(err) { case file_open_error: - DebugMessage(M64MSG_WARNING, "couldn't open storage file '%s' for writing", fstorage->filename); + log_cb(RETRO_LOG_WARN, "Couldn't open storage file '%s' for writing\n", fstorage->filename); break; case file_write_error: - DebugMessage(M64MSG_WARNING, "failed to write storage file '%s'", fstorage->filename); + log_cb(RETRO_LOG_WARN, "Failed to write storage file '%s'\n", fstorage->filename); break; default: break; diff --git a/src/backends/plugins_compat/audio_plugin_compat.c b/src/backends/plugins_compat/audio_plugin_compat.c index 327a4048..14287f1a 100644 --- a/src/backends/plugins_compat/audio_plugin_compat.c +++ b/src/backends/plugins_compat/audio_plugin_compat.c @@ -20,6 +20,17 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include +#include "plugins_compat.h" + +#include "api/m64p_plugin.h" +#include "plugin/plugin.h" + +#include "main/main.h" + +#include +#include +#include +#include #include "backends/api/audio_out_backend.h" #include "device/rcp/ai/ai_controller.h" @@ -27,7 +38,7 @@ #include "device/rcp/vi/vi_controller.h" #include "device/rdram/rdram.h" #include "main/rom.h" -#include "plugin/plugin.h" + static void audio_plugin_set_frequency(void* aout, unsigned int frequency) { diff --git a/src/backends/plugins_compat/input_plugin_compat.c b/src/backends/plugins_compat/input_plugin_compat.c index ceb1128a..8ebdd059 100644 --- a/src/backends/plugins_compat/input_plugin_compat.c +++ b/src/backends/plugins_compat/input_plugin_compat.c @@ -33,6 +33,7 @@ #include #include #include +#include /* XXX: this is an abuse of the Zilmar Spec normally this value is reserved */ enum { @@ -90,7 +91,6 @@ static m64p_error input_plugin_get_input(void* opaque, uint32_t* input_) return M64ERR_SYSTEM_FAIL; } - /* has Controls[i].Plugin changed since last call */ if (cin_compat->last_pak_type != Controls[cin_compat->control_id].Plugin) { pak_change_requested = 1; @@ -114,18 +114,25 @@ static m64p_error input_plugin_get_input(void* opaque, uint32_t* input_) if (cin_compat->pak_switch_delay > 0 && --cin_compat->pak_switch_delay == 0) { cin_compat->main_switch_pak(cin_compat->control_id); cin_compat->main_switch_pak = NULL; + // If switching to Transfer Pak and if a rom path is set, Switch it + if(Controls[cin_compat->control_id].Plugin == PLUGIN_TRANSFER_PAK && retro_transferpak_rom_path) + { + cin_compat->gb_cart_switch_enabled = 1; + } } if (cin_compat->gb_cart_switch_enabled) { - /* disconnect current GB cart (if any) immediately after "GB cart switch" button is released */ - if (is_button_released(keys.Value, cin_compat->last_input, GB_CART_SWITCH_BUTTON)) { + // disconnect current GB cart (if any) immediately after "GB cart switch" button is released + if (!cin_compat->gb_switch_delay) { change_gb_cart(cin_compat->tpk, NULL); cin_compat->gb_switch_delay = GB_CART_SWITCH_DELAY; } - /* switch to new GB cart after switch delay has expired */ + // switch to new GB cart after switch delay has expired if (cin_compat->gb_switch_delay > 0 && --cin_compat->gb_switch_delay == 0) { main_change_gb_cart(cin_compat->control_id); + cin_compat->gb_cart_switch_enabled = 0; + cin_compat->gb_switch_delay = 0; } } diff --git a/src/device/controllers/paks/biopak.c b/src/device/controllers/paks/biopak.c index 6f5e743a..d08ed149 100644 --- a/src/device/controllers/paks/biopak.c +++ b/src/device/controllers/paks/biopak.c @@ -28,8 +28,11 @@ #include "api/m64p_types.h" #include "api/callbacks.h" -#include +#ifdef HAVE_LIBNX +#include +#endif +#include #include void init_biopak(struct biopak* bpk, @@ -51,7 +54,7 @@ static void read_biopak(void* pak, uint16_t address, uint8_t* data, size_t size) struct biopak* bpk = (struct biopak*)pak; if (address == 0xc000) { - uint32_t now = SDL_GetTicks(); + time_t now = time(NULL) * 1000; uint32_t period = UINT32_C(60*1000) / bpk->bpm; uint32_t k = now % period; diff --git a/src/device/dd/dd_controller.c b/src/device/dd/dd_controller.c index d27172e2..33fafe5a 100644 --- a/src/device/dd/dd_controller.c +++ b/src/device/dd/dd_controller.c @@ -204,8 +204,8 @@ static void read_C2(struct dd_controller* dd) sector %= 90; size_t offset = 0x40 * (sector - SECTORS_PER_BLOCK); - DebugMessage(M64MSG_VERBOSE, "read C2: length=%08x, offset=%08x", - (uint32_t)length, (uint32_t)offset); + //DebugMessage(M64MSG_VERBOSE, "read C2: length=%08x, offset=%08x", + // (uint32_t)length, (uint32_t)offset); for (i = 0; i < length; ++i) { dd->c2s_buf[(offset + i) ^ 3] = 0; @@ -431,7 +431,7 @@ void read_dd_regs(void* opaque, uint32_t address, uint32_t* value) } *value = dd->regs[reg]; - DebugMessage(M64MSG_VERBOSE, "DD REG: %08X -> %08x", address, *value); + //DebugMessage(M64MSG_VERBOSE, "DD REG: %08X -> %08x", address, *value); /* post read update. Not part of the returned value */ switch(reg) @@ -462,7 +462,7 @@ void write_dd_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask assert(mask == ~UINT32_C(0)); - DebugMessage(M64MSG_VERBOSE, "DD REG: %08X <- %08x", address, value); + //DebugMessage(M64MSG_VERBOSE, "DD REG: %08X <- %08x", address, value); switch (reg) { @@ -787,12 +787,12 @@ void read_dd_rom(void* opaque, uint32_t address, uint32_t* value) *value = dd->rom[addr]; - DebugMessage(M64MSG_VERBOSE, "DD ROM: %08X -> %08x", address, *value); + //DebugMessage(M64MSG_VERBOSE, "DD ROM: %08X -> %08x", address, *value); } void write_dd_rom(void* opaque, uint32_t address, uint32_t value, uint32_t mask) { - DebugMessage(M64MSG_VERBOSE, "DD ROM: %08X <- %08x & %08x", address, value, mask); + //DebugMessage(M64MSG_VERBOSE, "DD ROM: %08X <- %08x & %08x", address, value, mask); } unsigned int dd_dom_dma_read(void* opaque, const uint8_t* dram, uint32_t dram_addr, uint32_t cart_addr, uint32_t length) @@ -801,8 +801,8 @@ unsigned int dd_dom_dma_read(void* opaque, const uint8_t* dram, uint32_t dram_ad uint8_t* mem; size_t i; - DebugMessage(M64MSG_VERBOSE, "DD DMA read dram=%08x cart=%08x length=%08x", - dram_addr, cart_addr, length); + //DebugMessage(M64MSG_VERBOSE, "DD DMA read dram=%08x cart=%08x length=%08x", + // dram_addr, cart_addr, length); if (cart_addr == MM_DD_DS_BUFFER) { cart_addr = (cart_addr - MM_DD_DS_BUFFER) & 0x3fffff; @@ -836,8 +836,8 @@ unsigned int dd_dom_dma_write(void* opaque, uint8_t* dram, uint32_t dram_addr, u const uint8_t* mem; size_t i; - DebugMessage(M64MSG_VERBOSE, "DD DMA write dram=%08x cart=%08x length=%08x", - dram_addr, cart_addr, length); + //DebugMessage(M64MSG_VERBOSE, "DD DMA write dram=%08x cart=%08x length=%08x", + // dram_addr, cart_addr, length); if (cart_addr < MM_DD_ROM) { if (cart_addr == MM_DD_C2S_BUFFER) { diff --git a/src/device/dd/disk.c b/src/device/dd/disk.c index 7f5e9454..405d28fd 100644 --- a/src/device/dd/disk.c +++ b/src/device/dd/disk.c @@ -330,8 +330,8 @@ static uint8_t* get_sector_base_sdk(const struct dd_disk* disk, } } - if (lba <= MAX_LBA && sector == 0) - DebugMessage(M64MSG_VERBOSE, "LBA %d - Offset %08X - Size %04X", lba, offset, sector_size * SECTORS_PER_BLOCK); + //if (lba <= MAX_LBA && sector == 0) + // DebugMessage(M64MSG_VERBOSE, "LBA %d - Offset %08X - Size %04X", lba, offset, sector_size * SECTORS_PER_BLOCK); return disk->istorage->data(disk->storage) + offset; } @@ -376,8 +376,8 @@ static uint8_t* get_sector_base_d64(const struct dd_disk* disk, return NULL; } - if (lba <= MAX_LBA && sector == 0) - DebugMessage(M64MSG_VERBOSE, "LBA %d - Offset %08X - Size %04X", lba, offset, sector_size * SECTORS_PER_BLOCK); + //if (lba <= MAX_LBA && sector == 0) + // DebugMessage(M64MSG_VERBOSE, "LBA %d - Offset %08X - Size %04X", lba, offset, sector_size * SECTORS_PER_BLOCK); return disk->istorage->data(disk->storage) + offset; } @@ -530,7 +530,7 @@ uint8_t* scan_and_expand_disk_format(uint8_t* data, size_t size, size_t d64_size = D64_OFFSET_DATA + rom_size + ram_size; size_t full_d64_size = D64_OFFSET_DATA + rom_size + RAM_SIZES[disk_type]; - DebugMessage(M64MSG_INFO, "D64 Disk Areas - ROM: 0000 - %04X / RAM: %04X - %04X", rom_lba_end, ram_lba_start, ram_lba_end); + //DebugMessage(M64MSG_INFO, "D64 Disk Areas - ROM: 0000 - %04X / RAM: %04X - %04X", rom_lba_end, ram_lba_start, ram_lba_end); if (ram_lba_start != (RAM_START_LBA[disk_type] - 24) && ram_lba_start != 0xFFFF) { diff --git a/src/device/memory/memory.c b/src/device/memory/memory.c index 715a67ab..6625d198 100644 --- a/src/device/memory/memory.c +++ b/src/device/memory/memory.c @@ -42,10 +42,11 @@ #include #include -#ifdef _WIN32 +#if defined(_WIN32) || defined(HAVE_LIBNX) #include #endif + #ifdef DBG enum { @@ -246,9 +247,14 @@ void* init_mem_base(void) /* First try the full mem base alloc */ #ifdef _WIN32 mem_base = _aligned_malloc(MB_MAX_SIZE_FULL, MB_RDRAM_DRAM_ALIGNMENT_REQUIREMENT); +#else +#ifdef HAVE_LIBNX + if (!(mem_base = memalign(MB_RDRAM_DRAM_ALIGNMENT_REQUIREMENT, MB_MAX_SIZE_FULL))) + mem_base = NULL; #else if (posix_memalign(&mem_base, MB_RDRAM_DRAM_ALIGNMENT_REQUIREMENT, MB_MAX_SIZE_FULL) != 0) mem_base = NULL; +#endif // HAVE_LIBNX #endif if (mem_base == NULL) { /* if it failed, try the compressed mem base alloc */ diff --git a/src/device/r4300/fpu.h b/src/device/r4300/fpu.h index 14c23bba..6d175531 100644 --- a/src/device/r4300/fpu.h +++ b/src/device/r4300/fpu.h @@ -40,7 +40,9 @@ static __inline float truncf(float x) { return (float)(int)x; } #else #define M64P_FPU_INLINE static inline -#include +#if !defined(VITA) && !defined(__SWITCH__) + #include +#endif #endif #define FCR31_CMP_BIT UINT32_C(0x800000) @@ -69,6 +71,7 @@ static __inline float truncf(float x) { return (float)(int)x; } M64P_FPU_INLINE void set_rounding(uint32_t fcr31) { +#if !defined(VITA) && !defined(__SWITCH__) switch(fcr31 & 3) { case 0: /* Round to nearest, or to even if equidistant */ fesetround(FE_TONEAREST); @@ -83,6 +86,7 @@ M64P_FPU_INLINE void set_rounding(uint32_t fcr31) fesetround(FE_DOWNWARD); break; } +#endif } #ifdef ACCURATE_FPU_BEHAVIOR diff --git a/src/device/r4300/new_dynarec/arm/asm_defines_gas.h b/src/device/r4300/new_dynarec/arm/asm_defines_gas.h new file mode 100644 index 00000000..b137e36c --- /dev/null +++ b/src/device/r4300/new_dynarec/arm/asm_defines_gas.h @@ -0,0 +1,35 @@ +#define offsetof_struct_device_r4300 (0x00000000) +#define offsetof_struct_r4300_core_cp0 (0x029014cc) +#define offsetof_struct_cp0_last_addr (0x0000017c) +#define offsetof_struct_cp0_count_per_op (0x00000180) +#define offsetof_struct_cp0_tlb (0x00000188) +#define offsetof_struct_tlb_entries (0x00000000) +#define offsetof_struct_tlb_LUT_r (0x00000680) +#define offsetof_struct_tlb_LUT_w (0x00400680) +#define offsetof_struct_r4300_core_cached_interp (0x00000098) +#define offsetof_struct_cached_interp_invalid_code (0x00000000) +#define offsetof_struct_r4300_core_new_dynarec_hot_state (0x02501000) +#define offsetof_struct_r4300_core_extra_memory (0x00501000) +#define offsetof_struct_new_dynarec_hot_state_dynarec_local (0x00000000) +#define offsetof_struct_new_dynarec_hot_state_cycle_count (0x00000040) +#define offsetof_struct_new_dynarec_hot_state_pending_exception (0x00000044) +#define offsetof_struct_new_dynarec_hot_state_pcaddr (0x00000048) +#define offsetof_struct_new_dynarec_hot_state_stop (0x0000004c) +#define offsetof_struct_new_dynarec_hot_state_invc_ptr (0x00000050) +#define offsetof_struct_new_dynarec_hot_state_fcr0 (0x0000006c) +#define offsetof_struct_new_dynarec_hot_state_fcr31 (0x00000070) +#define offsetof_struct_new_dynarec_hot_state_regs (0x00000078) +#define offsetof_struct_new_dynarec_hot_state_hi (0x00000178) +#define offsetof_struct_new_dynarec_hot_state_lo (0x00000180) +#define offsetof_struct_new_dynarec_hot_state_cp0_regs (0x00000188) +#define offsetof_struct_new_dynarec_hot_state_cp1_regs_simple (0x00000208) +#define offsetof_struct_new_dynarec_hot_state_cp1_regs_double (0x00000288) +#define offsetof_struct_new_dynarec_hot_state_rounding_modes (0x00000308) +#define offsetof_struct_new_dynarec_hot_state_branch_target (0x00000318) +#define offsetof_struct_new_dynarec_hot_state_pc (0x0000031c) +#define offsetof_struct_new_dynarec_hot_state_fake_pc (0x00000320) +#define offsetof_struct_new_dynarec_hot_state_rs (0x000003a8) +#define offsetof_struct_new_dynarec_hot_state_rt (0x000003b0) +#define offsetof_struct_new_dynarec_hot_state_rd (0x000003b8) +#define offsetof_struct_new_dynarec_hot_state_mini_ht (0x000003c4) +#define offsetof_struct_new_dynarec_hot_state_memory_map (0x000004c4) diff --git a/src/device/r4300/new_dynarec/arm/asm_defines_nasm.h b/src/device/r4300/new_dynarec/arm/asm_defines_nasm.h new file mode 100644 index 00000000..508dc99b --- /dev/null +++ b/src/device/r4300/new_dynarec/arm/asm_defines_nasm.h @@ -0,0 +1,35 @@ +%define offsetof_struct_device_r4300 (0x00000000) +%define offsetof_struct_r4300_core_cp0 (0x029014cc) +%define offsetof_struct_cp0_last_addr (0x0000017c) +%define offsetof_struct_cp0_count_per_op (0x00000180) +%define offsetof_struct_cp0_tlb (0x00000188) +%define offsetof_struct_tlb_entries (0x00000000) +%define offsetof_struct_tlb_LUT_r (0x00000680) +%define offsetof_struct_tlb_LUT_w (0x00400680) +%define offsetof_struct_r4300_core_cached_interp (0x00000098) +%define offsetof_struct_cached_interp_invalid_code (0x00000000) +%define offsetof_struct_r4300_core_new_dynarec_hot_state (0x02501000) +%define offsetof_struct_r4300_core_extra_memory (0x00501000) +%define offsetof_struct_new_dynarec_hot_state_dynarec_local (0x00000000) +%define offsetof_struct_new_dynarec_hot_state_cycle_count (0x00000040) +%define offsetof_struct_new_dynarec_hot_state_pending_exception (0x00000044) +%define offsetof_struct_new_dynarec_hot_state_pcaddr (0x00000048) +%define offsetof_struct_new_dynarec_hot_state_stop (0x0000004c) +%define offsetof_struct_new_dynarec_hot_state_invc_ptr (0x00000050) +%define offsetof_struct_new_dynarec_hot_state_fcr0 (0x0000006c) +%define offsetof_struct_new_dynarec_hot_state_fcr31 (0x00000070) +%define offsetof_struct_new_dynarec_hot_state_regs (0x00000078) +%define offsetof_struct_new_dynarec_hot_state_hi (0x00000178) +%define offsetof_struct_new_dynarec_hot_state_lo (0x00000180) +%define offsetof_struct_new_dynarec_hot_state_cp0_regs (0x00000188) +%define offsetof_struct_new_dynarec_hot_state_cp1_regs_simple (0x00000208) +%define offsetof_struct_new_dynarec_hot_state_cp1_regs_double (0x00000288) +%define offsetof_struct_new_dynarec_hot_state_rounding_modes (0x00000308) +%define offsetof_struct_new_dynarec_hot_state_branch_target (0x00000318) +%define offsetof_struct_new_dynarec_hot_state_pc (0x0000031c) +%define offsetof_struct_new_dynarec_hot_state_fake_pc (0x00000320) +%define offsetof_struct_new_dynarec_hot_state_rs (0x000003a8) +%define offsetof_struct_new_dynarec_hot_state_rt (0x000003b0) +%define offsetof_struct_new_dynarec_hot_state_rd (0x000003b8) +%define offsetof_struct_new_dynarec_hot_state_mini_ht (0x000003c4) +%define offsetof_struct_new_dynarec_hot_state_memory_map (0x000004c4) diff --git a/src/device/r4300/new_dynarec/arm64/asm_defines_gas.h b/src/device/r4300/new_dynarec/arm64/asm_defines_gas.h new file mode 100644 index 00000000..15fc3f6b --- /dev/null +++ b/src/device/r4300/new_dynarec/arm64/asm_defines_gas.h @@ -0,0 +1,35 @@ +#define offsetof_struct_device_r4300 (0x00000000) +#define offsetof_struct_r4300_core_cp0 (0x031017d8) +#define offsetof_struct_cp0_last_addr (0x00000278) +#define offsetof_struct_cp0_count_per_op (0x0000027c) +#define offsetof_struct_cp0_tlb (0x00000284) +#define offsetof_struct_tlb_entries (0x00000000) +#define offsetof_struct_tlb_LUT_r (0x00000680) +#define offsetof_struct_tlb_LUT_w (0x00400680) +#define offsetof_struct_r4300_core_cached_interp (0x000000e0) +#define offsetof_struct_cached_interp_invalid_code (0x00000000) +#define offsetof_struct_r4300_core_new_dynarec_hot_state (0x02901000) +#define offsetof_struct_r4300_core_extra_memory (0x00901000) +#define offsetof_struct_new_dynarec_hot_state_dynarec_local (0x00000000) +#define offsetof_struct_new_dynarec_hot_state_cycle_count (0x00000100) +#define offsetof_struct_new_dynarec_hot_state_pending_exception (0x00000104) +#define offsetof_struct_new_dynarec_hot_state_pcaddr (0x00000108) +#define offsetof_struct_new_dynarec_hot_state_stop (0x0000010c) +#define offsetof_struct_new_dynarec_hot_state_invc_ptr (0x00000110) +#define offsetof_struct_new_dynarec_hot_state_fcr0 (0x00000134) +#define offsetof_struct_new_dynarec_hot_state_fcr31 (0x00000138) +#define offsetof_struct_new_dynarec_hot_state_regs (0x00000140) +#define offsetof_struct_new_dynarec_hot_state_hi (0x00000240) +#define offsetof_struct_new_dynarec_hot_state_lo (0x00000248) +#define offsetof_struct_new_dynarec_hot_state_cp0_regs (0x00000250) +#define offsetof_struct_new_dynarec_hot_state_cp1_regs_simple (0x000002d0) +#define offsetof_struct_new_dynarec_hot_state_cp1_regs_double (0x000003d0) +#define offsetof_struct_new_dynarec_hot_state_rounding_modes (0x000004d0) +#define offsetof_struct_new_dynarec_hot_state_branch_target (0x000004e0) +#define offsetof_struct_new_dynarec_hot_state_pc (0x000004e8) +#define offsetof_struct_new_dynarec_hot_state_fake_pc (0x000004f0) +#define offsetof_struct_new_dynarec_hot_state_rs (0x000005b0) +#define offsetof_struct_new_dynarec_hot_state_rt (0x000005b8) +#define offsetof_struct_new_dynarec_hot_state_rd (0x000005c0) +#define offsetof_struct_new_dynarec_hot_state_mini_ht (0x000005d0) +#define offsetof_struct_new_dynarec_hot_state_memory_map (0x000007d0) diff --git a/src/device/r4300/new_dynarec/arm64/asm_defines_nasm.h b/src/device/r4300/new_dynarec/arm64/asm_defines_nasm.h new file mode 100644 index 00000000..a1a12ebd --- /dev/null +++ b/src/device/r4300/new_dynarec/arm64/asm_defines_nasm.h @@ -0,0 +1,35 @@ +%define offsetof_struct_device_r4300 (0x00000000) +%define offsetof_struct_r4300_core_cp0 (0x031017d8) +%define offsetof_struct_cp0_last_addr (0x00000278) +%define offsetof_struct_cp0_count_per_op (0x0000027c) +%define offsetof_struct_cp0_tlb (0x00000284) +%define offsetof_struct_tlb_entries (0x00000000) +%define offsetof_struct_tlb_LUT_r (0x00000680) +%define offsetof_struct_tlb_LUT_w (0x00400680) +%define offsetof_struct_r4300_core_cached_interp (0x000000e0) +%define offsetof_struct_cached_interp_invalid_code (0x00000000) +%define offsetof_struct_r4300_core_new_dynarec_hot_state (0x02901000) +%define offsetof_struct_r4300_core_extra_memory (0x00901000) +%define offsetof_struct_new_dynarec_hot_state_dynarec_local (0x00000000) +%define offsetof_struct_new_dynarec_hot_state_cycle_count (0x00000100) +%define offsetof_struct_new_dynarec_hot_state_pending_exception (0x00000104) +%define offsetof_struct_new_dynarec_hot_state_pcaddr (0x00000108) +%define offsetof_struct_new_dynarec_hot_state_stop (0x0000010c) +%define offsetof_struct_new_dynarec_hot_state_invc_ptr (0x00000110) +%define offsetof_struct_new_dynarec_hot_state_fcr0 (0x00000134) +%define offsetof_struct_new_dynarec_hot_state_fcr31 (0x00000138) +%define offsetof_struct_new_dynarec_hot_state_regs (0x00000140) +%define offsetof_struct_new_dynarec_hot_state_hi (0x00000240) +%define offsetof_struct_new_dynarec_hot_state_lo (0x00000248) +%define offsetof_struct_new_dynarec_hot_state_cp0_regs (0x00000250) +%define offsetof_struct_new_dynarec_hot_state_cp1_regs_simple (0x000002d0) +%define offsetof_struct_new_dynarec_hot_state_cp1_regs_double (0x000003d0) +%define offsetof_struct_new_dynarec_hot_state_rounding_modes (0x000004d0) +%define offsetof_struct_new_dynarec_hot_state_branch_target (0x000004e0) +%define offsetof_struct_new_dynarec_hot_state_pc (0x000004e8) +%define offsetof_struct_new_dynarec_hot_state_fake_pc (0x000004f0) +%define offsetof_struct_new_dynarec_hot_state_rs (0x000005b0) +%define offsetof_struct_new_dynarec_hot_state_rt (0x000005b8) +%define offsetof_struct_new_dynarec_hot_state_rd (0x000005c0) +%define offsetof_struct_new_dynarec_hot_state_mini_ht (0x000005d0) +%define offsetof_struct_new_dynarec_hot_state_memory_map (0x000007d0) diff --git a/src/device/r4300/new_dynarec/arm64/assem_arm64.c b/src/device/r4300/new_dynarec/arm64/assem_arm64.c index 84097657..98dea54f 100644 --- a/src/device/r4300/new_dynarec/arm64/assem_arm64.c +++ b/src/device/r4300/new_dynarec/arm64/assem_arm64.c @@ -302,6 +302,9 @@ static void set_jump_target(intptr_t addr,uintptr_t target) intptr_t offset=target-(intptr_t)addr; if(ptr==NULL) return; + if(!ptr) // Indiana Jones is weird + return; + if((*ptr&0xFC000000)==0x14000000) { assert(offset>=-134217728LL&&offset<134217728LL); *ptr=(*ptr&0xFC000000)|((offset>>2)&0x3ffffff); @@ -354,6 +357,9 @@ static void *kill_pointer(void *stub) int *i_ptr=(int*)((intptr_t)ptr+offset); assert((*i_ptr&0xfc000000)==0x14000000); //b set_jump_target((intptr_t)i_ptr,(intptr_t)stub); + + intptr_t ptr_rx=((intptr_t)i_ptr-(intptr_t)base_addr)+(intptr_t)base_addr_rx; + cache_flush((void*)ptr_rx, (void*)(ptr_rx+4)); return i_ptr; } @@ -2994,7 +3000,7 @@ static void emit_adr(intptr_t addr, int rt) intptr_t offset=addr-(intptr_t)out_rx; assert(offset>=-1048576LL&&offset<1048576LL); - assem_debug("adr %d,#%d",regname64[rt],offset); + assem_debug("adr %s,#%d",regname64[rt],offset); output_w32(0x10000000|(offset&0x3)<<29|((offset>>2)&0x7ffff)<<5|rt); } static void emit_adrp(intptr_t addr, int rt) @@ -3007,7 +3013,7 @@ static void emit_adrp(intptr_t addr, int rt) assert(offset>=-4294967296LL&&offset<4294967296LL); offset>>=12; assert((((intptr_t)out_rx&~0xfffLL)+(offset<<12))==(addr&~0xfffLL)); - assem_debug("adrp %d,#%d",regname64[rt],offset); + assem_debug("adrp %s,#%d",regname64[rt],offset); output_w32(0x90000000|(offset&0x3)<<29|((offset>>2)&0x7ffff)<<5|rt); } #if 0 @@ -4484,7 +4490,8 @@ static void multdiv_assemble_arm64(int i,struct regstat *i_regs) assert(r1l>=0); assert(r2l>=0); - for(int hr=0;hrregmap[hr]>=0) reglist|=1< #include // needed for u_int, u_char, etc #include +#include #if defined(WIN32) #ifndef WIN32_LEAN_AND_MEAN @@ -55,7 +56,11 @@ #include "device/rcp/rsp/rsp_core.h" #if !defined(WIN32) +#ifndef HAVE_LIBNX #include +#else +#include "../../../../../switch/mman.h" +#endif // HAVE_LIBNX #endif #if defined(RECOMPILER_DEBUG) && !defined(RECOMP_DBG) @@ -149,6 +154,8 @@ static void ensure_dynarec_cache_alignment(void) #define assem_debug(...) DebugMessage(M64MSG_VERBOSE, __VA_ARGS__) #else #define assem_debug(...) + // Cleanup debug copies + #define strcpy(...) #endif #if INV_DEBUG #define inv_debug(...) DebugMessage(M64MSG_VERBOSE, __VA_ARGS__) @@ -2520,7 +2527,7 @@ static void ll_kill_pointers(struct ll_entry *head,intptr_t addr,int shift) { inv_debug("EXP: Kill pointer at %x (%x)\n",(intptr_t)head->addr,head->vaddr); uintptr_t host_addr=(intptr_t)kill_pointer(head->addr); - #if NEW_DYNAREC >= NEW_DYNAREC_ARM + #if NEW_DYNAREC == NEW_DYNAREC_ARM needs_clear_cache[(host_addr-(uintptr_t)base_addr)>>17]|=1<<(((host_addr-(uintptr_t)base_addr)>>12)&31); #else /* avoid unused variable warning */ @@ -2861,7 +2868,7 @@ static void invalidate_page(u_int page) while(head!=NULL) { inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(intptr_t)head->addr); uintptr_t host_addr=(intptr_t)kill_pointer(head->addr); - #if NEW_DYNAREC >= NEW_DYNAREC_ARM + #if NEW_DYNAREC == NEW_DYNAREC_ARM needs_clear_cache[(host_addr-(uintptr_t)base_addr)>>17]|=1<<(((host_addr-(uintptr_t)base_addr)>>12)&31); #else /* avoid unused variable warning */ @@ -8696,6 +8703,9 @@ static void pagespan_ds(void) } /**** Recompiler ****/ +#ifdef HAVE_LIBNX +ALIGN(4096, char jit_memory[33554432]) __attribute__((section(".text"))); +#endif void new_dynarec_init(void) { DebugMessage(M64MSG_INFO, "Init new dynarec"); @@ -8713,9 +8723,17 @@ void new_dynarec_init(void) #define DOUBLE_CACHE_ADDR 3 // Put the dynarec cache at random address with RW address != RX address // Default to fixed cache address +#ifdef HAVE_LIBNX +#define CACHE_ADDR DOUBLE_CACHE_ADDR +#else #define CACHE_ADDR FIXED_CACHE_ADDR +#endif #if CACHE_ADDR==DOUBLE_CACHE_ADDR +#ifdef HAVE_LIBNX + base_addr = mmap((u_char *)jit_memory, 1< #include #include @@ -8736,6 +8754,7 @@ void new_dynarec_init(void) assert(base_addr_rx!=(void*)-1); close(fd); +#endif // HAVE_LIBNX #elif CACHE_ADDR==FIXED_CACHE_ADDR mprotect ((u_char *)g_dev.r4300.extra_memory, 1<=0x80&&ptr[1]<=0x8f); diff --git a/src/device/r4300/new_dynarec/x86/linkage_x86.asm b/src/device/r4300/new_dynarec/x86/linkage_x86.asm index 17c14bb3..379feeed 100644 --- a/src/device/r4300/new_dynarec/x86/linkage_x86.asm +++ b/src/device/r4300/new_dynarec/x86/linkage_x86.asm @@ -55,14 +55,21 @@ section .note.GNU-stack noalloc noexec nowrite progbits add ebx,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc %endmacro +%macro get_delta 0 + call %%getdelta + %%getdelta: + pop ebx + sub ebx, %%getdelta +%endmacro + %ifdef PIC %define get_got_address get_GOT %define find_local_data(a) ebx + a wrt ..gotoff %define find_external_data(a) ebx + a wrt ..got %else - %define get_got_address - %define find_local_data(a) a - %define find_extern_data(a) a + %define get_got_address get_delta + %define find_local_data(a) ebx + a + %define find_external_data(a) ebx + a %endif %define g_dev_r4300_new_dynarec_hot_state_stop (g_dev + offsetof_struct_device_r4300 + offsetof_struct_r4300_core_new_dynarec_hot_state + offsetof_struct_new_dynarec_hot_state_stop) diff --git a/src/device/r4300/tlb.c b/src/device/r4300/tlb.c index b7a29e8d..35d3b902 100644 --- a/src/device/r4300/tlb.c +++ b/src/device/r4300/tlb.c @@ -20,6 +20,7 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "tlb.h" +#include #include "api/m64p_types.h" #include "device/r4300/r4300_core.h" @@ -140,7 +141,35 @@ uint32_t virtual_to_physical_address(struct r4300_core* r4300, uint32_t address, //printf("tlb exception !!! @ %x, %x, add:%x\n", address, w, r4300->pc->addr); //getchar(); - TLB_refill_exception(r4300, address, w); +#ifdef NEW_DYNAREC + if(IgnoreTLBExceptions == 0) { + /* False, Default Behaviour */ + TLB_refill_exception(r4300, address, w); + } else if(IgnoreTLBExceptions == 1) { + /* OnlyNotEnabled */ + if(r4300->emumode == EMUMODE_DYNAREC) + { + if(using_tlb) + { + TLB_refill_exception(r4300, address, w); + } + } else { + TLB_refill_exception(r4300, address, w); + } + } else if(IgnoreTLBExceptions == 2) + { + /* AlwaysIgnoreTLB */ + /* Use-case GdbStub... */ + } +#else + if(IgnoreTLBExceptions == 2) + { + /* AlwaysIgnoreTLB */ + /* Use-case for Interpreter-only GdbStub... */ + } else { + TLB_refill_exception(r4300, address, w); + } +#endif // NEW_DYNAREC //return 0x80000000; return 0x00000000; diff --git a/src/device/rcp/vi/vi_controller.c b/src/device/rcp/vi/vi_controller.c index b644fcd7..e3b035d8 100644 --- a/src/device/rcp/vi/vi_controller.c +++ b/src/device/rcp/vi/vi_controller.c @@ -29,6 +29,7 @@ #include "device/rcp/mi/mi_controller.h" #include "main/main.h" #include "plugin/plugin.h" +#include unsigned int vi_clock_from_tv_standard(m64p_system_type tv_standard) { @@ -79,8 +80,13 @@ void poweron_vi(struct vi_controller* vi) { memset(vi->regs, 0, VI_REGS_COUNT*sizeof(uint32_t)); vi->field = 0; - vi->delay = 0; - vi->count_per_scanline = 0; + if(!CountPerScanlineOverride) { + vi->delay = 0; + vi->count_per_scanline = 0; + } else { + vi->delay = 5000; + vi->count_per_scanline = CountPerScanlineOverride; + } } void read_vi_regs(void* opaque, uint32_t address, uint32_t* value) @@ -142,7 +148,11 @@ void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask if ((vi->regs[VI_V_SYNC_REG] & mask) != (value & mask)) { masked_write(&vi->regs[VI_V_SYNC_REG], value, mask); - vi->count_per_scanline = (vi->clock / vi->expected_refresh_rate) / (vi->regs[VI_V_SYNC_REG] + 1); + if(!CountPerScanlineOverride) { + vi->count_per_scanline = (vi->clock / vi->expected_refresh_rate) / (vi->regs[VI_V_SYNC_REG] + 1); + } else { + vi->count_per_scanline = CountPerScanlineOverride; + } vi->delay = (vi->regs[VI_V_SYNC_REG] + 1) * vi->count_per_scanline; set_vi_vertical_interrupt(vi); } @@ -175,6 +185,13 @@ void vi_vertical_interrupt_event(void* opaque) vi->field ^= (vi->regs[VI_STATUS_REG] >> 6) & 0x1; /* schedule next vertical interrupt */ + if(CountPerScanlineOverride) { + if (vi->regs[VI_V_SYNC_REG] == 0) + vi->delay = 500000; + else + vi->delay = (vi->regs[VI_V_SYNC_REG] + 1) * vi->count_per_scanline; + } + uint32_t next_vi = *get_event(&vi->mi->r4300->cp0.q, VI_INT) + vi->delay; remove_interrupt_event(&vi->mi->r4300->cp0); add_interrupt_event_count(&vi->mi->r4300->cp0, VI_INT, next_vi); diff --git a/src/main/cheat.c b/src/main/cheat.c index 8058afad..eb41b782 100644 --- a/src/main/cheat.c +++ b/src/main/cheat.c @@ -22,8 +22,6 @@ /* gameshark and xploder64 reference: http://doc.kodewerx.net/hacking_n64.html */ -#include -#include #define __STDC_FORMAT_MACROS #include @@ -193,14 +191,14 @@ static cheat_t *find_or_create_cheat(struct cheat_ctx* ctx, const char *name) /* public functions */ void cheat_init(struct cheat_ctx* ctx) { - ctx->mutex = SDL_CreateMutex(); + ctx->mutex = NULL; //SDL_CreateMutex(); INIT_LIST_HEAD(&ctx->active_cheats); } void cheat_uninit(struct cheat_ctx* ctx) { if (ctx->mutex != NULL) { - SDL_DestroyMutex(ctx->mutex); + //SDL_DestroyMutex(ctx->mutex); } ctx->mutex = NULL; } @@ -210,16 +208,10 @@ void cheat_apply_cheats(struct cheat_ctx* ctx, struct r4300_core* r4300, int ent cheat_t *cheat; cheat_code_t *code; int cond_failed; - + if (list_empty(&ctx->active_cheats)) return; - if (ctx->mutex == NULL || SDL_LockMutex(ctx->mutex) != 0) - { - DebugMessage(M64MSG_ERROR, "Internal error: failed to lock mutex in cheat_apply_cheats()"); - return; - } - list_for_each_entry_t(cheat, &ctx->active_cheats, cheat_t, list) { if (cheat->enabled) { @@ -312,8 +304,6 @@ void cheat_apply_cheats(struct cheat_ctx* ctx, struct r4300_core* r4300, int ent } } } - - SDL_UnlockMutex(ctx->mutex); } @@ -325,12 +315,6 @@ void cheat_delete_all(struct cheat_ctx* ctx) if (list_empty(&ctx->active_cheats)) return; - if (ctx->mutex == NULL || SDL_LockMutex(ctx->mutex) != 0) - { - DebugMessage(M64MSG_ERROR, "Internal error: failed to lock mutex in cheat_delete_all()"); - return; - } - list_for_each_entry_safe_t(cheat, safe_cheat, &ctx->active_cheats, cheat_t, list) { free(cheat->name); @@ -341,8 +325,6 @@ void cheat_delete_all(struct cheat_ctx* ctx) list_del(&cheat->list); free(cheat); } - - SDL_UnlockMutex(ctx->mutex); } int cheat_set_enabled(struct cheat_ctx* ctx, const char* name, int enabled) @@ -352,22 +334,14 @@ int cheat_set_enabled(struct cheat_ctx* ctx, const char* name, int enabled) if (list_empty(&ctx->active_cheats)) return 0; - if (ctx->mutex == NULL || SDL_LockMutex(ctx->mutex) != 0) - { - DebugMessage(M64MSG_ERROR, "Internal error: failed to lock mutex in cheat_set_enabled()"); - return 0; - } - list_for_each_entry_t(cheat, &ctx->active_cheats, cheat_t, list) { if (strcmp(name, cheat->name) == 0) { cheat->enabled = enabled; - SDL_UnlockMutex(ctx->mutex); return 1; } } - SDL_UnlockMutex(ctx->mutex); return 0; } @@ -376,17 +350,10 @@ int cheat_add_new(struct cheat_ctx* ctx, const char* name, m64p_cheat_code* code cheat_t *cheat; int i, j; - if (ctx->mutex == NULL || SDL_LockMutex(ctx->mutex) != 0) - { - DebugMessage(M64MSG_ERROR, "Internal error: failed to lock mutex in cheat_add_new()"); - return 0; - } - /* create a new cheat function or erase the codes in an existing cheat function */ cheat = find_or_create_cheat(ctx, name); if (cheat == NULL) { - SDL_UnlockMutex(ctx->mutex); return 0; } @@ -426,7 +393,6 @@ int cheat_add_new(struct cheat_ctx* ctx, const char* name, m64p_cheat_code* code } } - SDL_UnlockMutex(ctx->mutex); return 1; } diff --git a/src/main/eventloop.c b/src/main/eventloop.c index eb0fd191..2522e6e0 100644 --- a/src/main/eventloop.c +++ b/src/main/eventloop.c @@ -20,13 +20,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include #include #include #include -SDL_JoystickID l_iJoyInstanceID[10]; - #define M64P_CORE_PROTOTYPES 1 #include "api/callbacks.h" #include "api/config.h" diff --git a/src/main/main.c b/src/main/main.c index 87dab35c..06ba0016 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -28,7 +28,6 @@ * if you want to implement an interface, you should look here */ -#include #include #include #include @@ -66,9 +65,7 @@ #include "device/pif/bootrom_hle.h" #include "eventloop.h" #include "main.h" -#include "osal/files.h" -#include "osal/preproc.h" -#include "osd/osd.h" +#include "callbacks.h" #include "plugin/plugin.h" #if defined(PROFILE) #include "profile.h" @@ -79,6 +76,25 @@ #include "util.h" #include "netplay.h" +#include +#include + +#ifdef M64P_NETPLAY +#undef SDL_GetTicks +#include +#endif // M64P_NETPLAY + +#ifdef HAVE_LIBNX +#include +#include +#endif + +#ifdef __LIBRETRO__ +#include +#include +#include +#endif // __LIBRETRO__ + #ifdef DBG #include "debugger/dbg_debugger.h" #endif @@ -124,10 +140,6 @@ static int l_SpeedFactor = 100; // percentage of nominal game speed at static int l_FrameAdvance = 0; // variable to check if we pause on next frame static int l_MainSpeedLimit = 1; // insert delay during vi_interrupt to keep speed at real-time -static osd_message_t *l_msgVol = NULL; -static osd_message_t *l_msgFF = NULL; -static osd_message_t *l_msgPause = NULL; - /* compatible paks */ enum { PAK_MAX_SIZE = 5 }; static size_t l_paks_idx[GAME_CONTROLLERS_COUNT]; @@ -144,20 +156,7 @@ static struct xoshiro256pp_state l_mpk_idgen; static const char *get_savepathdefault(const char *configpath) { - static char path[1024]; - - if (!configpath || (strlen(configpath) == 0)) { - snprintf(path, 1024, "%ssave%c", ConfigGetUserDataPath(), OSAL_DIR_SEPARATORS[0]); - path[1023] = 0; - } else { - snprintf(path, 1024, "%s%c", configpath, OSAL_DIR_SEPARATORS[0]); - path[1023] = 0; - } - - /* create directory if it doesn't exist */ - osal_mkdirp(path, 0700); - - return path; + return ""; } static char *get_save_filename(void) @@ -186,174 +185,50 @@ static char *get_save_filename(void) static char *get_mempaks_path(void) { - char *path; - size_t size = 0; - - /* check if old file path exists, if it does then use that */ - path = formatstr("%s%s.mpk", get_savesrampath(), ROM_SETTINGS.goodname); - if (get_file_size(path, &size) == file_ok && size > 0) - { - return path; - } - free(path); - - /* else use new path */ - return formatstr("%s%s.mpk", get_savesrampath(), get_save_filename()); + return ""; } static char *get_eeprom_path(void) { - char *path; - size_t size = 0; - - /* check if old file path exists, if it does then use that */ - path = formatstr("%s%s.eep", get_savesrampath(), ROM_SETTINGS.goodname); - if (get_file_size(path, &size) == file_ok && size > 0) - { - return path; - } - free(path); - - /* else use new path */ - return formatstr("%s%s.eep", get_savesrampath(), get_save_filename()); + return ""; } static char *get_sram_path(void) { - char *path; - size_t size = 0; - - /* check if old file path exists, if it does then use that */ - path = formatstr("%s%s.sra", get_savesrampath(), ROM_SETTINGS.goodname); - if (get_file_size(path, &size) == file_ok && size > 0) - { - return path; - } - free(path); - - /* else use new path */ - return formatstr("%s%s.sra", get_savesrampath(), get_save_filename()); + return ""; } static char *get_flashram_path(void) { - char *path; - size_t size = 0; - - /* check if old file path exists, if it does then use that */ - path = formatstr("%s%s.fla", get_savesrampath(), ROM_SETTINGS.goodname); - if (get_file_size(path, &size) == file_ok && size > 0) - { - return path; - } - free(path); - - /* else use new path */ - return formatstr("%s%s.fla", get_savesrampath(), get_save_filename()); + return ""; } static char *get_gb_ram_path(const char* gbrom, unsigned int control_id) { - return formatstr("%s%s.%u.sav", get_savesrampath(), gbrom, control_id); + return ""; } -static char *get_dd_disk_save_path(const char* disk, int format) -{ - char* filename = NULL; - - int len = strlen(disk); - int has_expected_ext = (len >= 4 && (strcmp(disk + len - 4, ".ndd") == 0 || strcmp(disk + len - 4, ".d64") == 0)); - - switch (format) { - case 0: /* *.ndr,*.d6r, full disk content */ - if (has_expected_ext) { - /* file has .ndd / .d64, so adjust existing extension */ - filename = formatstr("%s%s", get_savesrampath(), disk); - len = strlen(filename); - filename[len-1] = 'r'; - } - else { - /* file doesn't have .ndd / .d64 extension, so fallback to .ndr */ - filename = formatstr("%s%s.ndr", get_savesrampath(), disk); - } - break; - case 1: /* *.ram, only RAM part is persisted */ - if (has_expected_ext) { - /* file has .ndd / .d64, so adjust existing extension */ - filename = formatstr("%s%s", get_savesrampath(), disk); - len = strlen(filename); - filename[len-3] = 'r'; - filename[len-2] = 'a'; - filename[len-1] = 'm'; - } - else { - /* file doesn't have .ndd / .d64 extension, so fallback to .ram */ - filename = formatstr("%s%s.ram", get_savesrampath(), disk); - } - break; - default: - DebugMessage(M64MSG_WARNING, "Unexpected DD save format: %d", format); - break; - } - return filename; -} - - -static m64p_error init_video_capture_backend(const struct video_capture_backend_interface** ivcap, void** vcap, m64p_handle config, const char* key) -{ - m64p_error err; - - const char* name = ConfigGetParamString(config, key); - if (name == NULL) { - DebugMessage(M64MSG_WARNING, "Couldn't get %s value. Using NULL value instead.", key); - } - - /* try to find desired backend (by name) */ - *ivcap = get_video_capture_backend(name); - - /* handle not found case */ - if (*ivcap == NULL) { - /* default to dummy backend */ - *ivcap = get_video_capture_backend(NULL); - - DebugMessage(M64MSG_WARNING, "Could not find %s video_capture_backend_interface. Using %s instead.", - name, (*ivcap)->name); - } - - /* build section name */ - char* section = formatstr("%s:%s", key, (*ivcap)->name); - - /* init backend */ - err = (*ivcap)->init(vcap, section); - - if (err == M64ERR_SUCCESS) { - DebugMessage(M64MSG_INFO, "Using video capture backend: %s", (*ivcap)->name); - } - else { - DebugMessage(M64MSG_ERROR, "Failed to initialize video capture backend %s: %s", (*ivcap)->name, CoreErrorMessage(err)); - *ivcap = NULL; - } - - free(section); - - return err; -} - -/********************************************************************************************************* -* helper functions -*/ - - const char *get_savestatepath(void) { - /* try to get the SaveStatePath string variable in the Core configuration section */ - return get_savepathdefault(ConfigGetParamString(g_CoreConfig, "SaveStatePath")); + return ""; } const char *get_savesrampath(void) { - /* try to get the SaveSRAMPath string variable in the Core configuration section */ - return get_savepathdefault(ConfigGetParamString(g_CoreConfig, "SaveSRAMPath")); + return ""; +} + +const char *get_dd_disk_save_path(const char* diskname, int save_format) +{ + char* newPath = (char*)malloc(PATH_MAX); + strcpy(newPath, diskname); + + if(save_format == 0) + strcat(newPath, ".disk_save"); + else + strcat(newPath, ".ram"); + + return newPath; } const char *get_savestatefilename(void) @@ -371,88 +246,31 @@ void main_message(m64p_msg_level level, unsigned int corner, const char *format, buffer[2048]='\0'; va_end(ap); - /* send message to on-screen-display if enabled */ - if (ConfigGetParamBool(g_CoreConfig, "OnScreenDisplay")) - osd_new_message((enum osd_corner) corner, "%s", buffer); /* send message to front-end */ DebugMessage(level, "%s", buffer); } +extern retro_input_poll_t poll_cb; static void main_check_inputs(void) { #ifdef WITH_LIRC lircCheckInput(); #endif - SDL_PumpEvents(); + if(!(current_rdp_type == RDP_PLUGIN_GLIDEN64 && EnableThreadedRenderer)) + { + // Input Polling will be forced to early if Threaded GLideN64 + poll_cb(); + } } /********************************************************************************************************* * global functions, for adjusting the core emulator behavior */ - +extern void Config_LoadConfig(); int main_set_core_defaults(void) { - float fConfigParamsVersion; - int bUpgrade = 0; - - if (ConfigGetParameter(g_CoreConfig, "Version", M64TYPE_FLOAT, &fConfigParamsVersion, sizeof(float)) != M64ERR_SUCCESS) - { - DebugMessage(M64MSG_WARNING, "No version number in 'Core' config section. Setting defaults."); - ConfigDeleteSection("Core"); - ConfigOpenSection("Core", &g_CoreConfig); - } - else if (((int) fConfigParamsVersion) != ((int) CONFIG_PARAM_VERSION)) - { - DebugMessage(M64MSG_WARNING, "Incompatible version %.2f in 'Core' config section: current is %.2f. Setting defaults.", fConfigParamsVersion, (float) CONFIG_PARAM_VERSION); - ConfigDeleteSection("Core"); - ConfigOpenSection("Core", &g_CoreConfig); - } - else if ((CONFIG_PARAM_VERSION - fConfigParamsVersion) >= 0.0001f) - { - float fVersion = (float) CONFIG_PARAM_VERSION; - ConfigSetParameter(g_CoreConfig, "Version", M64TYPE_FLOAT, &fVersion); - DebugMessage(M64MSG_INFO, "Updating parameter set version in 'Core' config section to %.2f", fVersion); - bUpgrade = 1; - } - - /* parameters controlling the operation of the core */ - ConfigSetDefaultFloat(g_CoreConfig, "Version", (float) CONFIG_PARAM_VERSION, "Mupen64Plus Core config parameter set version number. Please don't change this version number."); - ConfigSetDefaultBool(g_CoreConfig, "OnScreenDisplay", 1, "Draw on-screen display if True, otherwise don't draw OSD"); -#if defined(DYNAREC) - ConfigSetDefaultInt(g_CoreConfig, "R4300Emulator", 2, "Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more"); -#else - ConfigSetDefaultInt(g_CoreConfig, "R4300Emulator", 1, "Use Pure Interpreter if 0, Cached Interpreter if 1, or Dynamic Recompiler if 2 or more"); -#endif - ConfigSetDefaultBool(g_CoreConfig, "NoCompiledJump", 0, "Disable compiled jump commands in dynamic recompiler (should be set to False) "); - ConfigSetDefaultBool(g_CoreConfig, "DisableExtraMem", 0, "Disable 4MB expansion RAM pack. May be necessary for some games"); - ConfigSetDefaultInt(g_CoreConfig, "CountPerOp", 0, "Force number of cycles per emulated instruction"); - ConfigSetDefaultInt(g_CoreConfig, "CountPerOpDenomPot", 0, "Reduce number of cycles per update by power of two when set greater than 0 (overclock)"); - ConfigSetDefaultBool(g_CoreConfig, "AutoStateSlotIncrement", 0, "Increment the save state slot after each save operation"); - ConfigSetDefaultInt(g_CoreConfig, "CurrentStateSlot", 0, "Save state slot (0-9) to use when saving/loading the emulator state"); - ConfigSetDefaultBool(g_CoreConfig, "EnableDebugger", 0, "Activate the R4300 debugger when ROM execution begins, if core was built with Debugger support"); - ConfigSetDefaultString(g_CoreConfig, "ScreenshotPath", "", "Path to directory where screenshots are saved. If this is blank, the default value of ${UserDataPath}/screenshot will be used"); - ConfigSetDefaultString(g_CoreConfig, "SaveStatePath", "", "Path to directory where emulator save states (snapshots) are saved. If this is blank, the default value of ${UserDataPath}/save will be used"); - ConfigSetDefaultString(g_CoreConfig, "SaveSRAMPath", "", "Path to directory where SRAM/EEPROM data (in-game saves) are stored. If this is blank, the default value of ${UserDataPath}/save will be used"); - ConfigSetDefaultString(g_CoreConfig, "SharedDataPath", "", "Path to a directory to search when looking for shared data files"); - ConfigSetDefaultBool(g_CoreConfig, "RandomizeInterrupt", 1, "Randomize PI/SI Interrupt Timing"); - ConfigSetDefaultInt(g_CoreConfig, "SiDmaDuration", -1, "Duration of SI DMA (-1: use per game settings)"); - ConfigSetDefaultString(g_CoreConfig, "GbCameraVideoCaptureBackend1", DEFAULT_VIDEO_CAPTURE_BACKEND, "Gameboy Camera Video Capture backend"); - ConfigSetDefaultInt(g_CoreConfig, "SaveDiskFormat", 1, "Disk Save Format (0: Full Disk Copy (*.ndr/*.d6r), 1: RAM Area Only (*.ram))"); - ConfigSetDefaultInt(g_CoreConfig, "SaveFilenameFormat", 1, "Save (SRAM/State) Filename Format (0: ROM Header Name, 1: Automatic (including partial MD5 hash))"); - - /* handle upgrades */ - if (bUpgrade) - { - if (fConfigParamsVersion < 1.01f) - { // added separate SaveSRAMPath parameter in v1.01 - const char *pccSaveStatePath = ConfigGetParamString(g_CoreConfig, "SaveStatePath"); - if (pccSaveStatePath != NULL) - ConfigSetParameter(g_CoreConfig, "SaveSRAMPath", M64TYPE_STRING, pccSaveStatePath); - } - } - - /* set config parameters for keyboard and joystick commands */ - return event_set_core_defaults(); + Config_LoadConfig(); + return 1; } void main_speeddown(int percent) @@ -463,7 +281,6 @@ void main_speeddown(int percent) if (l_SpeedFactor - percent > 10) /* 10% minimum speed */ { l_SpeedFactor -= percent; - main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "%s %d%%", "Playback speed:", l_SpeedFactor); audio.setSpeedFactor(l_SpeedFactor); StateChanged(M64CORE_SPEED_FACTOR, l_SpeedFactor); } @@ -477,7 +294,6 @@ void main_speedup(int percent) if (l_SpeedFactor + percent < 300) /* 300% maximum speed */ { l_SpeedFactor += percent; - main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "%s %d%%", "Playback speed:", l_SpeedFactor); audio.setSpeedFactor(l_SpeedFactor); StateChanged(M64CORE_SPEED_FACTOR, l_SpeedFactor); } @@ -497,7 +313,6 @@ static void main_speedset(int percent) main_set_fastforward(0); // set speed l_SpeedFactor = percent; - main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "%s %d%%", "Playback speed:", l_SpeedFactor); audio.setSpeedFactor(l_SpeedFactor); StateChanged(M64CORE_SPEED_FACTOR, l_SpeedFactor); } @@ -517,10 +332,6 @@ void main_set_fastforward(int enable) l_SpeedFactor = 250; audio.setSpeedFactor(l_SpeedFactor); StateChanged(M64CORE_SPEED_FACTOR, l_SpeedFactor); - // set fast-forward indicator - l_msgFF = osd_new_message(OSD_TOP_RIGHT, "Fast Forward"); - osd_message_set_static(l_msgFF); - osd_message_set_user_managed(l_msgFF); } else if (!enable && ff_state) { @@ -528,9 +339,6 @@ void main_set_fastforward(int enable) l_SpeedFactor = SavedSpeedFactor; audio.setSpeedFactor(l_SpeedFactor); StateChanged(M64CORE_SPEED_FACTOR, l_SpeedFactor); - // remove message - osd_delete_message(l_msgFF); - l_msgFF = NULL; } } @@ -579,22 +387,11 @@ void main_toggle_pause(void) if (g_rom_pause) { DebugMessage(M64MSG_STATUS, "Emulation continued."); - if(l_msgPause) - { - osd_delete_message(l_msgPause); - l_msgPause = NULL; - } StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING); } else { - if(l_msgPause) - osd_delete_message(l_msgPause); - DebugMessage(M64MSG_STATUS, "Emulation paused."); - l_msgPause = osd_new_message(OSD_MIDDLE_CENTER, "Paused"); - osd_message_set_static(l_msgPause); - osd_message_set_user_managed(l_msgPause); StateChanged(M64CORE_EMU_STATE, M64EMU_PAUSED); } @@ -611,27 +408,7 @@ void main_advance_one(void) static void main_draw_volume_osd(void) { - char msgString[64]; - const char *volString; - - // this calls into the audio plugin - volString = audio.volumeGetString(); - if (volString == NULL) - { - strcpy(msgString, "Volume Not Supported."); - } - else - { - sprintf(msgString, "%s: %s", "Volume", volString); - } - - // create a new message or update an existing one - if (l_msgVol != NULL) - osd_update_message(l_msgVol, "%s", msgString); - else { - l_msgVol = osd_new_message(OSD_MIDDLE_CENTER, "%s", msgString); - osd_message_set_user_managed(l_msgVol); - } + return; } /* this function could be called as a result of a keypress, joystick/button movement, @@ -692,12 +469,7 @@ m64p_error main_core_state_query(m64p_core_param param, int *rval) *rval = M64EMU_RUNNING; break; case M64CORE_VIDEO_MODE: - if (!VidExt_VideoRunning()) - *rval = M64VIDEO_NONE; - else if (VidExt_InFullscreenMode()) *rval = M64VIDEO_FULLSCREEN; - else - *rval = M64VIDEO_WINDOWED; break; case M64CORE_SAVESTATE_SLOT: *rval = savestates_get_slot(); @@ -770,19 +542,8 @@ m64p_error main_core_state_set(m64p_core_param param, int val) case M64CORE_VIDEO_MODE: if (!g_EmulatorRunning) return M64ERR_INVALID_STATE; - if (val == M64VIDEO_WINDOWED) - { - if (VidExt_InFullscreenMode()) - gfx.changeWindow(); - return M64ERR_SUCCESS; - } - else if (val == M64VIDEO_FULLSCREEN) - { - if (!VidExt_InFullscreenMode()) - gfx.changeWindow(); - return M64ERR_SUCCESS; - } - return M64ERR_INPUT_INVALID; + gfx.changeWindow(); + return M64ERR_SUCCESS; case M64CORE_SAVESTATE_SLOT: if (val < 0 || val > 9) return M64ERR_INPUT_INVALID; @@ -851,7 +612,6 @@ m64p_error main_volume_up(void) { int level = 0; audio.volumeUp(); - main_draw_volume_osd(); main_volume_get_level(&level); StateChanged(M64CORE_AUDIO_VOLUME, level); return M64ERR_SUCCESS; @@ -861,7 +621,6 @@ m64p_error main_volume_down(void) { int level = 0; audio.volumeDown(); - main_draw_volume_osd(); main_volume_get_level(&level); StateChanged(M64CORE_AUDIO_VOLUME, level); return M64ERR_SUCCESS; @@ -876,7 +635,6 @@ m64p_error main_volume_get_level(int *level) m64p_error main_volume_set_level(int level) { audio.volumeSetLevel(level); - main_draw_volume_osd(); level = audio.volumeGetLevel(); StateChanged(M64CORE_AUDIO_VOLUME, level); return M64ERR_SUCCESS; @@ -885,7 +643,6 @@ m64p_error main_volume_set_level(int level) m64p_error main_volume_mute(void) { audio.volumeMute(); - main_draw_volume_osd(); StateChanged(M64CORE_AUDIO_MUTE, main_volume_get_muted()); return M64ERR_SUCCESS; } @@ -913,32 +670,6 @@ m64p_error main_reset(int do_hard_reset) static void video_plugin_render_callback(int bScreenRedrawn) { -#ifdef M64P_OSD - int bOSD = ConfigGetParamBool(g_CoreConfig, "OnScreenDisplay"); -#endif /* M64P_OSD */ - - // if the flag is set to take a screenshot, then grab it now - if (l_TakeScreenshot != 0) - { - // if the OSD is enabled, and the screen has not been recently redrawn, then we cannot take a screenshot now because - // it contains the OSD text. Wait until the next redraw -#ifdef M64P_OSD - if (!bOSD || bScreenRedrawn) -#endif /* M64P_OSD */ - { - TakeScreenshot(l_TakeScreenshot - 1); // current frame number +1 is in l_TakeScreenshot - l_TakeScreenshot = 0; // reset flag - } - } - -#ifdef M64P_OSD - // if the OSD is enabled, then draw it now - if (bOSD) - { - osd_render(); - } -#endif /* M64P_OSD */ - // if the input plugin specified a render callback, call it now if(input.renderCallback) { @@ -961,6 +692,8 @@ void new_frame(void) } } +/* +#define SAMPLE_COUNT 1 static void apply_speed_limiter(void) { static unsigned long totalVIs = 0; @@ -968,13 +701,19 @@ static void apply_speed_limiter(void) static int lastSpeedFactor = 100; static unsigned int StartFPSTime = 0; static const double defaultSpeedFactor = 100.0; +#ifdef HAVE_LIBNX + unsigned int CurrentFPSTime = armTicksToNs(armGetSystemTick()) / 1000000; +#else unsigned int CurrentFPSTime = SDL_GetTicks(); +#endif // HAVE_LIBNX + static double sleepTimes[SAMPLE_COUNT]; + static unsigned int sleepTimesIndex = 0; // calculate frame duration based upon ROM setting (50/60hz) and mupen64plus speed adjustment const double VILimitMilliseconds = 1000.0 / g_dev.vi.expected_refresh_rate; const double SpeedFactorMultiple = defaultSpeedFactor/l_SpeedFactor; const double AdjustedLimit = VILimitMilliseconds * SpeedFactorMultiple; - + //if this is the first time or we are resuming from pause if(StartFPSTime == 0 || !resetOnce || lastSpeedFactor != l_SpeedFactor) { @@ -1009,19 +748,31 @@ static void apply_speed_limiter(void) resetOnce = 0; } - if (sleepTime < minSleepNeeded) { - totalVIs += (unsigned long)(minSleepNeeded/AdjustedLimit); + sleepTimes[sleepTimesIndex%SAMPLE_COUNT] = sleepTime; + sleepTimesIndex++; + + unsigned int elementsForAverage = sleepTimesIndex > SAMPLE_COUNT ? SAMPLE_COUNT : sleepTimesIndex; + + // compute the average sleepTime + double sum = 0; + unsigned int index; + for(index = 0; index < elementsForAverage; index++) + { + sum += sleepTimes[index]; } - if(l_MainSpeedLimit && sleepTime > 0 && sleepTime < maxSleepNeeded*SpeedFactorMultiple) - { - while(sleepTime >= 0) { - SDL_Delay((unsigned int) sleepTime); + double averageSleep = sum/elementsForAverage; - CurrentFPSTime = SDL_GetTicks(); - elapsedRealTime = CurrentFPSTime - StartFPSTime; - sleepTime = totalElapsedGameTime - elapsedRealTime; - } + int sleepMs = (int)averageSleep; + + if(sleepMs > 0 && l_MainSpeedLimit) + { + //DebugMessage(M64MSG_VERBOSE, " apply_speed_limiter(): Waiting %ims", sleepMs); +#ifdef HAVE_LIBNX + svcSleepThread(sleepMs * 1000000); +#else + SDL_Delay(sleepMs); +#endif // HAVE_LIBNX } @@ -1029,6 +780,7 @@ static void apply_speed_limiter(void) timed_section_end(TIMED_SECTION_IDLE); #endif } +*/ /* TODO: make a GameShark module and move that there */ static void gs_apply_cheats(struct cheat_ctx* ctx) @@ -1051,11 +803,8 @@ static void pause_loop(void) { if(g_rom_pause) { - osd_render(); // draw Paused message in case gfx.updateScreen didn't do it - VidExt_GL_SwapBuffers(); while(g_rom_pause) { - SDL_Delay(10); main_check_inputs(); } } @@ -1071,12 +820,11 @@ void new_vi(void) gs_apply_cheats(&g_cheat_ctx); - apply_speed_limiter(); + // apply_speed_limiter(); main_check_inputs(); - pause_loop(); - netplay_check_sync(&g_dev.r4300.cp0); + retro_return(); } static void main_switch_pak(int control_id) @@ -1115,68 +863,75 @@ void main_switch_plugin_pak(int control_id) main_switch_pak(control_id); } -static void open_mpk_file(struct file_storage* fstorage) +void save_storage_file_libretro(void* storage) { - unsigned int i; - int ret = open_file_storage(fstorage, GAME_CONTROLLERS_COUNT*MEMPAK_SIZE, get_mempaks_path()); +} - if (ret == (int)file_open_error) { - /* if file doesn't exists provide default content */ - for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) { - - /* Generate a random serial ID */ - uint32_t serial[6]; - size_t k; - for (k = 0; k < 6; ++k) { - serial[k] = xoshiro256pp_next(&l_mpk_idgen); - } - - format_mempak(fstorage->data + i * MEMPAK_SIZE, - serial, - DEFAULT_MEMPAK_DEVICEID, - DEFAULT_MEMPAK_BANKS, - DEFAULT_MEMPAK_VERSION); - } +static void open_mpk_file(struct file_storage* storage) +{ + if (!netplay_is_init()) + { + storage->data = saved_memory.mempack; + storage->size = MEMPAK_SIZE * 4; + } + else + { + // First we save them with what we have + storage->data = saved_memory.mempack; + storage->size = MEMPAK_SIZE * 4; + // If player 1 we send, otherwise we recieve + netplay_read_storage("MPK.bin", storage->data, storage->size); } } -static void open_fla_file(struct file_storage* fstorage) +static void open_fla_file(struct file_storage* storage) { - int ret = open_file_storage(fstorage, FLASHRAM_SIZE, get_flashram_path()); - - if (ret == (int)file_open_error) { - /* if file doesn't exists provide default content */ - format_flashram(fstorage->data); + if (!netplay_is_init()) + { + storage->data = saved_memory.flashram; + storage->size = FLASHRAM_SIZE; + } + else + { + // First we save them with what we have + storage->data = saved_memory.flashram; + storage->size = FLASHRAM_SIZE; + // If player 1 we send, otherwise we recieve + netplay_read_storage("FLA.bin", storage->data, storage->size); } } -static void open_sra_file(struct file_storage* fstorage) +static void open_sra_file(struct file_storage* storage) { - int ret = open_file_storage(fstorage, SRAM_SIZE, get_sram_path()); - - if (ret == (int)file_open_error) { - /* if file doesn't exists provide default content */ - format_sram(fstorage->data); + if (!netplay_is_init()) + { + storage->data = saved_memory.sram; + storage->size = SRAM_SIZE; + } + else + { + // First we save them with what we have + storage->data = saved_memory.sram; + storage->size = SRAM_SIZE; + // If player 1 we send, otherwise we recieve + netplay_read_storage("SRA.bin", storage->data, storage->size); } } -static void open_eep_file(struct file_storage* fstorage) +static void open_eep_file(struct file_storage* storage) { - /* Note: EEP files are all EEPROM_MAX_SIZE bytes long, - * whatever the real EEPROM size is. - */ - enum { EEPROM_MAX_SIZE = 0x800 }; - - int ret = open_file_storage(fstorage, EEPROM_MAX_SIZE, get_eeprom_path()); - - if (ret == (int)file_open_error) { - /* if file doesn't exists provide default content */ - format_eeprom(fstorage->data, EEPROM_MAX_SIZE); + if (!netplay_is_init()) + { + storage->data = saved_memory.eeprom; + storage->size = EEPROM_MAX_SIZE; } - - /* Truncate to 4k bit if necessary */ - if (ROM_SETTINGS.savetype != SAVETYPE_EEPROM_16K) { - fstorage->size = 0x200; + else + { + // First we save them with what we have + storage->data = saved_memory.eeprom; + storage->size = EEPROM_MAX_SIZE; + // If player 1 we send, otherwise we recieve + netplay_read_storage("EEP.bin", storage->data, storage->size); } } @@ -1193,6 +948,25 @@ static void load_dd_rom(uint8_t* rom, size_t* rom_size, uint8_t* disk_region) ? NULL : g_media_loader.get_dd_rom(g_media_loader.cb_data); + char* sys_pathname; + environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &sys_pathname); + char* pathname = (char*)malloc(2048); + strncpy(pathname, sys_pathname, 2048 - 1); + if (pathname[(strlen(pathname)-1)] != '/' && pathname[(strlen(pathname)-1)] != '\\') + strcat(pathname, PATH_DEFAULT_SLASH()); + strcat(pathname, "Mupen64plus"); + strcat(pathname, PATH_DEFAULT_SLASH()); + strcat(pathname, "IPL.n64"); + + if(retro_dd_path_img) + { + dd_ipl_rom_filename = pathname; + } + else + { + dd_ipl_rom_filename = NULL; + } + if ((dd_ipl_rom_filename == NULL) || (strlen(dd_ipl_rom_filename) == 0)) { goto no_dd; } @@ -1247,13 +1021,18 @@ no_dd: *rom_size = 0; } +extern char* retro_dd_path_img; +extern char* retro_dd_path_rom; static int load_dd_disk(struct dd_disk* dd_disk, const struct storage_backend_interface** dd_idisk) { /* ask the core loader for DD disk filename */ char* dd_disk_filename = (g_media_loader.get_dd_disk == NULL) - ? NULL + ? (retro_dd_path_img ? strdup(retro_dd_path_img) : NULL) : g_media_loader.get_dd_disk(g_media_loader.cb_data); + //printf("Load DD disk %s\n", dd_disk_filename); + //fflush(stdout); + /* handle the no disk case */ if (dd_disk_filename == NULL || strlen(dd_disk_filename) == 0) { goto no_disk; @@ -1276,7 +1055,7 @@ static int load_dd_disk(struct dd_disk* dd_disk, const struct storage_backend_in } /* Determine disk save format */ - int save_format = ConfigGetParamInt(g_CoreConfig, "SaveDiskFormat"); + int save_format = 0; //ConfigGetParamInt(g_CoreConfig, "SaveDiskFormat"); /* MAME disks only support full disk save */ if (dd_size == MAME_FORMAT_DUMP_SIZE && save_format != 0) { DebugMessage(M64MSG_WARNING, "MAME disks only support full disk save format, switching to full disk format !"); @@ -1284,7 +1063,7 @@ static int load_dd_disk(struct dd_disk* dd_disk, const struct storage_backend_in } /* Determine save file name */ - char* save_filename = get_dd_disk_save_path(namefrompath(dd_disk_filename), save_format); + char* save_filename = get_dd_disk_save_path(dd_disk_filename, save_format); if (save_filename == NULL) { DebugMessage(M64MSG_ERROR, "Failed to get DD save path, DD will be read-only."); save_format = -1; @@ -1454,7 +1233,7 @@ static void init_gb_rom(void* opaque, void** storage, const struct storage_backe /* Ask the core loader for rom filename */ char* rom_filename = (g_media_loader.get_gb_cart_rom == NULL) - ? NULL + ? (retro_transferpak_rom_path ? strdup(retro_transferpak_rom_path) : NULL) : g_media_loader.get_gb_cart_rom(g_media_loader.cb_data, data->control_id); /* Handle the no cart case */ @@ -1464,11 +1243,11 @@ static void init_gb_rom(void* opaque, void** storage, const struct storage_backe /* Open ROM file */ if (open_rom_file_storage(&data->rom_fstorage, rom_filename) != file_ok) { - DebugMessage(M64MSG_ERROR, "Failed to load ROM file: %s", rom_filename); + log_cb(RETRO_LOG_ERROR, "Failed to load ROM file: %s\n", rom_filename); goto no_cart; } - DebugMessage(M64MSG_INFO, "GB Loader ROM: %s - %zu", + log_cb(RETRO_LOG_INFO, "GB Loader ROM: %s - %zu\n", data->rom_fstorage.filename, data->rom_fstorage.size); @@ -1498,7 +1277,7 @@ static void init_gb_ram(void* opaque, size_t ram_size, void** storage, const str /* Ask the core loader for ram filename */ char* ram_filename = (g_media_loader.get_gb_cart_ram == NULL) - ? NULL + ? (retro_transferpak_ram_path ? strdup(retro_transferpak_ram_path) : NULL) : g_media_loader.get_gb_cart_ram(g_media_loader.cb_data, data->control_id); /* Handle the no RAM case @@ -1514,13 +1293,13 @@ static void init_gb_ram(void* opaque, size_t ram_size, void** storage, const str int err = open_file_storage(&data->ram_fstorage, ram_size, ram_filename); if (err == file_open_error) { memset(data->ram_fstorage.data, 0, data->ram_fstorage.size); - DebugMessage(M64MSG_INFO, "Providing default RAM content"); + log_cb(RETRO_LOG_INFO, "Providing default RAM content\n"); } else if (err == file_read_error) { - DebugMessage(M64MSG_WARNING, "Size mismatch between expected RAM size and effective file size"); + log_cb(RETRO_LOG_WARN, "Size mismatch between expected RAM size and effective file size\n"); } - DebugMessage(M64MSG_INFO, "GB Loader RAM: %s - %zu", + log_cb(RETRO_LOG_INFO, "GB Loader RAM: %s - %zu\n", data->ram_fstorage.filename, data->ram_fstorage.size); @@ -1563,10 +1342,10 @@ void main_change_gb_cart(int control_id) if (tpk->gb_cart != NULL) { const uint8_t* rom_data = gb_cart->irom_storage->data(gb_cart->rom_storage); - DebugMessage(M64MSG_INFO, "Inserting GB cart %s into transferpak %u", rom_data + 0x134, control_id); + log_cb(RETRO_LOG_INFO, "Inserting GB cart %s into transferpak %u\n", rom_data + 0x134, control_id); } else { - DebugMessage(M64MSG_INFO, "Removing GB cart from transferpak %u", control_id); + log_cb(RETRO_LOG_WARN, "Removing GB cart from transferpak %u\n", control_id); } } @@ -1574,12 +1353,17 @@ void main_change_gb_cart(int control_id) /********************************************************************************************************* * emulation thread - runs the core */ +extern gfx_plugin_functions gfx_gln64; +extern rsp_plugin_functions rsp_hle; +extern input_plugin_functions dummy_input; +extern audio_plugin_functions dummy_audio; +unsigned int r4300_emumode; +size_t rdram_size; m64p_error main_run(void) { size_t i, k; - size_t rdram_size; uint32_t count_per_op; uint32_t count_per_op_denom_pot; uint32_t emumode; @@ -1593,6 +1377,7 @@ m64p_error main_run(void) size_t dd_rom_size; struct dd_disk dd_disk; m64p_error failure_rval; + struct audio_out_backend_interface audio_out_backend_libretro; int control_ids[GAME_CONTROLLERS_COUNT]; struct controller_input_compat cin_compats[GAME_CONTROLLERS_COUNT]; @@ -1605,6 +1390,13 @@ m64p_error main_run(void) /* XXX: select type of flashram from db */ uint32_t flashram_type = MX29L1100_ID; + + emumode = r4300_emumode; + randomize_interrupt = 0; // We don't want this right now + no_compiled_jump = 0; + count_per_op = CountPerOp; + count_per_op_denom_pot = CountPerOpDenomPot; + disable_extra_mem = ROM_SETTINGS.disableextramem; uint16_t eeprom_type = JDT_NONE; switch (ROM_SETTINGS.savetype) { @@ -1620,22 +1412,14 @@ m64p_error main_run(void) uint64_t mpk_seed = !netplay_is_init() ? (uint64_t)time(NULL) : 0; l_mpk_idgen = xoshiro256pp_seed(mpk_seed); - /* take the r4300 emulator mode from the config file at this point and cache it in a global variable */ - emumode = ConfigGetParamInt(g_CoreConfig, "R4300Emulator"); - - /* set some other core parameters based on the config file values */ - savestates_set_autoinc_slot(ConfigGetParamBool(g_CoreConfig, "AutoStateSlotIncrement")); - savestates_select_slot(ConfigGetParamInt(g_CoreConfig, "CurrentStateSlot")); no_compiled_jump = ConfigGetParamBool(g_CoreConfig, "NoCompiledJump"); //We disable any randomness for netplay - randomize_interrupt = !netplay_is_init() ? ConfigGetParamBool(g_CoreConfig, "RandomizeInterrupt") : 0; - count_per_op = ConfigGetParamInt(g_CoreConfig, "CountPerOp"); - count_per_op_denom_pot = ConfigGetParamInt(g_CoreConfig, "CountPerOpDenomPot"); + //randomize_interrupt = !netplay_is_init() ? ConfigGetParamBool(g_CoreConfig, "RandomizeInterrupt") : 0; if (ROM_SETTINGS.disableextramem) disable_extra_mem = ROM_SETTINGS.disableextramem; else - disable_extra_mem = ConfigGetParamInt(g_CoreConfig, "DisableExtraMem"); + disable_extra_mem = ForceDisableExtraMem; if (count_per_op <= 0) count_per_op = ROM_SETTINGS.countperop; @@ -1643,9 +1427,7 @@ m64p_error main_run(void) if (count_per_op_denom_pot > 20) count_per_op_denom_pot = 20; - si_dma_duration = ConfigGetParamInt(g_CoreConfig, "SiDmaDuration"); - if (si_dma_duration < 0) - si_dma_duration = ROM_SETTINGS.sidmaduration; + si_dma_duration = ROM_SETTINGS.sidmaduration; //During netplay, player 1 is the source of truth for these settings netplay_sync_settings(&count_per_op, &count_per_op_denom_pot, &disable_extra_mem, &si_dma_duration, &emumode, &no_compiled_jump); @@ -1663,6 +1445,11 @@ m64p_error main_run(void) } #endif + /* setup backends */ + extern void set_audio_format_via_libretro(void* user_data, unsigned int frequency); + extern void push_audio_samples_via_libretro(void* user_data, const void* buffer, size_t size); + audio_out_backend_libretro = (struct audio_out_backend_interface){ set_audio_format_via_libretro, push_audio_samples_via_libretro }; + /* Fill-in l_pak_type_idx and l_ipaks according to game compatibility */ k = 0; if (ROM_SETTINGS.biopak) { @@ -1698,13 +1485,6 @@ m64p_error main_run(void) l_pak_type_idx[PLUGIN_TRANSFER_PAK] = k; } - /* init GbCamera backend specified in the configuration file */ - init_video_capture_backend(&igbcam_backend, &gbcam_backend, - g_CoreConfig, "GbCameraVideoCaptureBackend1"); - - /* open GB cam video device */ - igbcam_backend->open(gbcam_backend, M64282FP_SENSOR_W, M64282FP_SENSOR_H); - /* open storage files, provide default content if not present */ open_mpk_file(&mpk); open_eep_file(&eep); @@ -1826,7 +1606,7 @@ m64p_error main_run(void) mpk_storages[i].offset = i * MEMPAK_SIZE; mpk_storages[i].filename = (void*)&mpk; /* OK for isubfile_storage */ - init_mempak(&g_dev.mempaks[i], &mpk_storages[i], &g_isubfile_storage); + init_mempak(&g_dev.mempaks[i], &mpk_storages[i], &g_ifile_storage_ro); l_paks[i][k] = &g_dev.mempaks[i]; if (Controls[i].Plugin == PLUGIN_MEMPAK) { @@ -1862,7 +1642,7 @@ m64p_error main_run(void) } /* enable GB cart switch */ - cin_compats[i].gb_cart_switch_enabled = 1; + // cin_compats[i].gb_cart_switch_enabled = 1; } /* No Pak */ else { @@ -1892,6 +1672,7 @@ m64p_error main_run(void) } } } + for (i = GAME_CONTROLLERS_COUNT; i < PIF_CHANNELS_COUNT; ++i) { joybus_devices[i] = &g_dev.cart; ijoybus_devices[i] = &g_ijoybus_device_cart; @@ -1899,13 +1680,13 @@ m64p_error main_run(void) init_device(&g_dev, g_mem_base, - emumode, + r4300_emumode, count_per_op, count_per_op_denom_pot, no_compiled_jump, randomize_interrupt, g_start_address, - &g_dev.ai, &g_iaudio_out_backend_plugin_compat, ((float)ROM_SETTINGS.aidmamodifier / 100.0), + &g_dev.ai, &audio_out_backend_libretro, ((float)ROM_SETTINGS.aidmamodifier / 100.0), si_dma_duration, rdram_size, joybus_devices, ijoybus_devices, @@ -1913,10 +1694,10 @@ m64p_error main_run(void) NULL, &g_iclock_ctime_plus_delta, g_rom_size, eeprom_type, - &eep, &g_ifile_storage, + &eep, &g_ifile_storage_ro, flashram_type, - &fla, &g_ifile_storage, - &sra, &g_ifile_storage, + &fla, &g_ifile_storage_ro, + &sra, &g_ifile_storage_ro, NULL, dd_rtc_iclock, dd_rom_size, &dd_disk, dd_idisk); @@ -1936,52 +1717,17 @@ m64p_error main_run(void) goto on_input_open_failure; } - /* set up the SDL key repeat and event filter to catch keyboard/joystick commands for the core */ - event_initialize(); - - /* initialize frame counter */ - l_CurrentFrame = 0; - - /* initialize the on-screen display */ - if (ConfigGetParamBool(g_CoreConfig, "OnScreenDisplay")) - { - // init on-screen display - int width = 640, height = 480; - gfx.readScreen(NULL, &width, &height, 0); // read screen to get width and height - osd_init(width, height); - } - // setup rendering callback from video plugin to the core, for screenshots and On-Screen-Display gfx.setRenderingCallback(video_plugin_render_callback); -#ifdef WITH_LIRC - lircStart(); -#endif // WITH_LIRC - -#ifdef DBG - if (ConfigGetParamBool(g_CoreConfig, "EnableDebugger")) - init_debugger(); -#endif - - /* Startup message on the OSD */ - osd_new_message(OSD_MIDDLE_CENTER, "Mupen64Plus Started..."); - g_EmulatorRunning = 1; StateChanged(M64CORE_EMU_STATE, M64EMU_RUNNING); poweron_device(&g_dev); pif_bootrom_hle_execute(&g_dev.r4300); + run_device(&g_dev); - /* now begin to shut down */ -#ifdef WITH_LIRC - lircStop(); -#endif // WITH_LIRC - -#ifdef DBG - if (g_DebuggerActive) - destroy_debugger(); -#endif /* release gb_carts */ for(i = 0; i < GAME_CONTROLLERS_COUNT; ++i) { if (!Controls[i].RawData && (Controls[i].Type == CONT_TYPE_STANDARD) && g_dev.gb_carts[i].read_gb_cart != NULL) { @@ -1990,6 +1736,7 @@ m64p_error main_run(void) } } +#if 0 igbcam_backend->close(gbcam_backend); igbcam_backend->release(gbcam_backend); @@ -1997,16 +1744,13 @@ m64p_error main_run(void) close_file_storage(&fla); close_file_storage(&eep); close_file_storage(&mpk); - close_dd_disk(&dd_disk); +#endif /* reset pif */ close_pif(); + close_dd_disk(&dd_disk); - if (ConfigGetParamBool(g_CoreConfig, "OnScreenDisplay")) - { - osd_exit(); - } - + /* Emulation stopped */ rsp.romClosed(); input.romClosed(); audio.romClosed(); @@ -2016,6 +1760,18 @@ m64p_error main_run(void) g_EmulatorRunning = 0; StateChanged(M64CORE_EMU_STATE, M64EMU_STOPPED); + /** + * Actually never returns. + * Jump back to frontend for deinit + */ + extern cothread_t retro_thread; + + // For GLN64 Threaded GL we just sanely return, exit sync is handled elsewhere + if(!(current_rdp_type == RDP_PLUGIN_GLIDEN64 && EnableThreadedRenderer)) + { + co_switch(retro_thread); + } + return M64ERR_SUCCESS; on_disk_failure: @@ -2035,6 +1791,7 @@ on_gfx_open_failure: } } +#if 0 igbcam_backend->close(gbcam_backend); igbcam_backend->release(gbcam_backend); @@ -2044,6 +1801,7 @@ on_gfx_open_failure: close_file_storage(&eep); close_file_storage(&mpk); close_dd_disk(&dd_disk); +#endif /* reset pif */ close_pif(); @@ -2059,21 +1817,7 @@ void main_stop(void) return; DebugMessage(M64MSG_STATUS, "Stopping emulation."); - if(l_msgPause) - { - osd_delete_message(l_msgPause); - l_msgPause = NULL; - } - if(l_msgFF) - { - osd_delete_message(l_msgFF); - l_msgFF = NULL; - } - if(l_msgVol) - { - osd_delete_message(l_msgVol); - l_msgVol = NULL; - } + if (g_rom_pause) { g_rom_pause = 0; @@ -2081,13 +1825,6 @@ void main_stop(void) } stop_device(&g_dev); - -#ifdef DBG - if(g_DebuggerActive) - { - debugger_step(); - } -#endif } m64p_error open_pif(const unsigned char* pifimage, unsigned int size) diff --git a/src/main/netplay.c b/src/main/netplay.c index 5ec92992..7d35a189 100644 --- a/src/main/netplay.c +++ b/src/main/netplay.c @@ -29,11 +29,20 @@ #include "backends/plugins_compat/plugins_compat.h" #include "netplay.h" -#include +#include + +#include #if !defined(WIN32) -#include +#include #endif +#ifndef HAVE_LIBNX +#include +#else +#include +#include +#endif // HAVE_LIBNX + static int l_canFF; static int l_netplay_controller; static int l_netplay_control[4]; @@ -84,14 +93,14 @@ m64p_error netplay_start(const char* host, int port) { if (SDLNet_Init() < 0) { - DebugMessage(M64MSG_ERROR, "Netplay: Could not initialize SDL Net library"); + log_cb(RETRO_LOG_INFO, "Netplay: Could not initialize SDL Net library\n"); return M64ERR_SYSTEM_FAIL; } l_udpSocket = SDLNet_UDP_Open(0); if (l_udpSocket == NULL) { - DebugMessage(M64MSG_ERROR, "Netplay: UDP socket creation failed"); + log_cb(RETRO_LOG_INFO, "Netplay: UDP socket creation failed\n"); return M64ERR_SYSTEM_FAIL; } @@ -107,7 +116,7 @@ m64p_error netplay_start(const char* host, int port) l_udpChannel = SDLNet_UDP_Bind(l_udpSocket, -1, &dest); if (l_udpChannel < 0) { - DebugMessage(M64MSG_ERROR, "Netplay: could not bind to UDP socket"); + log_cb(RETRO_LOG_INFO, "Netplay: could not bind to UDP socket\n"); SDLNet_UDP_Close(l_udpSocket); l_udpSocket = NULL; return M64ERR_SYSTEM_FAIL; @@ -116,7 +125,7 @@ m64p_error netplay_start(const char* host, int port) l_tcpSocket = SDLNet_TCP_Open(&dest); if (l_tcpSocket == NULL) { - DebugMessage(M64MSG_ERROR, "Netplay: could not bind to TCP socket"); + log_cb(RETRO_LOG_INFO, "Netplay: could not bind to TCP socket\n"); SDLNet_UDP_Close(l_udpSocket); l_udpSocket = NULL; return M64ERR_SYSTEM_FAIL; @@ -297,11 +306,11 @@ static void netplay_process() if (current_status != l_status) { if (((current_status & 0x1) ^ (l_status & 0x1)) != 0) - DebugMessage(M64MSG_ERROR, "Netplay: players have de-synced at VI %u", l_vi_counter); + log_cb(RETRO_LOG_INFO, "Netplay: players have de-synced at VI %u\n", l_vi_counter); for (int dis = 1; dis < 5; ++dis) { if (((current_status & (0x1 << dis)) ^ (l_status & (0x1 << dis))) != 0) - DebugMessage(M64MSG_ERROR, "Netplay: player %u has disconnected", dis); + log_cb(RETRO_LOG_INFO, "Netplay: player %u has disconnected\n", dis); } l_status = current_status; } @@ -334,7 +343,7 @@ static void netplay_process() } break; default: - DebugMessage(M64MSG_ERROR, "Netplay: received unknown message from server"); + log_cb(RETRO_LOG_INFO, "Netplay: received unknown message from server\n"); break; } } @@ -380,6 +389,8 @@ static void netplay_delete_event(struct netplay_event* current, uint8_t control_ static uint32_t netplay_get_input(uint8_t control_id) { uint32_t keys; + struct retro_fastforwarding_override ff_override; + netplay_process(); netplay_request_input(control_id); @@ -390,10 +401,23 @@ static uint32_t netplay_get_input(uint8_t control_id) { l_canFF = 1; main_core_state_set(M64CORE_SPEED_LIMITER, 0); + + // Enable Fast Forward + ff_override.fastforward = true; + // Prevent user toggling Fast Forward + ff_override.inhibit_toggle = true; + environ_cb(RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE, &ff_override); } else { main_core_state_set(M64CORE_SPEED_LIMITER, 1); + + // Disable Fast Forward + ff_override.fastforward = false; + // Prevent user toggling Fast Forward + ff_override.inhibit_toggle = true; + environ_cb(RETRO_ENVIRONMENT_SET_FASTFORWARDING_OVERRIDE, &ff_override); + l_canFF = 0; } @@ -411,7 +435,7 @@ static uint32_t netplay_get_input(uint8_t control_id) } else { - DebugMessage(M64MSG_ERROR, "Netplay: lost connection to server"); + log_cb(RETRO_LOG_INFO, "Netplay: lost connection to server\n"); main_core_state_set(M64CORE_EMU_STATE, M64EMU_STOPPED); keys = 0; } @@ -494,9 +518,10 @@ file_status_t netplay_read_storage(const char *filename, void *data, size_t size memcpy(&output_data[buffer_pos], file_extension, strlen(file_extension) + 1); buffer_pos += strlen(file_extension) + 1; - ret = read_from_file(filename, data, size); - if (ret == file_open_error) - memset(data, 0, size); //all zeros means there is no save file + // Not wanted for libretro + //ret = read_from_file(filename, data, size); + //if (ret == file_open_error) + // memset(data, 0, size); //all zeros means there is no save file SDLNet_Write32((int32_t)size, &output_data[buffer_pos]); //file data size buffer_pos += 4; memcpy(&output_data[buffer_pos], data, size); //file data diff --git a/src/main/netplay.h b/src/main/netplay.h index 088d4a39..92b1681e 100644 --- a/src/main/netplay.h +++ b/src/main/netplay.h @@ -93,7 +93,7 @@ static osal_inline int netplay_get_controller(uint8_t player) static osal_inline file_status_t netplay_read_storage(const char *filename, void *data, size_t size) { - return 0; + return file_open_error; } static osal_inline void netplay_sync_settings(uint32_t *count_per_op, uint32_t *count_per_op_denom_pot, uint32_t *disable_extra_mem, int32_t *si_dma_duration, uint32_t *emumode, int32_t *no_compiled_jump) diff --git a/src/main/savestates.c b/src/main/savestates.c index 86adbb7f..ef318709 100644 --- a/src/main/savestates.c +++ b/src/main/savestates.c @@ -22,8 +22,12 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#ifdef USE_SDL #include #include +#else +#include +#endif #include #include #include @@ -31,8 +35,6 @@ #include #include #include -#include -#include #define M64P_CORE_PROTOTYPES 1 #include "api/callbacks.h" @@ -51,6 +53,9 @@ #include "util.h" #include "workqueue.h" +#include +#include + enum { GB_CART_FINGERPRINT_SIZE = 0x1c }; enum { GB_CART_FINGERPRINT_OFFSET = 0x134 }; @@ -62,18 +67,28 @@ static const unsigned char pj64_magic[4] = { 0xC8, 0xA6, 0xD8, 0x23 }; static savestates_job job = savestates_job_nothing; static savestates_type type = savestates_type_unknown; + +// Libretro will re-use fname for the ptr +// This avoids ifdef shenanigans static char *fname = NULL; static unsigned int slot = 0; static int autoinc_save_slot = 0; +#ifdef USE_SDL static SDL_mutex *savestates_lock; +#else +static pthread_mutex_t savestates_lock; +#endif struct savestate_work { char *filepath; char *data; size_t size; struct work_struct work; +#ifdef __LIBRETRO__ + void *mempointer; +#endif }; /* Returns the malloc'd full path of the currently selected savestate. */ @@ -152,16 +167,23 @@ savestates_job savestates_get_job(void) void savestates_set_job(savestates_job j, savestates_type t, const char *fn) { +#ifndef __LIBRETRO__ if (fname != NULL) { free(fname); fname = NULL; } - +#endif // __LIBRETRO__ job = j; type = t; +#ifndef __LIBRETRO__ if (fn != NULL) fname = strdup(fn); +#else + pthread_mutex_lock(&savestates_lock); + fname = (char*)fn; + pthread_mutex_unlock(&savestates_lock); +#endif // __LIBRETRO__ } static void savestates_clear_job(void) @@ -184,10 +206,13 @@ static void savestates_clear_job(void) #define PUTDATA(buff, type, value) \ do { type x = value; PUTARRAY(&x, buff, type, 1); } while(0) -static int savestates_load_m64p(struct device* dev, char *filepath) +#ifndef __LIBRETRO__ +int savestates_load_m64p(struct device* dev, char *filepath) +#else +int savestates_load_m64p(struct device* dev, const void *data) +#endif { unsigned char header[44]; - gzFile f; unsigned int version; int i; uint32_t FCR31; @@ -200,13 +225,21 @@ static int savestates_load_m64p(struct device* dev, char *filepath) uint32_t* cp0_regs = r4300_cp0_regs(&dev->r4300.cp0); +#ifdef USE_SDL SDL_LockMutex(savestates_lock); +#else + pthread_mutex_lock(&savestates_lock); +#endif +#ifndef __LIBRETRO__ + gzFile f; f = gzopen(filepath, "rb"); if(f==NULL) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not open state file: %s", filepath); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#endif return 0; } @@ -215,7 +248,9 @@ static int savestates_load_m64p(struct device* dev, char *filepath) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read header from state file %s", filepath); gzclose(f); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#endif return 0; } curr = header; @@ -224,9 +259,21 @@ static int savestates_load_m64p(struct device* dev, char *filepath) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State file: %s is not a valid Mupen64plus savestate.", filepath); gzclose(f); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#endif return 0; } +#else + memcpy(header, data, 44); + curr = header; + if(strncmp((char *)curr, savestate_magic, 8)!=0) + { + main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Savestate is not a valid Mupen64plus savestate."); + return 0; + } +#endif + curr += 8; version = *curr++; @@ -236,16 +283,28 @@ static int savestates_load_m64p(struct device* dev, char *filepath) if((version >> 16) != (savestate_latest_version >> 16)) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State version (%08x) isn't compatible. Please update Mupen64Plus.", version); +#ifndef __LIBRETRO__ gzclose(f); +#endif +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#else + pthread_mutex_unlock(&savestates_lock); +#endif return 0; } if(memcmp((char *)curr, ROM_SETTINGS.MD5, 32)) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State ROM MD5 does not match current ROM."); +#ifndef __LIBRETRO__ gzclose(f); +#endif +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#else + pthread_mutex_unlock(&savestates_lock); +#endif return 0; } curr += 32; @@ -256,37 +315,59 @@ static int savestates_load_m64p(struct device* dev, char *filepath) if (savestateData == NULL) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Insufficient memory to load state."); +#ifndef __LIBRETRO__ gzclose(f); +#endif +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#else + pthread_mutex_unlock(&savestates_lock); +#endif return 0; } if (version == 0x00010000) /* original savestate version */ { - if (gzread(f, savestateData, savestateSize) != (int)savestateSize || +#ifndef __LIBRETRO__ + if (gzread(f, savestateData, savestateSize) != savestateSize || (gzread(f, queue, sizeof(queue)) % 4) != 0) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read Mupen64Plus savestate 1.0 data from %s", filepath); free(savestateData); gzclose(f); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#endif return 0; } +#else + memcpy(savestateData, data + 44, savestateSize); + memcpy(queue, data + 44 + savestateSize, sizeof(queue)); +#endif } else if (version == 0x00010100) // saves entire eventqueue plus 4-byte using_tlb flags { - if (gzread(f, savestateData, savestateSize) != (int)savestateSize || +#ifndef __LIBRETRO__ + if (gzread(f, savestateData, savestateSize) != savestateSize || gzread(f, queue, sizeof(queue)) != sizeof(queue) || gzread(f, using_tlb_data, sizeof(using_tlb_data)) != sizeof(using_tlb_data)) { main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read Mupen64Plus savestate 1.1 data from %s", filepath); free(savestateData); gzclose(f); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#endif return 0; } +#else + memcpy(savestateData, data + 44, savestateSize); + memcpy(queue, data + 44 + savestateSize, sizeof(queue)); + memcpy(using_tlb_data, data + 44 + savestateSize + sizeof(queue), sizeof(using_tlb_data)); +#endif } else // version >= 0x00010200 saves entire eventqueue, 4-byte using_tlb flags and extra state { +#ifndef __LIBRETRO__ if (gzread(f, savestateData, savestateSize) != (int)savestateSize || gzread(f, queue, sizeof(queue)) != sizeof(queue) || gzread(f, using_tlb_data, sizeof(using_tlb_data)) != sizeof(using_tlb_data) || @@ -295,13 +376,27 @@ static int savestates_load_m64p(struct device* dev, char *filepath) main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Could not read Mupen64Plus savestate 1.2+ data from %s", filepath); free(savestateData); gzclose(f); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#endif return 0; } +#else + memcpy(savestateData, data + 44, savestateSize); + memcpy(queue, data + 44 + savestateSize, sizeof(queue)); + memcpy(using_tlb_data, data + 44 + savestateSize + sizeof(queue), sizeof(using_tlb_data)); + memcpy(data_0001_0200, data + 44 + savestateSize + sizeof(queue) + sizeof(using_tlb_data), sizeof(data_0001_0200)); +#endif } +#ifndef __LIBRETRO__ gzclose(f); +#endif +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#else + pthread_mutex_unlock(&savestates_lock); +#endif // Parse savestate dev->rdram.regs[0][RDRAM_CONFIG_REG] = GETDATA(curr, uint32_t); @@ -954,7 +1049,10 @@ static int savestates_load_m64p(struct device* dev, char *filepath) *r4300_cp0_last_addr(&dev->r4300.cp0) = *r4300_pc(&dev->r4300); free(savestateData); + +#ifndef __LIBRETRO__ main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "State loaded from: %s", namefrompath(filepath)); +#endif return 1; } @@ -1399,9 +1497,12 @@ static savestates_type savestates_detect_type(char *filepath) int savestates_load(void) { + int ret = 0; + struct device* dev = &g_dev; + +#ifndef __LIBRETRO__ FILE *fPtr = NULL; char *filepath = NULL; - int ret = 0; if (fname == NULL) // For slots, autodetect the savestate type { @@ -1457,8 +1558,6 @@ int savestates_load(void) if (filepath != NULL) { - struct device* dev = &g_dev; - switch (type) { case savestates_type_m64p: ret = savestates_load_m64p(dev, filepath); break; @@ -1469,6 +1568,15 @@ int savestates_load(void) free(filepath); filepath = NULL; } +#else + if(fname) + { + ret = savestates_load_m64p(dev, fname); + fname = NULL; + } else { + ret = 0; + } +#endif // __LIBRETRO__ // deliver callback to indicate completion of state loading operation StateChanged(M64CORE_STATE_LOADCOMPLETE, ret); @@ -1480,13 +1588,18 @@ int savestates_load(void) static void savestates_save_m64p_work(struct work_struct *work) { - gzFile f; - int gzres; struct savestate_work *save = container_of(work, struct savestate_work, work); +#ifdef USE_SDL SDL_LockMutex(savestates_lock); +#else + pthread_mutex_lock(&savestates_lock); +#endif +#ifndef __LIBRETRO__ // Write the state to a GZIP file + gzFile f; + int gzres; f = gzopen(save->filepath, "wb"); if (f==NULL) @@ -1509,15 +1622,28 @@ static void savestates_save_m64p_work(struct work_struct *work) gzclose(f); main_message(M64MSG_STATUS, OSD_BOTTOM_LEFT, "Saved state to: %s", namefrompath(save->filepath)); +#else + memcpy(save->mempointer, save->data, save->size); +#endif free(save->data); +#ifndef __LIBRETRO__ free(save->filepath); +#endif free(save); +#ifdef USE_SDL SDL_UnlockMutex(savestates_lock); +#else StateChanged(M64CORE_STATE_SAVECOMPLETE, 1); + pthread_mutex_unlock(&savestates_lock); +#endif } -static int savestates_save_m64p(const struct device* dev, char *filepath) +#ifndef __LIBRETRO__ +int savestates_save_m64p(const struct device* dev, char *filepath) +#else +int savestates_save_m64p(const struct device* dev, void *data) +#endif { unsigned char outbuf[4]; int i; @@ -1537,7 +1663,11 @@ static int savestates_save_m64p(const struct device* dev, char *filepath) return 0; } +#ifndef __LIBRETRO__ save->filepath = strdup(filepath); +#else + save->mempointer = data; +#endif if(autoinc_save_slot) savestates_inc_slot(); @@ -2162,10 +2292,12 @@ static int savestates_save_pj64_unc(const struct device* dev, char *filepath) int savestates_save(void) { - char *filepath; int ret = 0; const struct device* dev = &g_dev; +#ifndef __LIBRETRO__ + char *filepath; + /* Can only save PJ64 savestates on VI / COMPARE interrupt. Otherwise try again in a little while. */ if ((type == savestates_type_pj64_zip || @@ -2194,22 +2326,39 @@ int savestates_save(void) { StateChanged(M64CORE_STATE_SAVECOMPLETE, ret); } +#else + if(fname) + { + ret = savestates_save_m64p(dev, fname); + fname = NULL; + } else { + ret = 0; + } + + // deliver callback to indicate completion of state saving operation + StateChanged(M64CORE_STATE_SAVECOMPLETE, ret); +#endif // __LIBRETRO__ savestates_clear_job(); + return ret; } void savestates_init(void) { +#ifdef USE_SDL savestates_lock = SDL_CreateMutex(); if (!savestates_lock) { DebugMessage(M64MSG_ERROR, "Could not create savestates list lock"); return; } +#endif } void savestates_deinit(void) { +#ifdef USE_SDL SDL_DestroyMutex(savestates_lock); +#endif savestates_clear_job(); } diff --git a/src/main/savestates.h b/src/main/savestates.h index ae10352a..f74b3b6b 100644 --- a/src/main/savestates.h +++ b/src/main/savestates.h @@ -53,5 +53,13 @@ unsigned int savestates_get_slot(void); void savestates_set_autoinc_slot(int b); void savestates_inc_slot(void); +#ifndef __LIBRETRO__ +int savestates_save_m64p(const struct device* dev, char *filepath); +int savestates_load_m64p(struct device* dev, char *filepath); +#else +int savestates_save_m64p(const struct device* dev, void *data); +int savestates_load_m64p(struct device* dev, const void *data); +#endif + #endif /* __SAVESTAVES_H__ */ diff --git a/src/main/sdl_key_converter.h b/src/main/sdl_key_converter.h index 84fce4de..19d3274e 100644 --- a/src/main/sdl_key_converter.h +++ b/src/main/sdl_key_converter.h @@ -19,7 +19,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include #include #include "osal/preproc.h" @@ -29,10 +28,10 @@ uint16_t sdl_scancode2keysym(uint16_t scancode); static osal_inline uint16_t sdl_keysym2native(uint16_t keysym) { - return sdl_keysym2scancode(keysym); + return keysym; } static osal_inline uint16_t sdl_native2keysym(uint16_t native) { - return sdl_scancode2keysym(native); + return native; } diff --git a/src/plugin/plugin.c b/src/plugin/plugin.c index 86e119ff..e0246bbc 100644 --- a/src/plugin/plugin.c +++ b/src/plugin/plugin.c @@ -36,45 +36,79 @@ #include "device/rcp/vi/vi_controller.h" #include "dummy_audio.h" #include "dummy_input.h" -#include "dummy_rsp.h" -#include "dummy_video.h" #include "main/main.h" #include "main/rom.h" #include "main/version.h" #include "osal/dynamiclib.h" #include "plugin.h" +#ifdef __LIBRETRO__ +#include "mupen64plus-next_common.h" +#endif + +#include CONTROL Controls[4]; +void ResizeVideoOutput(int width, int height){ + +} +/* local data structures and functions */ +#define DEFINE_GFX(X) \ + EXPORT m64p_error CALL X##PluginGetVersion(m64p_plugin_type *, int *, int *, const char **, int *); \ + EXPORT void CALL X##ChangeWindow(void); \ + EXPORT int CALL X##InitiateGFX(GFX_INFO Gfx_Info); \ + EXPORT void CALL X##MoveScreen(int x, int y); \ + EXPORT void CALL X##ProcessDList(void); \ + EXPORT void CALL X##ProcessRDPList(void); \ + EXPORT void CALL X##RomClosed(void); \ + EXPORT int CALL X##RomOpen(void); \ + EXPORT void CALL X##ShowCFB(void); \ + EXPORT void CALL X##UpdateScreen(void); \ + EXPORT void CALL X##ViStatusChanged(void); \ + EXPORT void CALL X##ViWidthChanged(void); \ + EXPORT void CALL X##ReadScreen2(void *dest, int *width, int *height, int front); \ + EXPORT void CALL X##SetRenderingCallback(void (*callback)(int)); \ + EXPORT void CALL X##ResizeVideoOutput(int width, int height); \ + EXPORT void CALL X##FBRead(unsigned int addr); \ + EXPORT void CALL X##FBWrite(unsigned int addr, unsigned int size); \ + EXPORT void CALL X##FBGetFrameBufferInfo(void *p); \ + \ + gfx_plugin_functions gfx_##X = { \ + X##PluginGetVersion, \ + X##ChangeWindow, \ + X##InitiateGFX, \ + X##MoveScreen, \ + X##ProcessDList, \ + X##ProcessRDPList, \ + X##RomClosed, \ + X##RomOpen, \ + X##ShowCFB, \ + X##UpdateScreen, \ + X##ViStatusChanged, \ + X##ViWidthChanged, \ + X##ReadScreen2, \ + X##SetRenderingCallback, \ + ResizeVideoOutput, \ + X##FBRead, \ + X##FBWrite, \ + X##FBGetFrameBufferInfo \ + } + +DEFINE_GFX(gln64); +#if defined(HAVE_THR_AL) +DEFINE_GFX(angrylion); +#endif +#if defined(HAVE_PARALLEL_RDP) +DEFINE_GFX(parallel); +#endif -/* global function pointers - initialized on core startup */ gfx_plugin_functions gfx; +GFX_INFO gfx_info; audio_plugin_functions audio; input_plugin_functions input; rsp_plugin_functions rsp; +RSP_INFO rsp_info; -/* local data structures and functions */ -static const gfx_plugin_functions dummy_gfx = { - dummyvideo_PluginGetVersion, - dummyvideo_ChangeWindow, - dummyvideo_InitiateGFX, - dummyvideo_MoveScreen, - dummyvideo_ProcessDList, - dummyvideo_ProcessRDPList, - dummyvideo_RomClosed, - dummyvideo_RomOpen, - dummyvideo_ShowCFB, - dummyvideo_UpdateScreen, - dummyvideo_ViStatusChanged, - dummyvideo_ViWidthChanged, - dummyvideo_ReadScreen2, - dummyvideo_SetRenderingCallback, - dummyvideo_ResizeVideoOutput, - dummyvideo_FBRead, - dummyvideo_FBWrite, - dummyvideo_FBGetFrameBufferInfo -}; - -static const audio_plugin_functions dummy_audio = { +const audio_plugin_functions dummy_audio = { dummyaudio_PluginGetVersion, dummyaudio_AiDacrateChanged, dummyaudio_AiLenChanged, @@ -91,14 +125,26 @@ static const audio_plugin_functions dummy_audio = { dummyaudio_VolumeGetString }; -static const input_plugin_functions dummy_input = { - dummyinput_PluginGetVersion, - dummyinput_ControllerCommand, - dummyinput_GetKeys, - dummyinput_InitiateControllers, - dummyinput_ReadController, - dummyinput_RomClosed, - dummyinput_RomOpen, + +extern m64p_error inputPluginGetVersion(m64p_plugin_type *PluginType, int *PluginVersion, + int *APIVersion, const char **PluginNamePtr, int *Capabilities); +extern void inputInitiateControllers (CONTROL_INFO ControlInfo); +extern void inputGetKeys_default(int Control, BUTTONS * Keys ); +extern void inputControllerCommand(int Control, unsigned char *Command); +extern void inputInitiateControllers(CONTROL_INFO ControlInfo); +extern void inputReadController(int Control, unsigned char *Command); +extern int inputRomOpen(void); +extern void inputRomClosed(void); + + +const input_plugin_functions dummy_input = { + inputPluginGetVersion, + inputControllerCommand, + inputGetKeys_default, + inputInitiateControllers, + inputReadController, + inputRomClosed, + inputRomOpen, dummyinput_SDL_KeyDown, dummyinput_SDL_KeyUp, dummyinput_RenderCallback, @@ -109,18 +155,8 @@ static const input_plugin_functions dummy_input = { dummyinput_SetVRUWordMask }; -static const rsp_plugin_functions dummy_rsp = { - dummyrsp_PluginGetVersion, - dummyrsp_DoRspCycles, - dummyrsp_InitiateRSP, - dummyrsp_RomClosed -}; - -static GFX_INFO gfx_info; static AUDIO_INFO audio_info; static CONTROL_INFO control_info; -static RSP_INFO rsp_info; - static int l_RspAttached = 0; static int l_InputAttached = 0; static int l_AudioAttached = 0; @@ -132,14 +168,31 @@ static unsigned int dummy; static void EmptyFunc(void) { } +/* RSP */ +#define DEFINE_RSP(X) \ + EXPORT m64p_error CALL X##PluginGetVersion(m64p_plugin_type *, int *, int *, const char **, int *); \ + EXPORT unsigned int CALL X##DoRspCycles(unsigned int Cycles); \ + EXPORT void CALL X##InitiateRSP(RSP_INFO Rsp_Info, unsigned int *CycleCount); \ + EXPORT void CALL X##RomClosed(void); \ + \ + const rsp_plugin_functions rsp_##X = { \ + X##PluginGetVersion, \ + X##DoRspCycles, \ + X##InitiateRSP, \ + X##RomClosed \ + } -// Handy macro to avoid code bloat when loading symbols -#define GET_FUNC(type, field, name) \ - ((field = (type)osal_dynlib_getproc(plugin_handle, name)) != NULL) +// Define RSP Interfaces +DEFINE_RSP(hle); + +#ifdef HAVE_PARALLEL_RSP +DEFINE_RSP(parallelRSP); +#endif // HAVE_PARALLEL_RSP + +#if HAVE_LLE +DEFINE_RSP(cxd4); +#endif // HAVE_LLE -// code to handle backwards-compatibility to video plugins with API_VERSION < 02.1.0. This API version introduced a boolean -// flag in the rendering callback, which told the core whether or not the current screen has been freshly redrawn since the -// last time the callback was called. static void (*l_mainRenderCallback)(int) = NULL; static ptr_SetRenderingCallback l_old1SetRenderingCallback = NULL; @@ -154,85 +207,10 @@ static void backcompat_setRenderCallbackIntercept(void (*callback)(int)) l_mainRenderCallback = callback; } -static void plugin_disconnect_gfx(void) +m64p_error plugin_start_gfx(void) { - gfx = dummy_gfx; - l_GfxAttached = 0; - l_mainRenderCallback = NULL; -} + printf("plugin_start_gfx\n"); -static m64p_error plugin_connect_gfx(m64p_dynlib_handle plugin_handle) -{ - /* attach the Video plugin function pointers */ - if (plugin_handle != NULL) - { - m64p_plugin_type PluginType; - int PluginVersion, APIVersion; - - if (l_GfxAttached) - return M64ERR_INVALID_STATE; - - /* set function pointers for required functions */ - if (!GET_FUNC(ptr_PluginGetVersion, gfx.getVersion, "PluginGetVersion") || - !GET_FUNC(ptr_ChangeWindow, gfx.changeWindow, "ChangeWindow") || - !GET_FUNC(ptr_InitiateGFX, gfx.initiateGFX, "InitiateGFX") || - !GET_FUNC(ptr_MoveScreen, gfx.moveScreen, "MoveScreen") || - !GET_FUNC(ptr_ProcessDList, gfx.processDList, "ProcessDList") || - !GET_FUNC(ptr_ProcessRDPList, gfx.processRDPList, "ProcessRDPList") || - !GET_FUNC(ptr_RomClosed, gfx.romClosed, "RomClosed") || - !GET_FUNC(ptr_RomOpen, gfx.romOpen, "RomOpen") || - !GET_FUNC(ptr_ShowCFB, gfx.showCFB, "ShowCFB") || - !GET_FUNC(ptr_UpdateScreen, gfx.updateScreen, "UpdateScreen") || - !GET_FUNC(ptr_ViStatusChanged, gfx.viStatusChanged, "ViStatusChanged") || - !GET_FUNC(ptr_ViWidthChanged, gfx.viWidthChanged, "ViWidthChanged") || - !GET_FUNC(ptr_ReadScreen2, gfx.readScreen, "ReadScreen2") || - !GET_FUNC(ptr_SetRenderingCallback, gfx.setRenderingCallback, "SetRenderingCallback") || - !GET_FUNC(ptr_FBRead, gfx.fBRead, "FBRead") || - !GET_FUNC(ptr_FBWrite, gfx.fBWrite, "FBWrite") || - !GET_FUNC(ptr_FBGetFrameBufferInfo, gfx.fBGetFrameBufferInfo, "FBGetFrameBufferInfo")) - { - DebugMessage(M64MSG_ERROR, "broken Video plugin; function(s) not found."); - plugin_disconnect_gfx(); - return M64ERR_INPUT_INVALID; - } - - /* set function pointers for optional functions */ - gfx.resizeVideoOutput = (ptr_ResizeVideoOutput)osal_dynlib_getproc(plugin_handle, "ResizeVideoOutput"); - - /* check the version info */ - (*gfx.getVersion)(&PluginType, &PluginVersion, &APIVersion, NULL, NULL); - if (PluginType != M64PLUGIN_GFX || (APIVersion & 0xffff0000) != (GFX_API_VERSION & 0xffff0000)) - { - DebugMessage(M64MSG_ERROR, "incompatible Video plugin"); - plugin_disconnect_gfx(); - return M64ERR_INCOMPATIBLE; - } - - /* handle backwards-compatibility */ - if (APIVersion < 0x020100) - { - DebugMessage(M64MSG_WARNING, "Fallback for Video plugin API (%02i.%02i.%02i) < 2.1.0. Screenshots may contain On Screen Display text", VERSION_PRINTF_SPLIT(APIVersion)); - // tell the video plugin to make its rendering callback to me (it's old, and doesn't have the bScreenRedrawn flag) - gfx.setRenderingCallback(backcompat_videoRenderCallback); - l_old1SetRenderingCallback = gfx.setRenderingCallback; // save this just for future use - gfx.setRenderingCallback = (ptr_SetRenderingCallback) backcompat_setRenderCallbackIntercept; - } - if (APIVersion < 0x20200 || gfx.resizeVideoOutput == NULL) - { - DebugMessage(M64MSG_WARNING, "Fallback for Video plugin API (%02i.%02i.%02i) < 2.2.0. Resizable video will not work", VERSION_PRINTF_SPLIT(APIVersion)); - gfx.resizeVideoOutput = dummyvideo_ResizeVideoOutput; - } - - l_GfxAttached = 1; - } - else - plugin_disconnect_gfx(); - - return M64ERR_SUCCESS; -} - -static m64p_error plugin_start_gfx(void) -{ uint8_t media = g_rom_size == 0 ? 0 : *((uint8_t*)mem_base_u32(g_mem_base, MM_CART_ROM) + (0x3b ^ S8)); /* Here we feed 64DD IPL ROM header to GFX plugin if 64DD is present. @@ -279,7 +257,7 @@ static m64p_error plugin_start_gfx(void) gfx_info.VI_X_SCALE_REG = &(g_dev.vi.regs[VI_X_SCALE_REG]); gfx_info.VI_Y_SCALE_REG = &(g_dev.vi.regs[VI_Y_SCALE_REG]); gfx_info.CheckInterrupts = EmptyFunc; - + gfx_info.version = 2; //Version 2 added SP_STATUS_REG and RDRAM_SIZE gfx_info.SP_STATUS_REG = &g_dev.sp.regs[SP_STATUS_REG]; gfx_info.RDRAM_SIZE = (unsigned int*) &g_dev.rdram.dram_size; @@ -297,54 +275,6 @@ static void plugin_disconnect_audio(void) l_AudioAttached = 0; } -static m64p_error plugin_connect_audio(m64p_dynlib_handle plugin_handle) -{ - /* attach the Audio plugin function pointers */ - if (plugin_handle != NULL) - { - m64p_plugin_type PluginType; - int PluginVersion, APIVersion; - - if (l_AudioAttached) - return M64ERR_INVALID_STATE; - - if (!GET_FUNC(ptr_PluginGetVersion, audio.getVersion, "PluginGetVersion") || - !GET_FUNC(ptr_AiDacrateChanged, audio.aiDacrateChanged, "AiDacrateChanged") || - !GET_FUNC(ptr_AiLenChanged, audio.aiLenChanged, "AiLenChanged") || - !GET_FUNC(ptr_InitiateAudio, audio.initiateAudio, "InitiateAudio") || - !GET_FUNC(ptr_ProcessAList, audio.processAList, "ProcessAList") || - !GET_FUNC(ptr_RomOpen, audio.romOpen, "RomOpen") || - !GET_FUNC(ptr_RomClosed, audio.romClosed, "RomClosed") || - !GET_FUNC(ptr_SetSpeedFactor, audio.setSpeedFactor, "SetSpeedFactor") || - !GET_FUNC(ptr_VolumeUp, audio.volumeUp, "VolumeUp") || - !GET_FUNC(ptr_VolumeDown, audio.volumeDown, "VolumeDown") || - !GET_FUNC(ptr_VolumeGetLevel, audio.volumeGetLevel, "VolumeGetLevel") || - !GET_FUNC(ptr_VolumeSetLevel, audio.volumeSetLevel, "VolumeSetLevel") || - !GET_FUNC(ptr_VolumeMute, audio.volumeMute, "VolumeMute") || - !GET_FUNC(ptr_VolumeGetString, audio.volumeGetString, "VolumeGetString")) - { - DebugMessage(M64MSG_ERROR, "broken Audio plugin; function(s) not found."); - plugin_disconnect_audio(); - return M64ERR_INPUT_INVALID; - } - - /* check the version info */ - (*audio.getVersion)(&PluginType, &PluginVersion, &APIVersion, NULL, NULL); - if (PluginType != M64PLUGIN_AUDIO || (APIVersion & 0xffff0000) != (AUDIO_API_VERSION & 0xffff0000)) - { - DebugMessage(M64MSG_ERROR, "incompatible Audio plugin"); - plugin_disconnect_audio(); - return M64ERR_INCOMPATIBLE; - } - - l_AudioAttached = 1; - } - else - plugin_disconnect_audio(); - - return M64ERR_SUCCESS; -} - static m64p_error plugin_start_audio(void) { /* fill in the AUDIO_INFO data structure */ @@ -373,63 +303,6 @@ static void plugin_disconnect_input(void) l_InputAttached = 0; } -static m64p_error plugin_connect_input(m64p_dynlib_handle plugin_handle) -{ - /* attach the Input plugin function pointers */ - if (plugin_handle != NULL) - { - m64p_plugin_type PluginType; - int PluginVersion, APIVersion; - - if (l_InputAttached) - return M64ERR_INVALID_STATE; - - if (!GET_FUNC(ptr_PluginGetVersion, input.getVersion, "PluginGetVersion") || - !GET_FUNC(ptr_ControllerCommand, input.controllerCommand, "ControllerCommand") || - !GET_FUNC(ptr_GetKeys, input.getKeys, "GetKeys") || - !GET_FUNC(ptr_InitiateControllers, input.initiateControllers, "InitiateControllers") || - !GET_FUNC(ptr_ReadController, input.readController, "ReadController") || - !GET_FUNC(ptr_RomOpen, input.romOpen, "RomOpen") || - !GET_FUNC(ptr_RomClosed, input.romClosed, "RomClosed") || - !GET_FUNC(ptr_SDL_KeyDown, input.keyDown, "SDL_KeyDown") || - !GET_FUNC(ptr_SDL_KeyUp, input.keyUp, "SDL_KeyUp")) - { - DebugMessage(M64MSG_ERROR, "broken Input plugin; function(s) not found."); - plugin_disconnect_input(); - return M64ERR_INPUT_INVALID; - } - - if (!GET_FUNC(ptr_SendVRUWord, input.sendVRUWord, "SendVRUWord") || - !GET_FUNC(ptr_SetMicState, input.setMicState, "SetMicState") || - !GET_FUNC(ptr_ReadVRUResults, input.readVRUResults, "ReadVRUResults") || - !GET_FUNC(ptr_ClearVRUWords, input.clearVRUWords, "ClearVRUWords") || - !GET_FUNC(ptr_SetVRUWordMask, input.setVRUWordMask, "SetVRUWordMask")) - { - DebugMessage(M64MSG_WARNING, "Input plugin does not contain VRU support."); - } - - /* check the version info */ - (*input.getVersion)(&PluginType, &PluginVersion, &APIVersion, NULL, NULL); - if (PluginType != M64PLUGIN_INPUT || (APIVersion & 0xffff0000) != (INPUT_API_VERSION & 0xffff0000) || APIVersion < 0x020100) - { - DebugMessage(M64MSG_ERROR, "incompatible Input plugin"); - plugin_disconnect_input(); - return M64ERR_INCOMPATIBLE; - } - - if (!GET_FUNC(ptr_RenderCallback, input.renderCallback, "RenderCallback")) - { - DebugMessage(M64MSG_INFO, "input plugin did not specify a render callback; there will be no on screen display by the input plugin."); - } - - l_InputAttached = 1; - } - else - plugin_disconnect_input(); - - return M64ERR_SUCCESS; -} - static m64p_error plugin_start_input(void) { int i; @@ -450,50 +323,6 @@ static m64p_error plugin_start_input(void) return M64ERR_SUCCESS; } -static void plugin_disconnect_rsp(void) -{ - rsp = dummy_rsp; - l_RspAttached = 0; -} - -static m64p_error plugin_connect_rsp(m64p_dynlib_handle plugin_handle) -{ - /* attach the RSP plugin function pointers */ - if (plugin_handle != NULL) - { - m64p_plugin_type PluginType; - int PluginVersion, APIVersion; - - if (l_RspAttached) - return M64ERR_INVALID_STATE; - - if (!GET_FUNC(ptr_PluginGetVersion, rsp.getVersion, "PluginGetVersion") || - !GET_FUNC(ptr_DoRspCycles, rsp.doRspCycles, "DoRspCycles") || - !GET_FUNC(ptr_InitiateRSP, rsp.initiateRSP, "InitiateRSP") || - !GET_FUNC(ptr_RomClosed, rsp.romClosed, "RomClosed")) - { - DebugMessage(M64MSG_ERROR, "broken RSP plugin; function(s) not found."); - plugin_disconnect_rsp(); - return M64ERR_INPUT_INVALID; - } - - /* check the version info */ - (*rsp.getVersion)(&PluginType, &PluginVersion, &APIVersion, NULL, NULL); - if (PluginType != M64PLUGIN_RSP || (APIVersion & 0xffff0000) != (RSP_API_VERSION & 0xffff0000)) - { - DebugMessage(M64MSG_ERROR, "incompatible RSP plugin"); - plugin_disconnect_rsp(); - return M64ERR_INCOMPATIBLE; - } - - l_RspAttached = 1; - } - else - plugin_disconnect_rsp(); - - return M64ERR_SUCCESS; -} - static m64p_error plugin_start_rsp(void) { /* fill in the RSP_INFO data structure */ @@ -530,32 +359,6 @@ static m64p_error plugin_start_rsp(void) return M64ERR_SUCCESS; } -/* global functions */ -m64p_error plugin_connect(m64p_plugin_type type, m64p_dynlib_handle plugin_handle) -{ - switch(type) - { - case M64PLUGIN_GFX: - if (plugin_handle != NULL && (l_AudioAttached || l_InputAttached || l_RspAttached)) - DebugMessage(M64MSG_WARNING, "Front-end bug: plugins are attached in wrong order."); - return plugin_connect_gfx(plugin_handle); - case M64PLUGIN_AUDIO: - if (plugin_handle != NULL && (l_InputAttached || l_RspAttached)) - DebugMessage(M64MSG_WARNING, "Front-end bug: plugins are attached in wrong order."); - return plugin_connect_audio(plugin_handle); - case M64PLUGIN_INPUT: - if (plugin_handle != NULL && (l_RspAttached)) - DebugMessage(M64MSG_WARNING, "Front-end bug: plugins are attached in wrong order."); - return plugin_connect_input(plugin_handle); - case M64PLUGIN_RSP: - return plugin_connect_rsp(plugin_handle); - default: - return M64ERR_INPUT_INVALID; - } - - return M64ERR_INTERNAL; -} - m64p_error plugin_start(m64p_plugin_type type) { switch(type) @@ -589,3 +392,116 @@ m64p_error plugin_check(void) return M64ERR_SUCCESS; } +#ifdef __LIBRETRO__ +enum rdp_plugin_type current_rdp_type = RDP_PLUGIN_NONE; +enum rsp_plugin_type current_rsp_type = RSP_PLUGIN_NONE; + +void plugin_connect_rdp_api(enum rdp_plugin_type type) +{ + switch (type) + { + case RDP_PLUGIN_GLIDEN64: + case RDP_PLUGIN_ANGRYLION: + case RDP_PLUGIN_PARALLEL: + current_rdp_type = type; + break; + case RSP_PLUGIN_NONE: + default: + break; + } +} + +void plugin_connect_rsp_api(enum rsp_plugin_type type) +{ + switch (type) + { + case RSP_PLUGIN_HLE: + case RSP_PLUGIN_CXD4: + case RSP_PLUGIN_PARALLEL: + current_rsp_type = type; + break; + case RSP_PLUGIN_NONE: + default: + break; + } +} + +/* global functions */ +void plugin_connect_all() +{ + switch (current_rdp_type) + { + case RDP_PLUGIN_ANGRYLION: +#ifdef HAVE_THR_AL + gfx = gfx_angrylion; +#endif + break; + case RDP_PLUGIN_PARALLEL: +#ifdef HAVE_PARALLEL_RDP + gfx = gfx_parallel; +#endif + break; + case RDP_PLUGIN_GLIDEN64: + gfx = gfx_gln64; + break; + case RDP_PLUGIN_NONE: + default: + break; + } + + l_GfxAttached = 1; + plugin_start_gfx(); + + switch (current_rsp_type) + { + case RSP_PLUGIN_HLE: + rsp = rsp_hle; + break; + case RSP_PLUGIN_CXD4: +#ifdef HAVE_LLE + rsp = rsp_cxd4; +#endif // HAVE_LLE + break; + case RSP_PLUGIN_PARALLEL: +#ifdef HAVE_PARALLEL_RSP + rsp = rsp_parallelRSP; +#endif // HAVE_PARALLEL_RSP + break; + case RSP_PLUGIN_NONE: + default: + break; + } + + l_RspAttached = 1; + plugin_start_rsp(); + + audio = dummy_audio; + l_AudioAttached = 1; + //plugin_start_audio(); + + input = dummy_input; + l_InputAttached = 1; + plugin_start_input(); +} +#else +/* global functions */ +void plugin_connect_all() +{ + gfx = gfx_gln64; + l_GfxAttached = 1; + plugin_start_gfx(); + + rsp = rsp_hle; + l_RspAttached = 1; + plugin_start_rsp(); + + audio = dummy_audio; + l_AudioAttached = 1; + //plugin_start_audio(); + + input = dummy_input; + l_InputAttached = 1; + plugin_start_input(); +} +#endif + diff --git a/src/plugin/plugin.h b/src/plugin/plugin.h index c5be095b..69836d28 100644 --- a/src/plugin/plugin.h +++ b/src/plugin/plugin.h @@ -26,6 +26,11 @@ #include "api/m64p_common.h" #include "api/m64p_plugin.h" #include "api/m64p_types.h" +#include "mupen64plus-next_common.h" + +extern GFX_INFO gfx_info; + +extern CONTROL Controls[4]; extern m64p_error plugin_connect(m64p_plugin_type, m64p_dynlib_handle plugin_handle); extern m64p_error plugin_start(m64p_plugin_type);