diff --git a/.cirrus.yml b/.cirrus.yml new file mode 100644 index 00000000..edac7a65 --- /dev/null +++ b/.cirrus.yml @@ -0,0 +1,206 @@ +# vim: sts=2 sw=2 ai + +################################################################################ +# snes9x +################################################################################ + +snes9x_linux-gtk-amd64_task: + container: + image: gcc:latest + + setup_script: + - git submodule update --init shaders/SPIRV-Cross + - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install meson gettext libsdl2-dev libgtk-3-dev libminizip-dev portaudio19-dev glslang-dev + + compile_script: + - meson build gtk --buildtype=release --strip + - ninja -j2 -C build + + package_script: + - mkdir snes9x + - cp -ar build/snes9x-gtk README.md LICENSE docs data gtk/AUTHORS snes9x/ + - tar -caf "snes9x-gtk-${CIRRUS_CHANGE_IN_REPO}.txz" snes9x + + build_artifacts: + path: "snes9x-gtk-${CIRRUS_CHANGE_IN_REPO}.txz" + + +snes9x_linux-x11-amd64_task: + container: + image: gcc:latest + + setup_script: + - apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install libxv-dev libxinerama-dev + + compile_script: + - cd unix + - touch configure + - ./configure + - make -j2 + + package_script: + - mkdir snes9x + - cp -ar unix/snes9x unix/docs unix/snes9x.conf.default README.md LICENSE data snes9x/ + - tar -caf "snes9x-x11-${CIRRUS_CHANGE_IN_REPO}.txz" snes9x + + build_artifacts: + path: "snes9x-x11-${CIRRUS_CHANGE_IN_REPO}.txz" + + +snes9x_freebsd-x11-amd64_task: + freebsd_instance: + image: freebsd-12-1-release-amd64 + + setup_script: + - pkg install -y gmake pkgconf minizip libX11 libXext + + compile_script: + - cd unix + - touch configure + - ./configure + - gmake -j2 + + package_script: + - mkdir snes9x + - cp -a unix/snes9x unix/docs unix/snes9x.conf.default README.md LICENSE data snes9x/ + - tar -caf "snes9x-x11-${CIRRUS_CHANGE_IN_REPO}.txz" snes9x + + build_artifacts: + path: "snes9x-x11-${CIRRUS_CHANGE_IN_REPO}.txz" + + +snes9x_macOS-amd64_task: + osx_instance: + image: mojave-xcode + + compile_script: + - xcodebuild -project macosx/snes9x.xcodeproj -target Snes9x -configuration Release build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO + + package_script: + - mkdir snes9x + - cp -R macosx/build/Release/Snes9x.app macosx/docs README.md LICENSE snes9x/ + - zip -r "snes9x-${CIRRUS_CHANGE_IN_REPO}.zip" snes9x + + build_artifacts: + path: "snes9x-${CIRRUS_CHANGE_IN_REPO}.zip" + +################################################################################ +# libretro +################################################################################ + +libretro_linux-amd64_task: + container: + image: gcc:latest + compile_script: + - make -j2 -C libretro + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_linux-i386_task: + container: + image: dockcross/linux-x86 + compile_script: + - make -j2 -C libretro + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_linux-armhf_task: + container: + image: dockcross/linux-armv7 + compile_script: + - make -j2 -C libretro + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_linux-armv7-neon-hf_task: + container: + image: dockcross/linux-armv7 + compile_script: + - make -j2 -C libretro platform=unix-armv7-neon-hardfloat + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_linux-arm64_task: + container: + image: dockcross/linux-arm64 + compile_script: + - make -j2 -C libretro + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_android-arm_task: + container: + image: dockcross/android-arm + compile_script: + - make -j2 -C libretro platform=unix + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_android-arm64_task: + container: + image: dockcross/android-arm64 + compile_script: + - make -j2 -C libretro platform=unix-arm64 + build_artifacts: + path: "libretro/snes9x_libretro.so" + + +libretro_emscripten_task: + container: + image: gcc:latest + compile_script: + - make -j2 -C libretro platform=emscripten + build_artifacts: + path: "libretro/snes9x_libretro_emscripten.bc" + + +libretro_macOS-amd64_task: + osx_instance: + image: mojave-xcode + compile_script: + - make -j2 -C libretro + build_artifacts: + path: "libretro/snes9x_libretro.dylib" + + +libretro_nintendo-wii_task: + container: + image: devkitpro/devkitppc + compile_script: + - make -j2 -C libretro platform=wii + build_artifacts: + path: "libretro/snes9x_libretro_wii.a" + + +libretro_nintendo-switch-libnx_task: + container: + image: devkitpro/devkita64 + compile_script: + - make -j2 -C libretro platform=libnx + build_artifacts: + path: "libretro/snes9x_libretro_libnx.a" + + +libretro_nintendo-ngc_task: + container: + image: devkitpro/devkitppc + compile_script: + - make -j2 -C libretro platform=ngc + build_artifacts: + path: "libretro/snes9x_libretro_ngc.a" + + +libretro_playstation-psp_task: + container: + image: bkcsoft/psptoolchain + compile_script: + - make -j2 -C libretro platform=unix + build_artifacts: + path: "libretro/snes9x_libretro.so" + diff --git a/.gitignore b/.gitignore index f0cf4db1..e6cf053c 100644 --- a/.gitignore +++ b/.gitignore @@ -495,3 +495,7 @@ healthchecksdb MigrationBackup/ # End of https://www.gitignore.io/api/c,c++,xcode,visualstudio + +# vim +*.swp + diff --git a/README.md b/README.md index 9014f5da..54b38fbc 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,58 @@ This is the official source code repository for the Snes9x project. Please check the [Wiki](https://github.com/snes9xgit/snes9x/wiki) for additional information. + +## Nightly builds + +Download nightly builds from continuous integration: + +### snes9x + +| OS | status | +|---------------|--------------------------------------------------| +| Windows | [![Status][s9x-win-all]][appveyor] | +| Linux (GTK) | [![Status][snes9x_linux-gtk-amd64]][cirrus-ci] | +| Linux (X11) | [![Status][snes9x_linux-x11-amd64]][cirrus-ci] | +| FreeBSD (X11) | [![Status][snes9x_freebsd-x11-amd64]][cirrus-ci] | +| macOS | [![Status][snes9x_macOS-amd64]][cirrus-ci] | + +[appveyor]: https://ci.appveyor.com/project/snes9x/snes9x +[cirrus-ci]: http://cirrus-ci.com/github/snes9xgit/snes9x + +[s9x-win-all]: https://ci.appveyor.com/api/projects/status/github/snes9xgit/snes9x?branch=master&svg=true +[snes9x_linux-gtk-amd64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=snes9x_linux-gtk-amd64 +[snes9x_linux-x11-amd64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=snes9x_linux-x11-amd64 +[snes9x_freebsd-x11-amd64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=snes9x_freebsd-x11-amd64 +[snes9x_macOS-amd64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=snes9x_macOS-amd64 + +### libretro core + +| OS | status | +|---------------------|---------------------------------------------------------| +| Linux/amd64 | [![Status][libretro_linux-amd64]][cirrus-ci] | +| Linux/i386 | [![Status][libretro_linux-i386]][cirrus-ci] | +| Linux/armhf | [![Status][libretro_linux-armhf]][cirrus-ci] | +| Linux/armv7-neon-hf | [![Status][libretro_linux-armv7-neon-hf]][cirrus-ci] | +| Linux/arm64 | [![Status][libretro_linux-arm64]][cirrus-ci] | +| Android/arm | [![Status][libretro_android-arm]][cirrus-ci] | +| Android/arm64 | [![Status][libretro_android-arm64]][cirrus-ci] | +| Emscripten | [![Status][libretro_emscripten]][cirrus-ci] | +| macOS/amd64 | [![Status][libretro_macOS-amd64]][cirrus-ci] | +| Nintendo Wii | [![Status][libretro_nintendo-wii]][cirrus-ci] | +| Nintendo Switch | [![Status][libretro_nintendo-switch-libnx]][cirrus-ci] | +| Nintendo GameCube | [![Status][libretro_nintendo-ngc]][cirrus-ci] | +| PSP | [![Status][libretro_playstation-psp]][cirrus-ci] | + +[libretro_linux-amd64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_linux-amd64 +[libretro_linux-i386]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_linux-i386 +[libretro_linux-armhf]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_linux-armhf +[libretro_linux-armv7-neon-hf]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_linux-armv7-neon-hf +[libretro_linux-arm64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_linux-arm64 +[libretro_android-arm]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_android-arm +[libretro_android-arm64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_android-arm64 +[libretro_emscripten]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_emscripten +[libretro_macOS-amd64]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_macOS-amd64 +[libretro_nintendo-wii]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_nintendo-wii +[libretro_nintendo-switch-libnx]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_nintendo-switch-libnx +[libretro_nintendo-ngc]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_nintendo-ngc +[libretro_playstation-psp]: https://api.cirrus-ci.com/github/snes9xgit/snes9x.svg?task=libretro_playstation-psp diff --git a/conffile.cpp b/conffile.cpp index 817afae7..fa7de3fa 100644 --- a/conffile.cpp +++ b/conffile.cpp @@ -452,7 +452,7 @@ void ConfigFile::ClearLines() } } -bool ConfigFile::ConfigEntry::section_then_key_less::operator()(const ConfigEntry &a, const ConfigEntry &b) { +bool ConfigFile::ConfigEntry::section_then_key_less::operator()(const ConfigEntry &a, const ConfigEntry &b) const{ if(curConfigFile && a.section!=b.section){ const int sva = curConfigFile->GetSectionSize(a.section); const int svb = curConfigFile->GetSectionSize(b.section); diff --git a/conffile.h b/conffile.h index ba69812d..d92128cb 100644 --- a/conffile.h +++ b/conffile.h @@ -90,7 +90,7 @@ class ConfigFile { mutable bool used; struct section_then_key_less { - bool operator()(const ConfigEntry &a, const ConfigEntry &b); + bool operator()(const ConfigEntry &a, const ConfigEntry &b) const; }; struct key_less { @@ -101,8 +101,8 @@ class ConfigFile { }; struct line_less { - bool operator()(const ConfigEntry &a, const ConfigEntry &b){ - if(a.line==b.line) return (b.val.empty() && !a.val.empty()) || a.key - + diff --git a/macosx/mac-joypad.mm b/macosx/mac-joypad.mm index 35a0388e..78f4a5e8 100755 --- a/macosx/mac-joypad.mm +++ b/macosx/mac-joypad.mm @@ -34,31 +34,6 @@ #include "mac-os.h" #include "mac-joypad.h" -#define kUp(i) (i * 4) -#define kDn(i) (i * 4 + 1) -#define kLf(i) (i * 4 + 2) -#define kRt(i) (i * 4 + 3) - -#define kPadElemTypeNone 0 -#define kPadElemTypeHat4 1 -#define kPadElemTypeHat8 2 -#define kPadElemTypeAxis 3 -#define kPadElemTypeButton 4 -#define kPadElemTypeOtherHat4 5 -#define kPadElemTypeOtherHat8 6 - -#define kPadXAxis 1 -#define kPadYAxis 0 -#define kPadHat 0 - -#define kMaskUp 0x0800 -#define kMaskDn 0x0400 -#define kMaskLf 0x0200 -#define kMaskRt 0x0100 - -typedef hu_device_t *pRecDevice; -typedef hu_element_t *pRecElement; - std::unordered_set allDevices; std::unordered_map>> defaultAxes; std::unordered_map> defaultButtons; @@ -175,7 +150,7 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu objcInput.value =inputStruct.value; pthread_mutex_unlock(&keyLock); - if (info.min != info.max) + if (info.usage != kHIDUsage_GD_Hatswitch && info.min != info.max) { if (inputStruct.value <= info.min || inputStruct.value >= info.max) { @@ -187,16 +162,19 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu } else { - if ([inputDelegate handleInput:objcInput fromJoypad:objcJoypad]) + if (inputStruct.value >= info.min && inputStruct.value <= info.max) { - return; + if ([inputDelegate handleInput:objcInput fromJoypad:objcJoypad]) + { + return; + } } } pthread_mutex_lock(&keyLock); struct JoypadInput oppositeInputStruct = inputStruct; - if (info.min != info.max) + if (info.usage != kHIDUsage_GD_Hatswitch && info.min != info.max) { if (inputStruct.value < info.min) { @@ -216,43 +194,69 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) { pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true; - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false; + + if ( buttonCodeByJoypadInput.find(oppositeInputStruct) != buttonCodeByJoypadInput.end() ) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false; + } + } else { oppositeInputStruct.value = info.min; - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false; + if ( buttonCodeByJoypadInput.find(oppositeInputStruct) != buttonCodeByJoypadInput.end() ) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false; + } oppositeInputStruct.value = info.max; - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false; + + if ( buttonCodeByJoypadInput.find(oppositeInputStruct) != buttonCodeByJoypadInput.end() ) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false; + } } } else if (info.usage == kHIDUsage_GD_Hatswitch) { int32 value = inputStruct.value; - inputStruct.value = 1; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + for (int i = info.min; i <= info.max; i++) { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); + inputStruct.value = i; + if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = false; + } } - inputStruct.value = 2; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) - { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); - } - - inputStruct.value = 4; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) - { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); - } - - inputStruct.value = 8; - if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) - { - pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value); - } + if (value % 2 == 0) + { + inputStruct.value = value; + if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true; + } + } + else + { + for (int i = value - 1; i <= value + 1; i++) + { + int button = i; + if (i < info.min) + { + button = info.max; + } + else if (i > info.max) + { + button = info.min; + } + inputStruct.value = button; + if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end()) + { + pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true; + } + } + } } else { @@ -269,12 +273,12 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu pthread_mutex_unlock(&keyLock); } -void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutableArray *buttons, NSMutableArray *axes, int64 *hat) +void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutableArray *buttons, NSMutableArray *axes, NSMutableDictionary *hat) { if (properties == nil) { return; - } + } int usagePage = [properties[@kIOHIDElementUsagePageKey] intValue]; int usage = [properties[@kIOHIDElementUsageKey] intValue]; @@ -288,18 +292,13 @@ void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutab } else if (usagePage == kHIDPage_GenericDesktop && usage == kHIDUsage_GD_Hatswitch) { - if (hat != NULL) - { - *hat = [properties[@kIOHIDElementCookieKey] intValue]; - } - } - else - { - for ( NSDictionary *child in properties[@kIOHIDElementKey] ) - { - findControls(device, child, buttons, axes, hat); - } + [hat setDictionary:properties]; } + + for ( NSDictionary *child in properties[@kIOHIDElementKey] ) + { + findControls(device, child, buttons, axes, hat); + } } void ParseDefaults (void) @@ -506,7 +505,7 @@ void AddDevice (IOHIDDeviceRef device) NSMutableArray *buttons = [NSMutableArray new]; NSMutableArray *axes = [NSMutableArray new]; - int64 hat = -1; + NSMutableDictionary *hat = [NSMutableDictionary new]; struct JoypadDevice deviceStruct; deviceStruct.vendorID = vendor.unsignedIntValue; @@ -538,7 +537,7 @@ void AddDevice (IOHIDDeviceRef device) for ( NSDictionary *child in ((__bridge NSDictionary *)properties)[@kIOHIDElementKey] ) { - findControls(deviceStruct, child, buttons, axes, &hat); + findControls(deviceStruct, child, buttons, axes, hat); } NSComparisonResult (^comparitor)(NSDictionary *a, NSDictionary *b) = ^NSComparisonResult(NSDictionary *a, NSDictionary *b) @@ -626,17 +625,17 @@ void AddDevice (IOHIDDeviceRef device) infoByCookie[cookie] = info; } - if (hat >= 0) + if ([hat count] >= 0) { struct JoypadCookie cookie; struct JoypadCookieInfo info; cookie.device = deviceStruct; - cookie.cookie = (uint32)hat; + cookie.cookie = hat[@kIOHIDElementCookieKey].unsignedIntValue; info.usage = kHIDUsage_GD_Hatswitch; - info.min = 0; - info.max = 0; + info.min = hat[@kIOHIDElementMinKey].intValue; + info.max = hat[@kIOHIDElementMaxKey].intValue; info.midpoint = 0; if (defaultHatValues.find(defaultsKey) != defaultHatValues.end()) @@ -755,12 +754,6 @@ void SetUpHID (void) { AddDevice((__bridge IOHIDDeviceRef)device); } - - if (orderedDevices.count == 1) - { - const struct JoypadDevice &deviceStruct = *(allDevices.begin()); - SetPlayerForJoypad(0, deviceStruct.vendorID, deviceStruct.productID, deviceStruct.index, NULL); - } } else { @@ -822,7 +815,7 @@ bool SetButtonCodeForJoypadControl(uint32 vendorID, uint32 productID, uint32 ind { auto info = infoByCookie[cookieStruct]; - if ( info.min != info.max ) + if (info.usage != kHIDUsage_GD_Hatswitch && info.min != info.max) { if (value <= info.min) { @@ -1017,7 +1010,7 @@ std::string LabelForInput(uint32 vendorID, uint32 productID, uint32 cookie, int3 } } - if (value == 1) + if (value == 0) { return "D-Pad Up"; } @@ -1029,7 +1022,7 @@ std::string LabelForInput(uint32 vendorID, uint32 productID, uint32 cookie, int3 { return "D-Pad Down"; } - else if (value == 8) + else if (value == 6) { return "D-Pad Left"; } diff --git a/macosx/mac-os.h b/macosx/mac-os.h index 76687519..3b6e9e9f 100644 --- a/macosx/mac-os.h +++ b/macosx/mac-os.h @@ -124,7 +124,10 @@ extern bool8 pressedKeys[MAC_MAX_PLAYERS][kNumButtons]; extern bool8 pressedGamepadButtons[MAC_MAX_PLAYERS][kNumButtons]; extern pthread_mutex_t keyLock; -extern MTKView *s9xView; +@interface S9xView: MTKView +- (void)updatePauseOverlay; +@end +extern S9xView *s9xView; void AdjustMenus (void); void UpdateMenuCommandStatus (Boolean); @@ -161,12 +164,15 @@ extern id inputDelegate; @property (nonatomic, weak) id inputDelegate; +- (void)recreateS9xView; + - (void)start; - (void)stop; - (BOOL)isRunning; - (BOOL)isPaused; - (void)pause; +- (void)quit; - (void)resume; - (BOOL)setButton:(S9xButtonCode)button forKey:(int16)key player:(int8)player oldButton:(S9xButtonCode *)oldButton oldPlayer:(int8 *)oldPlayer oldKey:(int16 *)oldKey; diff --git a/macosx/mac-os.mm b/macosx/mac-os.mm index 9b5cf5ef..9828acd7 100644 --- a/macosx/mac-os.mm +++ b/macosx/mac-os.mm @@ -219,7 +219,7 @@ bool8 pressedRawKeyboardButtons[MAC_NUM_KEYCODES] = { 0 }; bool8 heldFunctionButtons[kNumFunctionButtons] = { 0 }; pthread_mutex_t keyLock; -MTKView *s9xView; +S9xView *s9xView; enum { @@ -348,6 +348,8 @@ static inline void EmulationLoop (void) pauseEmulation = false; frameAdvance = false; + [s9xView updatePauseOverlay]; + if (macQTRecord) { @@ -2218,6 +2220,7 @@ static void ProcessInput (void) case ToggleEmulationPause: pauseEmulation = !pauseEmulation; + [s9xView updatePauseOverlay]; break; case AdvanceFrame: @@ -2239,6 +2242,7 @@ static void ProcessInput (void) if (ISpKeyIsPressed(keys, gamepadButtons, kISpEsc)) { pauseEmulation = true; + [s9xView updatePauseOverlay]; dispatch_async(dispatch_get_main_queue(), ^ { @@ -2419,8 +2423,10 @@ static void ProcessInput (void) } } - ControlPadFlagsToS9xReportButtons(0, controlPad[0]); - ControlPadFlagsToS9xReportButtons(1, controlPad[1]); + for (int i = 0; i < MAC_MAX_PLAYERS; ++i) + { + ControlPadFlagsToS9xReportButtons(i, controlPad[i]); + } if (macControllerOption == SNES_JUSTIFIER_2) ControlPadFlagsToS9xPseudoPointer(controlPad[1]); @@ -2545,7 +2551,7 @@ static void Initialize (void) Settings.Stereo = true; Settings.SoundPlaybackRate = 32000; Settings.SoundInputRate = 31950; - Settings.SupportHiRes = false; + Settings.SupportHiRes = true; Settings.Transparency = true; Settings.AutoDisplayMessages = true; Settings.InitialInfoStringTimeout = 120; @@ -2794,9 +2800,6 @@ void QuitWithFatalError ( NSString *message) [NSApp terminate:nil]; } -@interface S9xView : MTKView -@end - @implementation S9xView + (void)initialize @@ -2838,7 +2841,7 @@ void QuitWithFatalError ( NSString *message) pthread_mutex_lock(&keyLock); S9xButton button = keyCodes[event.keyCode]; - if ( button.buttonCode >= 0 && button.buttonCode < kNumButtons && button.player <= 0 && button.player <= MAC_MAX_PLAYERS) + if ( button.buttonCode >= 0 && button.buttonCode < kNumButtons && button.player >= 0 && button.player <= MAC_MAX_PLAYERS) { pressedKeys[button.player][button.buttonCode] = true; } @@ -2866,7 +2869,7 @@ void QuitWithFatalError ( NSString *message) pthread_mutex_lock(&keyLock); S9xButton button = keyCodes[event.keyCode]; - if ( button.buttonCode >= 0 && button.buttonCode < kNumButtons && button.player <= 0 && button.player <= MAC_MAX_PLAYERS) + if ( button.buttonCode >= 0 && button.buttonCode < kNumButtons && button.player >= 0 && button.player <= MAC_MAX_PLAYERS) { pressedKeys[button.player][button.buttonCode] = false; } @@ -2927,15 +2930,18 @@ void QuitWithFatalError ( NSString *message) - (void)mouseDown:(NSEvent *)event { pauseEmulation = true; - [self setNeedsDisplay:YES]; + [s9xView updatePauseOverlay]; } -- (void)drawRect:(NSRect)dirtyRect +- (void)updatePauseOverlay { - self.subviews[0].hidden = !pauseEmulation; - CGFloat scaleFactor = MAX(self.window.backingScaleFactor, 1.0); - glScreenW = self.frame.size.width * scaleFactor; - glScreenH = self.frame.size.height * scaleFactor; + dispatch_async(dispatch_get_main_queue(), ^{ + NSLog(@"%d", pauseEmulation); + self.subviews[0].hidden = !pauseEmulation; + CGFloat scaleFactor = MAX(self.window.backingScaleFactor, 1.0); + glScreenW = self.frame.size.width * scaleFactor; + glScreenH = self.frame.size.height * scaleFactor; + }); } - (void)setFrame:(NSRect)frame @@ -2970,15 +2976,7 @@ void QuitWithFatalError ( NSString *message) if (self = [super init]) { Initialize(); - - CGRect frame = NSMakeRect(0, 0, SNES_WIDTH * 2, SNES_HEIGHT * 2); - s9xView = [[S9xView alloc] initWithFrame:frame]; - s9xView.translatesAutoresizingMaskIntoConstraints = NO; - s9xView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; - [s9xView addConstraint:[NSLayoutConstraint constraintWithItem:s9xView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:s9xView attribute:NSLayoutAttributeWidth multiplier:(CGFloat)SNES_HEIGHT/(CGFloat)SNES_WIDTH constant:0.0]]; - [s9xView addConstraint:[NSLayoutConstraint constraintWithItem:s9xView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:SNES_WIDTH * 2.0]]; - [s9xView addConstraint:[NSLayoutConstraint constraintWithItem:s9xView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:SNES_HEIGHT * 2.0]]; - s9xView.device = MTLCreateSystemDefaultDevice(); + [self recreateS9xView]; } return self; @@ -2989,6 +2987,21 @@ void QuitWithFatalError ( NSString *message) Deinitialize(); } +- (void)recreateS9xView +{ + [s9xView removeFromSuperview]; + S9xDeinitDisplay(); + CGRect frame = NSMakeRect(0, 0, SNES_WIDTH * 2, SNES_HEIGHT * 2); + s9xView = [[S9xView alloc] initWithFrame:frame]; + s9xView.translatesAutoresizingMaskIntoConstraints = NO; + s9xView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; + [s9xView addConstraint:[NSLayoutConstraint constraintWithItem:s9xView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:s9xView attribute:NSLayoutAttributeWidth multiplier:(CGFloat)SNES_HEIGHT/(CGFloat)SNES_WIDTH constant:0.0]]; + [s9xView addConstraint:[NSLayoutConstraint constraintWithItem:s9xView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:SNES_WIDTH * 2.0]]; + [s9xView addConstraint:[NSLayoutConstraint constraintWithItem:s9xView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:SNES_HEIGHT * 2.0]]; + s9xView.device = MTLCreateSystemDefaultDevice(); + S9xInitDisplay(NULL, NULL); +} + - (void)start { #ifdef DEBUGGER @@ -3013,6 +3026,7 @@ void QuitWithFatalError ( NSString *message) - (void)stop { + SNES9X_Quit(); S9xExit(); } @@ -3029,12 +3043,19 @@ void QuitWithFatalError ( NSString *message) - (void)pause { pauseEmulation = true; - [s9xView setNeedsDisplay:YES]; + [s9xView updatePauseOverlay]; +} + +- (void)quit +{ + SNES9X_Quit(); + [self pause]; } - (void)resume { pauseEmulation = false; + [s9xView updatePauseOverlay]; } - (NSArray *)listJoypads diff --git a/macosx/mac-render.mm b/macosx/mac-render.mm index 74e7b1cf..3ce4e9a1 100644 --- a/macosx/mac-render.mm +++ b/macosx/mac-render.mm @@ -55,7 +55,19 @@ typedef struct vector_float2 textureCoordinate; } MetalVertex; +@interface MetalLayerDelegate: NSObject +@end + +@implementation MetalLayerDelegate +- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)newScale fromWindow:(NSWindow *)window +{ + return YES; +} + +@end + CAMetalLayer *metalLayer = nil; +MetalLayerDelegate *layerDelegate = nil; id metalDevice = nil; id metalTexture = nil; id metalCommandQueue = nil; @@ -147,6 +159,8 @@ static void S9xInitMetal (void) glScreenH = glScreenBounds.size.height; metalLayer = (CAMetalLayer *)s9xView.layer; + layerDelegate = [MetalLayerDelegate new]; + metalLayer.delegate = layerDelegate; metalDevice = s9xView.device; diff --git a/memmap.cpp b/memmap.cpp index e29fab4d..1178e889 100644 --- a/memmap.cpp +++ b/memmap.cpp @@ -894,7 +894,7 @@ static void S9xDeinterleaveGD24 (int size, uint8 *base) bool8 CMemory::Init (void) { RAM = (uint8 *) malloc(0x20000); - SRAM = (uint8 *) malloc(0x20000); + SRAM = (uint8 *) malloc(0x80000); VRAM = (uint8 *) malloc(0x10000); ROM = (uint8 *) malloc(MAX_ROM_SIZE + 0x200 + 0x8000); @@ -935,7 +935,7 @@ bool8 CMemory::Init (void) } memset(RAM, 0, 0x20000); - memset(SRAM, 0, 0x20000); + memset(SRAM, 0, 0x80000); memset(VRAM, 0, 0x10000); memset(ROM, 0, MAX_ROM_SIZE + 0x200 + 0x8000); diff --git a/sa1.cpp b/sa1.cpp index aa008590..e56bf6ad 100644 --- a/sa1.cpp +++ b/sa1.cpp @@ -117,10 +117,12 @@ void S9xSA1PostLoadState (void) SA1.VirtualBitmapFormat = (Memory.FillRAM[0x223f] & 0x80) ? 2 : 4; Memory.BWRAM = Memory.SRAM + (Memory.FillRAM[0x2224] & 0x1f) * 0x2000; S9xSA1SetBWRAMMemMap(Memory.FillRAM[0x2225]); +#if 0 S9xSetSA1(Memory.FillRAM[0x2220], 0x2220); S9xSetSA1(Memory.FillRAM[0x2221], 0x2221); S9xSetSA1(Memory.FillRAM[0x2222], 0x2222); S9xSetSA1(Memory.FillRAM[0x2223], 0x2223); +#endif } static void S9xSetSA1MemMap (uint32 which1, uint8 map) @@ -168,7 +170,7 @@ static void S9xSetSA1MemMap (uint32 which1, uint8 map) { offset = (((map & 0x80) ? (map - 4) : which1) & 7) * 0x100000 + (c << 11) - 0x8000; block = Memory.ROM + Multi.cartOffsetB + offset; - } + } } for (int i = c + 8; i < c + 16; i++) Memory.Map[start2 + i] = SA1.Map[start2 + i] = block; diff --git a/snapshot.cpp b/snapshot.cpp index 84dd9c41..b2a845da 100644 --- a/snapshot.cpp +++ b/snapshot.cpp @@ -1199,7 +1199,7 @@ void S9xFreezeToStream (STREAM stream) FreezeBlock (stream, "RAM", Memory.RAM, 0x20000); - FreezeBlock (stream, "SRA", Memory.SRAM, 0x20000); + FreezeBlock (stream, "SRA", Memory.SRAM, 0x80000); FreezeBlock (stream, "FIL", Memory.FillRAM, 0x8000); @@ -1404,9 +1404,9 @@ int S9xUnfreezeFromStream (STREAM stream) break; if (fast) - result = UnfreezeBlock(stream, "SRA", Memory.SRAM, 0x20000); + result = UnfreezeBlock(stream, "SRA", Memory.SRAM, 0x80000); else - result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x20000); + result = UnfreezeBlockCopy (stream, "SRA", &local_sram, 0x80000); if (result != SUCCESS) break; @@ -1576,7 +1576,7 @@ int S9xUnfreezeFromStream (STREAM stream) memcpy(Memory.RAM, local_ram, 0x20000); if (local_sram) - memcpy(Memory.SRAM, local_sram, 0x20000); + memcpy(Memory.SRAM, local_sram, 0x80000); if (local_fillram) memcpy(Memory.FillRAM, local_fillram, 0x8000);