Merge pull request #1 from snes9xgit/master

Merging
This commit is contained in:
JotaRandom 2020-06-11 05:10:33 -04:00 committed by GitHub
commit 2d4d589923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 448 additions and 131 deletions

206
.cirrus.yml Normal file
View File

@ -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"

4
.gitignore vendored
View File

@ -495,3 +495,7 @@ healthchecksdb
MigrationBackup/
# End of https://www.gitignore.io/api/c,c++,xcode,visualstudio
# vim
*.swp

View File

@ -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

View File

@ -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);

View File

@ -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,7 +101,7 @@ class ConfigFile {
};
struct line_less {
bool operator()(const ConfigEntry &a, const ConfigEntry &b){
bool operator()(const ConfigEntry &a, const ConfigEntry &b) const{
if(a.line==b.line) return (b.val.empty() && !a.val.empty()) || a.key<b.key;
if(b.line<0) return true;
if(a.line<0) return false;

View File

@ -93,13 +93,14 @@ endif
if slang and opengl
glslang_dep = c_compiler.find_library('glslang', required: false)
hlsl_dep = c_compiler.find_library('HLSL', required: false)
spirv_dep = c_compiler.find_library('SPIRV', required: false)
osdependent_dep = c_compiler.find_library('OSDependent', required: false)
ogl_compiler_dep = c_compiler.find_library('OGLCompiler', required: false)
spv_remapper_dep = c_compiler.find_library('SPVRemapper', required: false)
if glslang_dep.found() and spirv_dep.found() and osdependent_dep.found() and ogl_compiler_dep.found() and spv_remapper_dep.found()
deps += [glslang_dep, spirv_dep, osdependent_dep, ogl_compiler_dep, spv_remapper_dep]
if glslang_dep.found() and hlsl_dep.found() and spirv_dep.found() and osdependent_dep.found() and ogl_compiler_dep.found() and spv_remapper_dep.found()
deps += [glslang_dep, hlsl_dep, spirv_dep, osdependent_dep, ogl_compiler_dep, spv_remapper_dep]
args += ['-DUSE_SLANG',
'-DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS',

View File

@ -52,13 +52,6 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
window.frameAutosaveName = kMainWindowIdentifier;
window.releasedWhenClosed = NO;
[window.contentView addSubview:s9xView];
[s9xView.topAnchor constraintEqualToAnchor:window.contentView.topAnchor].active = YES;
[s9xView.bottomAnchor constraintEqualToAnchor:window.contentView.bottomAnchor].active = YES;
[s9xView.centerXAnchor constraintEqualToAnchor:window.contentView.centerXAnchor].active = YES;
[s9xView.leftAnchor constraintGreaterThanOrEqualToAnchor:window.contentView.leftAnchor].active = YES;
[s9xView.rightAnchor constraintLessThanOrEqualToAnchor:window.contentView.rightAnchor].active = YES;
if ( ![window setFrameUsingName:kMainWindowIdentifier] )
{
[window center];
@ -68,12 +61,12 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
[NSNotificationCenter.defaultCenter addObserverForName:NSWindowWillCloseNotification object:window queue:NSOperationQueue.mainQueue usingBlock:^(NSNotification *notification)
{
[self.s9xEngine pause];
[self.s9xEngine quit];
}];
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
[self.s9xEngine quit];
}
- (void)setupDefaults
@ -129,6 +122,8 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
};
[defaults registerDefaults:defaultSettings];
[defaults setBool:NO forKey:@"NSWindowAssertWhenDisplayCycleLimitReached"];
[defaults synchronize];
self.keys = [[defaults objectForKey:kKeyboardPrefs] mutableCopy];
@ -140,6 +135,8 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
[self setButtonCode:buttonCode forKeyCode:self.keys[control].integerValue player:player];
}
NSDictionary *joypadPlayerPrefs = [defaults objectForKey:kJoypadPlayerPrefs];
for ( S9xJoypad *joypad in [self listJoypads])
{
NSMutableDictionary *joypadPrefs = [[defaults objectForKey:kJoypadInputPrefs] mutableCopy];
@ -152,6 +149,14 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
NSString *key = [self prefsKeyForVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
for ( NSString *playerString in joypadPlayerPrefs )
{
if ( [key isEqualToString:joypadPlayerPrefs[playerString]] )
{
[self setPlayer:playerString.intValue forVendorID:joypad.vendorID productID:joypad.productID index:joypad.index];
}
}
NSMutableDictionary *devicePrefs = [joypadPrefs[key] mutableCopy];
if (devicePrefs == nil)
{
@ -444,8 +449,18 @@ static NSWindowFrameAutosaveName const kMainWindowIdentifier = @"s9xMainWindow";
{
if ([self.s9xEngine loadROM:url])
{
[self.s9xEngine recreateS9xView];
[self.window makeKeyAndOrderFront:self];
NSWindow *window = self.window;
[window.contentView addSubview:s9xView];
[s9xView.topAnchor constraintEqualToAnchor:window.contentView.topAnchor].active = YES;
[s9xView.bottomAnchor constraintEqualToAnchor:window.contentView.bottomAnchor].active = YES;
[s9xView.centerXAnchor constraintEqualToAnchor:window.contentView.centerXAnchor].active = YES;
[s9xView.leftAnchor constraintGreaterThanOrEqualToAnchor:window.contentView.leftAnchor].active = YES;
[s9xView.rightAnchor constraintLessThanOrEqualToAnchor:window.contentView.rightAnchor].active = YES;
[window makeKeyAndOrderFront:self];
[NSDocumentController.sharedDocumentController noteNewRecentDocumentURL:url];
return YES;
}

View File

@ -114,7 +114,7 @@
for (NSUInteger i = 0; i < kNumButtons; ++i)
{
controlsDict[@(i)] = keyboardDict[@(i + playerNum).stringValue];
controlsDict[@(i)] = keyboardDict[@(i + (playerNum * kNumButtons)).stringValue];
}
for (NSView *subview in self.view.subviews)

View File

@ -279,7 +279,7 @@
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="eyk-QN-lkH">
<rect key="frame" x="230" y="143" width="151" height="16"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Pause Soper Scope" id="5op-LV-kgt">
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Pause Super Scope" id="5op-LV-kgt">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>

View File

@ -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<JoypadDevice> allDevices;
std::unordered_map<JoypadDevice, std::map<uint8, std::map<int8, S9xButtonCode>>> defaultAxes;
std::unordered_map<JoypadDevice, std::map<uint8, S9xButtonCode>> 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)
{
@ -186,17 +161,20 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu
}
}
else
{
if (inputStruct.value >= info.min && inputStruct.value <= info.max)
{
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,42 +194,68 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu
if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end())
{
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true;
if ( buttonCodeByJoypadInput.find(oppositeInputStruct) != buttonCodeByJoypadInput.end() )
{
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false;
}
}
else
{
oppositeInputStruct.value = info.min;
if ( buttonCodeByJoypadInput.find(oppositeInputStruct) != buttonCodeByJoypadInput.end() )
{
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[oppositeInputStruct]] = false;
}
oppositeInputStruct.value = info.max;
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;
for (int i = info.min; i <= info.max; i++)
{
inputStruct.value = i;
if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end())
{
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value);
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = false;
}
}
inputStruct.value = 2;
if (value % 2 == 0)
{
inputStruct.value = value;
if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end())
{
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value);
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true;
}
inputStruct.value = 4;
if (buttonCodeByJoypadInput.find(inputStruct) != buttonCodeByJoypadInput.end())
{
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = (value & inputStruct.value);
}
inputStruct.value = 8;
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]] = (value & inputStruct.value);
pressedGamepadButtons[playerNum][buttonCodeByJoypadInput[inputStruct]] = true;
}
}
}
}
else
@ -269,7 +273,7 @@ void gamepadAction(void *inContext, IOReturn inResult, void *inSender, IOHIDValu
pthread_mutex_unlock(&keyLock);
}
void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutableArray<NSDictionary *> *buttons, NSMutableArray<NSDictionary *> *axes, int64 *hat)
void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutableArray<NSDictionary *> *buttons, NSMutableArray<NSDictionary *> *axes, NSMutableDictionary *hat)
{
if (properties == nil)
{
@ -288,19 +292,14 @@ void findControls(struct JoypadDevice &device, NSDictionary *properties, NSMutab
}
else if (usagePage == kHIDPage_GenericDesktop && usage == kHIDUsage_GD_Hatswitch)
{
if (hat != NULL)
{
*hat = [properties[@kIOHIDElementCookieKey] intValue];
[hat setDictionary:properties];
}
}
else
{
for ( NSDictionary *child in properties[@kIOHIDElementKey] )
{
findControls(device, child, buttons, axes, hat);
}
}
}
void ParseDefaults (void)
{
@ -506,7 +505,7 @@ void AddDevice (IOHIDDeviceRef device)
NSMutableArray<NSDictionary *> *buttons = [NSMutableArray new];
NSMutableArray<NSDictionary *> *axes = [NSMutableArray new];
int64 hat = -1;
NSMutableDictionary<NSString *, NSNumber *> *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";
}

View File

@ -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<S9xInputDelegate> inputDelegate;
@property (nonatomic, weak) id<S9xInputDelegate> 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;

View File

@ -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
{
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<S9xJoypad *> *)listJoypads

View File

@ -55,7 +55,19 @@ typedef struct
vector_float2 textureCoordinate;
} MetalVertex;
@interface MetalLayerDelegate: NSObject<CALayerDelegate, NSViewLayerContentScaleDelegate>
@end
@implementation MetalLayerDelegate
- (BOOL)layer:(CALayer *)layer shouldInheritContentsScale:(CGFloat)newScale fromWindow:(NSWindow *)window
{
return YES;
}
@end
CAMetalLayer *metalLayer = nil;
MetalLayerDelegate *layerDelegate = nil;
id<MTLDevice> metalDevice = nil;
id<MTLTexture> metalTexture = nil;
id<MTLCommandQueue> 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;

View File

@ -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);

View File

@ -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)

View File

@ -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);