42 Commits

Author SHA1 Message Date
clobber 173913b654 Bump version for sparkle updater (still MAME 0.250) 2022-12-15 21:34:28 -07:00
clobber 15c0cc9958 Set deployment target to 10.15
This resolves crashing for Intel Macs on macOS 13.x
2022-12-15 21:30:39 -07:00
clobber 54fd07c851 Update README.md 2022-12-14 14:05:55 -07:00
clobber 5b9f56f708 Only build x86_64 for now. 2022-12-11 20:01:24 -07:00
clobber a10a8925f5 Update deployment target 2022-12-11 16:02:30 -07:00
clobber 77dc525a88 Update readme 2022-12-11 15:40:09 -07:00
Stuart Carnie e473aede19 update MAME to 0250 2022-12-11 08:50:12 +11:00
Stuart Carnie 944046bb60 update MAME to 0240 2022-02-06 08:53:03 +11:00
clobber 2d0805aa3f Update readme 2021-09-16 16:26:21 -06:00
Stuart Carnie de6fb8dd22 update mame dependency 2021-09-17 08:19:20 +10:00
Stuart Carnie b122f3d3cc chore: Update to MAME 0235 2021-08-30 06:45:42 +10:00
Stuart Carnie 57c375d9e6 feat: MAME 0.231 release 2021-05-02 09:56:49 +10:00
clobber 5091dab464 Bump version for sparkle updater (still MAME 0.277)
This is build fix for 10.14 compat.
2021-01-03 18:49:06 -07:00
Stuart Carnie a5ed7abb1f feat: Update to MAME 0.227 🎉 2021-01-02 10:01:27 +11:00
Stuart Carnie 4a3079c7b5 feat: Upgrade to MAME 0.225 🎉 2020-10-01 08:12:36 -07:00
C.W. Betts 0487d834b0 Merge branch 'master' of github.com:OpenEmu/UME-Core into master 2020-10-01 01:30:54 -06:00
C.W. Betts 619e01001e Fix locations of the system plugin headers.
Minor Xcode maintenance.
2020-10-01 01:26:45 -06:00
Stuart Carnie baec92eba7 feat: Upgrade to MAME 0.224 🎉 2020-09-26 22:31:04 -07:00
Stuart Carnie a023f2d7a3 feat: Upgrade to MAME 0.219 🎉 2020-02-29 08:53:50 -07:00
Stuart Carnie cf1d704910 feat: MAME 0217 2020-01-06 17:07:14 -07:00
Stuart Carnie e1ab96e4a5 fix: Updated dep with fix for R/W CHDs 2019-11-25 18:06:37 -07:00
Stuart Carnie 3b5d9b3b98 feat: Update deps/mame with APIs to improve error handling 2019-11-25 17:19:53 -07:00
Stuart Carnie 2e13867b45 fix: use correct constant 2019-11-17 09:56:13 -07:00
Stuart Carnie 0550075d97 feat: Check for unsupported games and notify user 2019-11-16 11:34:31 -07:00
Stuart Carnie 138d4349ef fix: Update MAME dependency 2019-11-14 23:48:29 -07:00
Stuart Carnie dd86bd1ddb feat: update mame dependency; save/load error messages 2019-11-13 20:10:41 -07:00
Stuart Carnie 3e84bed561 feat: MAME 0.215 audit and error message improvements, cleanup
* Updated mame headless dependencyto latest
2019-11-13 18:13:00 -07:00
Stuart Carnie 40d3c1bc39 feat: port original audit error parsing 2019-11-06 23:01:55 -07:00
Stuart Carnie 2041d3708f feat: Update to MAME 0215 2019-11-06 20:10:35 -07:00
Stuart Carnie 499bd380d4 fix: update deps; larger buffer size 2019-08-27 22:06:48 -07:00
Stuart Carnie 73b13490bb chore: Rename input devices 2019-08-24 15:58:10 -07:00
Stuart Carnie 19c0ed9ae3 chore: remove dead code 2019-08-24 10:02:08 -07:00
Stuart Carnie e4b9a66c9e feat: Add UI configuration shortcut (mapped to TAB) 2019-08-18 10:58:48 -07:00
Stuart Carnie 6bf3cefc21 fix: use hard reset for greater compat 2019-08-11 14:15:56 -07:00
Stuart Carnie 59a43f6e16 feat: MAME 0209; rewind, save 2019-08-11 11:37:42 -07:00
Stuart Carnie 3b780e0fce wip: MAME 0209 update
This is dependent on an update to MAME which provides a minimal API
for hosting in other front-ends. The headless API includes some
minor modifications to MAME allow single-frame execution of a machine
via a simple Objective-C API. Longer term goals include exposing
more of MAME's configuration to OpenEmu.

Follow development of Headless MAME here:

https://github.com/stuartcarnie/mame/tree/mame0209-headless
2019-07-13 07:58:47 +10:00
clobber 1225c80616 Merge pull request #9 from MaddTheSane/patch-1
Update README.md
2018-09-17 00:23:23 -05:00
C.W. Betts 6986850cc1 Update README.md
Add OSD=osdmini to the build instructions.
Otherwise SDL detection might override the OSD detection and cause an early failure.
2018-09-16 23:14:42 -06:00
clobber c0e1f10371 Alert the user of missing required parent/device/BIOS ROMs 2018-09-14 17:12:34 -05:00
clobber b964bf251f Use -fileSystemRepresentation instead of -UTF8String for file names 2018-09-14 17:01:18 -05:00
clobber 2a37738cbe Fix restoring autosave states on launch. 2018-09-14 16:53:53 -05:00
clobber 1e49fd519e Fix audio after API change in https://github.com/OpenEmu/OpenEmu-SDK/commit/62c7436015a4fa5e7bb5d434a2585adb5de94d8c 2018-09-14 16:48:36 -05:00
15 changed files with 754 additions and 987 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
# Xcode
*/build/*
build
*/Build/*
*.pbxuser
!default.pbxuser
@@ -12,7 +12,7 @@
xcuserdata
profile
*.moved-aside
DerivedData
DerivedData/
.idea/
*.hmap
+4 -3
View File
@@ -1,3 +1,4 @@
[submodule "mame"]
path = mame
url = git@github.com:stuartcarnie/mame.git
[submodule "deps/mame"]
path = deps/mame
url = https://github.com/stuartcarnie/mame.git
branch = mame0225-headless
+15 -1
View File
@@ -19,11 +19,25 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.169.0</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string>OEGameCoreController</string>
<key>OEGameCoreClass</key>
<string>MAMEGameCore</string>
<key>OEGameCoreOptions</key>
<dict>
<key>openemu.system.arcade</key>
<dict>
<key>OEGameCoreRewindBufferSeconds</key>
<integer>10</integer>
<key>OEGameCoreRewindInterval</key>
<integer>0</integer>
<key>OEGameCoreSupportsDisplayModeChange</key>
<true/>
<key>OEGameCoreSupportsRewinding</key>
<true/>
</dict>
</dict>
<key>OEGameCorePlayerCount</key>
<string>8</string>
<key>OEProjectURL</key>
+137 -133
View File
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objectVersion = 53;
objects = {
/* Begin PBXAggregateTarget section */
@@ -22,15 +22,10 @@
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
051A8EE71C55CCCB00AB4D95 /* libmame_x64.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 051A8EE61C55CCCB00AB4D95 /* libmame_x64.a */; };
051A8EE91C55CCD300AB4D95 /* makefile in Sources */ = {isa = PBXBuildFile; fileRef = 051A8EE81C55CCD300AB4D95 /* makefile */; };
051A8EEB1C55CD1400AB4D95 /* minidir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 051A8EEA1C55CD1400AB4D95 /* minidir.cpp */; };
05334A961C52AEEF0066D493 /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05334A951C52AEEF0066D493 /* CoreMIDI.framework */; };
05334A991C52AF0E0066D493 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05334A981C52AF0E0066D493 /* CoreAudio.framework */; };
8C3132F8177F667D0002D0B9 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8C3132F7177F667D0002D0B9 /* OpenGL.framework */; };
8CA9071017A83C08001591B7 /* osx_osd_interface.mm in Sources */ = {isa = PBXBuildFile; fileRef = D00DAE0B176E1E6900F58FBB /* osx_osd_interface.mm */; };
0510AA1E2300825E002028C1 /* mamearcade_headless.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */; };
0510AA1F23008294002028C1 /* mamearcade_headless.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
D00A068E1763763000C99008 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D00A068D1763763000C99008 /* Cocoa.framework */; };
D00A06A617637E9100C99008 /* MAMEGameCore.mm in Sources */ = {isa = PBXBuildFile; fileRef = D00A06A517637E9100C99008 /* MAMEGameCore.mm */; };
D00A06A617637E9100C99008 /* MAMEGameCore.m in Sources */ = {isa = PBXBuildFile; fileRef = D00A06A517637E9100C99008 /* MAMEGameCore.m */; };
D0AADE31176382F900759E26 /* OpenEmuBase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AADE30176382F900759E26 /* OpenEmuBase.framework */; };
/* End PBXBuildFile section */
@@ -44,10 +39,28 @@
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
0510AA2023008294002028C1 /* Embed Libraries */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
0510AA1F23008294002028C1 /* mamearcade_headless.dylib in Embed Libraries */,
);
name = "Embed Libraries";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
051A8EE61C55CCCB00AB4D95 /* libmame_x64.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libmame_x64.a; sourceTree = "<group>"; };
051A8EE81C55CCD300AB4D95 /* makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = makefile; sourceTree = "<group>"; };
051A8EEA1C55CD1400AB4D95 /* minidir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = minidir.cpp; path = osd/minidir.cpp; sourceTree = "<group>"; };
050B7E8823775A04000ECB19 /* driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = driver.h; path = deps/mame/src/osd/headless/public/driver.h; sourceTree = "<group>"; };
050B7E8923775A04000ECB19 /* oecommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oecommon.h; path = deps/mame/src/osd/headless/public/oecommon.h; sourceTree = "<group>"; };
050B7E8A23775A04000ECB19 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = options.h; path = deps/mame/src/osd/headless/public/options.h; sourceTree = "<group>"; };
050B7E8B23775A04000ECB19 /* headless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = headless.h; path = deps/mame/src/osd/headless/public/headless.h; sourceTree = "<group>"; };
0510AA1B230081F3002028C1 /* inputenum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inputenum.h; path = deps/mame/src/osd/headless/public/inputenum.h; sourceTree = "<group>"; };
0510AA1C230081F3002028C1 /* osd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = osd.h; path = deps/mame/src/osd/headless/public/osd.h; sourceTree = "<group>"; };
0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = mamearcade_headless.dylib; path = deps/mame/mamearcade_headless.dylib; sourceTree = "<group>"; };
05334A951C52AEEF0066D493 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
05334A981C52AF0E0066D493 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
8C3132F7177F667D0002D0B9 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
@@ -56,10 +69,8 @@
D00A06921763763000C99008 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
D00A069F17637AB600C99008 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
D00A06A417637E9100C99008 /* MAMEGameCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAMEGameCore.h; sourceTree = "<group>"; };
D00A06A517637E9100C99008 /* MAMEGameCore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MAMEGameCore.mm; sourceTree = "<group>"; };
D00A06A717637EB500C99008 /* OEArcadeSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEArcadeSystemResponderClient.h; path = ../OpenEmu/Arcade/OEArcadeSystemResponderClient.h; sourceTree = "<group>"; };
D00DAE0A176E1E6900F58FBB /* osx_osd_interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = osx_osd_interface.h; path = osd/osx_osd_interface.h; sourceTree = "<group>"; };
D00DAE0B176E1E6900F58FBB /* osx_osd_interface.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = osx_osd_interface.mm; path = osd/osx_osd_interface.mm; sourceTree = "<group>"; };
D00A06A517637E9100C99008 /* MAMEGameCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAMEGameCore.m; sourceTree = "<group>"; };
D00A06A717637EB500C99008 /* OEArcadeSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEArcadeSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/Arcade/OEArcadeSystemResponderClient.h; sourceTree = "<group>"; };
D0AADE2F176381FB00759E26 /* MAME_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAME_Prefix.pch; sourceTree = "<group>"; };
D0AADE30176382F900759E26 /* OpenEmuBase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenEmuBase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D0AADE331763838A00759E26 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -71,11 +82,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
051A8EE71C55CCCB00AB4D95 /* libmame_x64.a in Frameworks */,
05334A991C52AF0E0066D493 /* CoreAudio.framework in Frameworks */,
05334A961C52AEEF0066D493 /* CoreMIDI.framework in Frameworks */,
0510AA1E2300825E002028C1 /* mamearcade_headless.dylib in Frameworks */,
D00A068E1763763000C99008 /* Cocoa.framework in Frameworks */,
8C3132F8177F667D0002D0B9 /* OpenGL.framework in Frameworks */,
D0AADE31176382F900759E26 /* OpenEmuBase.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -83,23 +91,13 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
051A8EE51C55CC7900AB4D95 /* lib */ = {
isa = PBXGroup;
children = (
051A8EE81C55CCD300AB4D95 /* makefile */,
051A8EE61C55CCCB00AB4D95 /* libmame_x64.a */,
);
path = lib;
sourceTree = "<group>";
};
D00A06811763762F00C99008 = {
isa = PBXGroup;
children = (
D00A06A317637BDD00C99008 /* Classes */,
051A8EE51C55CC7900AB4D95 /* lib */,
D0AADE2E176381E900759E26 /* Other Sources */,
D00A06931763763000C99008 /* Resources */,
D00A068C1763763000C99008 /* Frameworks and Libraries */,
D00A068C1763763000C99008 /* Frameworks */,
D00A068B1763763000C99008 /* Products */,
);
sourceTree = "<group>";
@@ -112,14 +110,15 @@
name = Products;
sourceTree = "<group>";
};
D00A068C1763763000C99008 /* Frameworks and Libraries */ = {
D00A068C1763763000C99008 /* Frameworks */ = {
isa = PBXGroup;
children = (
0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */,
D0AADE30176382F900759E26 /* OpenEmuBase.framework */,
D00A068F1763763000C99008 /* Linked Frameworks */,
D0AADE321763833600759E26 /* Other Frameworks */,
);
name = "Frameworks and Libraries";
name = Frameworks;
sourceTree = "<group>";
};
D00A068F1763763000C99008 /* Linked Frameworks */ = {
@@ -139,7 +138,6 @@
D00A069F17637AB600C99008 /* Info.plist */,
);
name = Resources;
path = MAME;
sourceTree = "<group>";
};
D00A06A317637BDD00C99008 /* Classes */ = {
@@ -147,7 +145,7 @@
children = (
D00A06A717637EB500C99008 /* OEArcadeSystemResponderClient.h */,
D00A06A417637E9100C99008 /* MAMEGameCore.h */,
D00A06A517637E9100C99008 /* MAMEGameCore.mm */,
D00A06A517637E9100C99008 /* MAMEGameCore.m */,
D0BA5A9517645D630033A910 /* osd */,
);
name = Classes;
@@ -174,9 +172,12 @@
D0BA5A9517645D630033A910 /* osd */ = {
isa = PBXGroup;
children = (
D00DAE0A176E1E6900F58FBB /* osx_osd_interface.h */,
D00DAE0B176E1E6900F58FBB /* osx_osd_interface.mm */,
051A8EEA1C55CD1400AB4D95 /* minidir.cpp */,
050B7E8823775A04000ECB19 /* driver.h */,
050B7E8B23775A04000ECB19 /* headless.h */,
050B7E8923775A04000ECB19 /* oecommon.h */,
050B7E8A23775A04000ECB19 /* options.h */,
0510AA1B230081F3002028C1 /* inputenum.h */,
0510AA1C230081F3002028C1 /* osd.h */,
);
name = osd;
sourceTree = "<group>";
@@ -191,6 +192,8 @@
D00A06861763763000C99008 /* Sources */,
D00A06871763763000C99008 /* Frameworks */,
D00A06881763763000C99008 /* Resources */,
0510AA2023008294002028C1 /* Embed Libraries */,
0510AA2123008883002028C1 /* ShellScript */,
);
buildRules = (
);
@@ -207,14 +210,16 @@
D00A06821763762F00C99008 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0700;
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1330;
ORGANIZATIONNAME = OpenEmu;
};
buildConfigurationList = D00A06851763762F00C99008 /* Build configuration list for PBXProject "MAME" */;
compatibilityVersion = "Xcode 3.2";
compatibilityVersion = "Xcode 10.0";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = D00A06811763762F00C99008;
@@ -239,6 +244,23 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
0510AA2123008883002028C1 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "install_name_tool -change mamearcade_headless.dylib @rpath/mamearcade_headless.dylib ${TARGET_BUILD_DIR}/${EXECUTABLE_PATH}\n";
};
D0AADE2D1763815000759E26 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -259,10 +281,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
051A8EEB1C55CD1400AB4D95 /* minidir.cpp in Sources */,
D00A06A617637E9100C99008 /* MAMEGameCore.mm in Sources */,
8CA9071017A83C08001591B7 /* osx_osd_interface.mm in Sources */,
051A8EE91C55CCD300AB4D95 /* makefile in Sources */,
D00A06A617637E9100C99008 /* MAMEGameCore.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -280,18 +299,40 @@
D00A069A1763763000C99008 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = x86_64;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "compiler-default";
CLANG_DEBUG_INFORMATION_LEVEL = default;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEAD_CODE_STRIPPING = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu89;
GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
GCC_INPUT_FILETYPE = sourcecode.cpp.cpp;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "";
@@ -300,105 +341,71 @@
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VALUE = NO;
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)\"",
"\"$(SRCROOT)/osd\"",
"\"$(SRCROOT)/mame/src/osd\"",
"\"$(SRCROOT)/mame/src/emu\"",
"\"$(SRCROOT)/mame/src/lib/util\"",
"\"$(SRCROOT)/mame/src/osd/modules/lib\"",
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CFLAGS = (
"-DMAME_DEBUG",
"-DFLAC__NO_DLL",
"-DNATIVE_DRC=drcbe_x64",
"-D__DYNAMIC__",
);
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-Woverloaded-virtual",
);
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.15;
ONLY_ACTIVE_ARCH = YES;
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SDKROOT = macosx;
USE_HEADERMAP = NO;
WARNING_CFLAGS = (
"-Wall",
"-Wcast-align",
"-Wundef",
"-Wformat-security",
"-Wwrite-strings",
"-Wno-sign-compare",
"-Wno-conversion",
"-Wno-cast-align",
"-Wno-tautological-compare",
"-Wno-constant-logical-operand",
"-Wno-shift-count-overflow",
"-Wno-self-assign-field",
"-Wno-unused-local-typedef",
);
};
name = Debug;
};
D00A069B1763763000C99008 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = x86_64;
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++14";
CLANG_CXX_LIBRARY = "compiler-default";
CLANG_DEBUG_INFORMATION_LEVEL = default;
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
DEAD_CODE_STRIPPING = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = NO;
GCC_C_LANGUAGE_STANDARD = gnu89;
GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
GCC_INPUT_FILETYPE = sourcecode.cpp.cpp;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 3;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "";
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VALUE = NO;
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)\"",
"\"$(SRCROOT)/osd\"",
"\"$(SRCROOT)/mame/src/osd\"",
"\"$(SRCROOT)/mame/src/emu\"",
"\"$(SRCROOT)/mame/src/lib/util\"",
"\"$(SRCROOT)/mame/src/osd/modules/lib\"",
);
MACOSX_DEPLOYMENT_TARGET = 10.11;
OTHER_CFLAGS = (
"-DNDEBUG",
"-DFLAC__NO_DLL",
"-DNATIVE_DRC=drcbe_x64",
"-fno-strict-aliasing",
"-D__DYNAMIC__",
);
OTHER_CPLUSPLUSFLAGS = (
"$(OTHER_CFLAGS)",
"-Woverloaded-virtual",
);
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 10.15;
PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
SDKROOT = macosx;
USE_HEADERMAP = NO;
WARNING_CFLAGS = (
"-Wall",
"-Wcast-align",
"-Wundef",
"-Wformat-security",
"-Wwrite-strings",
"-Wno-sign-compare",
"-Wno-conversion",
"-Wno-cast-align",
"-Wno-tautological-compare",
"-Wno-constant-logical-operand",
"-Wno-shift-count-overflow",
"-Wno-self-assign-field",
"-Wno-unused-local-typedef",
);
};
name = Release;
};
@@ -406,24 +413,22 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 0.250.0.1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
GCC_PRECOMPILE_PREFIX_HEADER = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"PTR64=1",
"CRLF=2",
LSB_FIRST,
SDLMAME_DARWIN,
"USE_OPENGL=1",
"DEBUG=1",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../OpenEmu/Arcade\"",
"$(SRCROOT)/deps/mame/src/osd/headless/public",
);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "\"$(USER_LIBRARY_DIR)/Application Support/OpenEmu/Cores\"";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/lib";
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/deps/mame",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.openemu.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -435,23 +440,22 @@
isa = XCBuildConfiguration;
buildSettings = {
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 0.250.0.1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
GCC_PRECOMPILE_PREFIX_HEADER = NO;
GCC_PREPROCESSOR_DEFINITIONS = (
"PTR64=1",
"CRLF=2",
LSB_FIRST,
SDLMAME_DARWIN,
"USE_OPENGL=1",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)/../OpenEmu/Arcade\"",
"$(SRCROOT)/deps/mame/src/osd/headless/public",
);
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "\"$(USER_LIBRARY_DIR)/Application Support/OpenEmu/Cores\"";
LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/lib";
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/deps/mame",
);
PRODUCT_BUNDLE_IDENTIFIER = "org.openemu.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
+2 -9
View File
@@ -27,16 +27,9 @@
#import <Cocoa/Cocoa.h>
#import <OpenEmuBase/OEGameCore.h>
#import "OEArcadeSystemResponderClient.h"
#import "osdcomm.h"
class running_machine;
#import "osd.h"
OE_EXPORTED_CLASS
@interface MAMEGameCore : OEGameCore
- (void)osd_init:(running_machine *)machine;
- (void)osd_exit:(running_machine *)machine;
- (void)osd_update:(bool)skip_redraw;
- (void)osd_update_audio_stream:(const INT16 *)buffer samples:(int)samples_this_frame;
@interface MAMEGameCore : OEGameCore<OSDDelegate>
@end
+585
View File
@@ -0,0 +1,585 @@
/*
Copyright (c) 2013, OpenEmu Team
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the OpenEmu Team nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "MAMEGameCore.h"
#import <OpenEmuBase/OERingBuffer.h>
#import <OpenGL/gl.h>
#import <os/log.h>
@interface MAMEAuditResult: NSObject
/*! Returns the unique identifier of this result
*
* @remarks
*
* Identifier which groups resources by their driver, parent or CHD name
*/
@property (nonatomic, readonly) NSString *identifier;
@property (nonatomic, readonly) NSString *fileName;
- (instancetype)initWithDriver:(NSString *)driver auditRecord:(AuditRecord *)record;
- (BOOL)checkSetExistsInDir:(NSURL *)dir;
@end
@interface MAMEGameCore () <OEArcadeSystemResponderClient>
{
uint32_t _buttons[8][OEArcadeButtonCount];
uint32_t _axes[8][InputMaxAxis];
uint32_t *_buffer;
OEIntSize _bufferSize;
OEIntRect _screenRect;
OEIntSize _aspectSize;
NSTimeInterval _frameInterval;
// dylib
void *_handle;
OSD *_osd;
BOOL _supportsRewinding;
}
@end
static int32_t joystick_get_state(void *device_internal, void *item_internal)
{
return *(int32_t *)item_internal;
}
static os_log_t OE_CORE_LOG, OE_CORE_AUDIT_LOG;
@implementation MAMEGameCore
#pragma mark - Lifecycle
+ (void)initialize
{
OE_CORE_LOG = os_log_create("org.openemu.MAME", "");
OE_CORE_AUDIT_LOG = os_log_create("org.openemu.MAME", "audit");
}
- (id)init
{
self = [super init];
if(!self)
{
return nil;
}
// Sensible defaults
_bufferSize = OEIntSizeMake(1024, 1024);
_frameInterval = 60;
_screenRect = { {0,0}, _bufferSize };
_aspectSize = { 4, 3 };
_osd = [OSD shared];
_osd.delegate = self;
return self;
}
#pragma mark - OSDDelegate
- (void)didInitialize
{
// initialize joysticks
for (int i = 0; i < 8; i++) {
NSString *name = [NSString stringWithFormat:@"OpenEmu Player %d", i];
InputDevice *dev = [_osd.joystick addDeviceNamed:name];
[dev addItemNamed:@"X Axis" id:InputItemID_XAXIS getter:joystick_get_state context:&_axes[i][0]];
[dev addItemNamed:@"Y Axis" id:InputItemID_YAXIS getter:joystick_get_state context:&_axes[i][1]];
[dev addItemNamed:@"Start" id:InputItemID_START getter:joystick_get_state context:&_buttons[i][OEArcadeButtonP1Start]];
[dev addItemNamed:@"Insert Coin" id:InputItemID_SELECT getter:joystick_get_state context:&_buttons[i][OEArcadeButtonInsertCoin]];
[dev addItemNamed:@"Button 1" id:InputItemID_BUTTON1 getter:joystick_get_state context:&_buttons[i][OEArcadeButton1]];
[dev addItemNamed:@"Button 2" id:InputItemID_BUTTON2 getter:joystick_get_state context:&_buttons[i][OEArcadeButton2]];
[dev addItemNamed:@"Button 3" id:InputItemID_BUTTON3 getter:joystick_get_state context:&_buttons[i][OEArcadeButton3]];
[dev addItemNamed:@"Button 4" id:InputItemID_BUTTON4 getter:joystick_get_state context:&_buttons[i][OEArcadeButton4]];
[dev addItemNamed:@"Button 5" id:InputItemID_BUTTON5 getter:joystick_get_state context:&_buttons[i][OEArcadeButton5]];
[dev addItemNamed:@"Button 6" id:InputItemID_BUTTON6 getter:joystick_get_state context:&_buttons[i][OEArcadeButton6]];
}
// Special keys
InputDevice *kb = [_osd.keyboard addDeviceNamed:@"OpenEmu Keyboard"];
[kb addItemNamed:@"Service" id:InputItemID_F2 getter:joystick_get_state context:&_buttons[0][OEArcadeButtonService]];
[kb addItemNamed:@"UI Configure" id:InputItemID_TAB getter:joystick_get_state context:&_buttons[0][OEArcadeUIConfigure]];
}
- (void)didChangeDisplayBounds:(NSSize)bounds fps:(double)fps aspect:(NSSize)aspect
{
_screenRect = {{0, 0}, OEIntSizeMake(bounds.width, bounds.height)};
// for single screen games:
BOOL singleScreen = YES;
if (singleScreen)
{
CGFloat newHeight = (aspect.height / aspect.width) * bounds.width;
_aspectSize = OEIntSizeMake(bounds.width, newHeight);
}
else
{
_aspectSize = OEIntSizeMake(bounds.width, bounds.height);
}
_frameInterval = fps;
}
- (void)updateAudioBuffer:(const int16_t *)buffer samples:(NSInteger)samples
{
id<OEAudioBuffer> buf = [self audioBufferAtIndex:0];
[buf write:buffer maxLength:samples * 2 * sizeof(int16_t)];
}
- (void)logLevel:(OSDLogLevel)level message:(NSString *)msg
{
switch (level) {
case OSDLogLevelError:
os_log_error(OE_CORE_LOG, "%{public}s", msg.UTF8String);
break;
case OSDLogLevelVerbose:
os_log_debug(OE_CORE_LOG, "%{public}s", msg.UTF8String);
break;
default:
os_log_info(OE_CORE_LOG, "%{public}s", msg.UTF8String);
break;
}
}
#pragma mark - Execution
BOOL driverIsNotWorking(GameDriverOptions o)
{
if ((o & GameDriverMachineNotWorking) == GameDriverMachineNotWorking) {
return YES;
}
if ((o & GameDriverMachineIsSkeleton) == GameDriverMachineIsSkeleton) {
return YES;
}
return NO;
}
- (BOOL)validateGameDriver:(GameDriver *)driver error:(NSError **)error
{
GameDriverOptions o = driver.flags;
if (o & (GameDriverMachineClickableArtwork | GameDriverMachineRequiresArtwork | GameDriverMachineMechanical))
{
if (error != nil)
{
*error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:@{
NSLocalizedDescriptionKey : @"Unable to load ROM.",
NSLocalizedRecoverySuggestionErrorKey: [NSString stringWithFormat:@"\"%@\" (%@).\n\nMechanical systems or systems which require artwork to operate are not supported.", driver.fullName, driver.name],
}];
}
return NO;
}
if (driverIsNotWorking(o)) {
if (error != nil)
{
*error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:@{
NSLocalizedDescriptionKey : @"Unable to load ROM.",
NSLocalizedRecoverySuggestionErrorKey: [NSString stringWithFormat:@"\"%@\" (%@).\n\nThis machine does not work and the emulation is not yet complete. There is nothing you can do to fix this problem except wait for the MAME developers to improve the emulation.", driver.fullName, driver.name],
}];
}
return NO;
}
return YES;
}
- (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error
{
NSString *romDir = [path stringByDeletingLastPathComponent];
Options *opts = _osd.options;
[opts setBasePath:self.supportDirectoryPath];
opts.romsPath = romDir;
BOOL prev;
prev = opts.autoStretchXY;
opts.autoStretchXY = NO;
prev = opts.unevenStretchX;
opts.unevenStretchX = NO;
prev = opts.unevenStretchY;
opts.unevenStretchY = NO;
prev = opts.unevenStretch;
opts.unevenStretch = NO;
opts.keepAspect = YES;
_osd.verboseOutput = NO; // TODO: debug only; remove later
NSString *rom = [[path lastPathComponent] stringByDeletingPathExtension];
AuditResult *ar;
BOOL success = [_osd setDriver:rom withAuditResult:&ar error:error];
if (!success)
{
return NO;
}
if (![self validateGameDriver:_osd.driver error:error])
{
return NO;
}
if (ar.summary == AuditSummaryIncorrect || ar.summary == AuditSummaryNotFound)
{
if (error != nil)
{
*error = [self processAuditResult:ar forRomDir:romDir];
}
return NO;
}
if (![_osd initializeWithError:error])
{
return NO;
}
_supportsRewinding = _osd.supportsSave && _osd.stateSize < 1e6;
if (_osd.supportsSave && !_supportsRewinding)
{
os_log_info(OE_CORE_LOG, "disabling rewind support, save state size too big %{iec-bytes}ld", _osd.stateSize);
}
return YES;
}
- (NSError *)processAuditResult:(AuditResult *)ar forRomDir:(NSString *)romDir
{
GameDriver *driver = _osd.driver;
NSString *gameDriverName = driver.name;
NSMutableOrderedSet<MAMEAuditResult *> *results = [NSMutableOrderedSet new];
for (AuditRecord *rec in ar.records) {
switch (rec.substatus) {
case AuditSubstatusGood:
continue;
case AuditSubstatusFoundNodump:
case AuditSubstatusGoodNeedsRedump:
case AuditSubstatusNotFoundNoDump:
case AuditSubstatusNotFoundOptional:
// acceptable conditions, based on audit.cpp:media_auditor::summarize method,
// which all result in a BEST_AVAILABLE status
continue;
// bad conditions
case AuditSubstatusFoundWrongLength: {
os_log_debug(OE_CORE_AUDIT_LOG, "wrong length: %{public}@, media type %ld", rec.name, rec.mediaType);
[results addObject:[[MAMEAuditResult alloc] initWithDriver:gameDriverName auditRecord:rec]];
break;
}
case AuditSubstatusFoundBadChecksum: {
os_log_debug(OE_CORE_AUDIT_LOG, "bad checksum: %{public}@, media type %ld", rec.name, rec.mediaType);
[results addObject:[[MAMEAuditResult alloc] initWithDriver:gameDriverName auditRecord:rec]];
break;
}
case AuditSubstatusNotFound: {
os_log_debug(OE_CORE_AUDIT_LOG, "not found: %{public}@, media type %ld", rec.name, rec.mediaType);
[results addObject:[[MAMEAuditResult alloc] initWithDriver:gameDriverName auditRecord:rec]];
break;
}
case AuditSubstatusUnverified:
default:
continue;
}
}
// Sort missing files by ascending order
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self"
ascending:YES];
[results sortUsingDescriptors:@[sortDescriptor]];
// Determine if ROMs exist with missing files, or are not found
NSURL *romDirURL = [NSURL fileURLWithPath:romDir isDirectory:YES];
NSMutableString *missingFilesList = [NSMutableString string];
for(MAMEAuditResult *result in results)
{
if ([result checkSetExistsInDir:romDirURL])
{
[missingFilesList appendString:[NSString stringWithFormat:@"%@ \t- INCORRECT SET\n", result.fileName]];
}
else
{
[missingFilesList appendString:[NSString stringWithFormat:@"%@ \t- NOT FOUND\n", result.fileName]];
}
}
// Give an audit report to the user
NSString *game = [NSString stringWithFormat:@"%@ (%@.zip)", driver.fullName, gameDriverName];
NSString *versionRequired = [[[[[self owner] bundle] infoDictionary] objectForKey:@"CFBundleVersion"] substringToIndex:5];
NSError *outErr = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:@{
NSLocalizedDescriptionKey : @"Required files are missing.",
NSLocalizedRecoverySuggestionErrorKey : [NSString stringWithFormat:@"%@ requires:\n\n%@\nThese ROMs must be from a MAME %@ ROM set. Some of these files can be parent/device/BIOS ROMs, which are not part of the game, but are still required. Delete files already imported and reimport with correct files.", game, missingFilesList, versionRequired],
}];
return outErr;
}
- (void)resetEmulation
{
[_osd scheduleHardReset];
}
#pragma mark - Video
- (const void *)getVideoBufferWithHint:(void *)hint
{
_buffer = (uint32_t *)hint;
[_osd setBuffer:hint size:NSSizeFromOEIntSize(_bufferSize)];
return _buffer;
}
- (OEIntSize)bufferSize
{
return _bufferSize;
}
- (OEIntRect)screenRect {
return _screenRect;
}
- (OEIntSize)aspectSize
{
return _aspectSize;
}
- (GLenum)pixelFormat
{
return GL_BGRA;
}
- (GLenum)pixelType
{
return GL_UNSIGNED_INT_8_8_8_8_REV;
}
#pragma mark - execution
- (void)executeFrame
{
[_osd execute];
}
- (void)stopEmulation
{
[_osd unload];
_osd.delegate = nil;
[super stopEmulation];
}
- (NSTimeInterval)frameInterval
{
return _frameInterval;
}
#pragma mark - Audio
- (double)audioSampleRate
{
return 48000;
}
- (NSUInteger)channelCount
{
return 2;
}
#pragma mark - Input
- (void)setState:(BOOL)pressed ofButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
{
_buttons[player-1][button] = pressed ? 1 : 0;
_axes[player-1][0] = _buttons[player-1][OEArcadeButtonLeft] ? InputAbsoluteMin : (_buttons[player-1][OEArcadeButtonRight] ? InputAbsoluteMax : 0);
_axes[player-1][1] = _buttons[player-1][OEArcadeButtonUp] ? InputAbsoluteMin : (_buttons[player-1][OEArcadeButtonDown] ? InputAbsoluteMax : 0);
}
- (oneway void)didPushArcadeButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
{
[self setState:YES ofButton:button forPlayer:player];
}
- (oneway void)didReleaseArcadeButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
{
[self setState:NO ofButton:button forPlayer:player];
}
#pragma mark - Save State
- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
{
BOOL res = NO;
NSError *err = nil;
if (_osd.supportsSave)
{
res = [_osd saveStateFromFileAtPath:fileName error:&err];
}
else
{
err = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotSaveStateError userInfo:@{
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Game \"%@\" does not not support save states.", _osd.driver.fullName],
}];
}
block(res, err);
}
- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
{
BOOL res = NO;
NSError *err = nil;
if (_osd.supportsSave)
{
res = [_osd loadStateFromFileAtPath:fileName error:&err];
}
else
{
err = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotSaveStateError userInfo:@{
NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Game \"%@\" does not not support save states.", _osd.driver.fullName],
}];
}
block(res, err);
}
- (BOOL)supportsRewinding
{
return _supportsRewinding;
}
- (NSData *)serializeStateWithError:(NSError *__autoreleasing *)outError
{
return [_osd serializeState];
}
- (BOOL)deserializeState:(NSData *)state withError:(NSError *__autoreleasing *)outError
{
return [_osd deserializeState:state];
}
@end
@implementation MAMEAuditResult
{
NSString *_driver;
AuditRecord *_record;
}
- (instancetype)initWithDriver:(NSString *)driver auditRecord:(AuditRecord *)record
{
if ((self = [super init]))
{
_driver = driver;
_record = record;
}
return self;
}
- (NSString *)identifier
{
if (_record.mediaType == AuditMediaTypeDisk)
{
// a CHD
return _record.name;
}
Device *parent = _record.sharedDevice;
if (parent)
{
return parent.shortName;
}
return _driver;
}
- (NSArray<NSString *> *)extensions
{
if (_record.mediaType == AuditMediaTypeDisk)
{
return @[@".chd"];
}
return @[@".zip", @".7z"];
}
- (BOOL)isEqual:(id)object
{
if (object == nil || ![object isKindOfClass:self.class])
{
return NO;
}
MAMEAuditResult *other = (MAMEAuditResult *)object;
return self.identifier == other.identifier;
}
- (NSComparisonResult)compare:(MAMEAuditResult *)other
{
return [self.identifier compare:other.identifier];
}
/*! Returns the first valid file name for this result
*/
- (NSString *)fileName
{
return [self.identifier stringByAppendingString:[[self extensions] firstObject]];
}
/*! Determines if the ROM set exists
*/
- (BOOL)checkSetExistsInDir:(NSURL *)dir
{
for (NSString *ext in [self extensions])
{
NSURL *missingFileURL = [dir URLByAppendingPathComponent:[self.identifier stringByAppendingString:ext]];
if([missingFileURL checkResourceIsReachableAndReturnError:nil])
{
return YES;
}
}
return NO;
}
- (NSUInteger)hash
{
return self.identifier.hash;
}
@end
-586
View File
@@ -1,586 +0,0 @@
/*
Copyright (c) 2013, OpenEmu Team
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the OpenEmu Team nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "MAMEGameCore.h"
#import <OpenEmuBase/OERingBuffer.h>
#import <OpenGL/gl.h>
#include "emu.h"
#include "render.h"
#include "emuopts.h"
#include "audit.h"
#include "mame.h"
#include "osx_osd_interface.h"
@interface MAMEGameCore () <OEArcadeSystemResponderClient>
{
running_machine *_machine;
render_target *_target;
INT32 _buttons[8][OEArcadeButtonCount];
INT32 _axes[8][INPUT_MAX_AXIS];
dispatch_semaphore_t _renderEvent;
dispatch_semaphore_t _exitEvent;
GLuint _texture;
GLuint _textureWidth;
GLuint _textureHeight;
uint32_t *_buffer;
NSString *_romDir;
NSString *_driverName;
NSString *_stateDir;
NSString *_stateFile;
NSFileManager *_fileManager;
NSTimeInterval _frameInterval;
OEIntSize _bufferSize;
BOOL _initializing;
}
- (void)waitForSaveOrLoad;
@end
static void error_callback(const running_machine &machine, const char *string)
{
// NSLog(@"MAME: %s", string);
}
static INT32 joystick_get_state(void *device_internal, void *item_internal)
{
return *(INT32 *)item_internal;
}
@implementation MAMEGameCore
#pragma mark - Lifecycle
- (id)init
{
self = [super init];
if(!self)
{
return nil;
}
_initializing = YES;
_renderEvent = dispatch_semaphore_create(0);
_exitEvent = dispatch_semaphore_create(0);
// Sensible defaults
_bufferSize = OEIntSizeMake(640, 480);
_frameInterval = 60;
_fileManager = [NSFileManager new];
return self;
}
- (void)dealloc
{
_renderEvent = nil;
_exitEvent = nil;
if(_buffer)
{
free(_buffer);
_buffer = NULL;
}
}
- (void)osd_init:(running_machine *)machine
{
_machine = machine;
_stateDir = [NSString pathWithComponents:@[NSTemporaryDirectory(), @"openemu", @"mame"]];
NSString *basename = [NSString stringWithCString:_machine->basename() encoding:NSASCIIStringEncoding];
_stateFile = [NSString pathWithComponents:@[_stateDir, basename, @"gamestate.sta"]];
[_fileManager createDirectoryAtPath:[_stateFile stringByDeletingLastPathComponent]
withIntermediateDirectories:YES
attributes:nil
error:nil];
std::string err;
_machine->options().set_value(OPTION_STATE_DIRECTORY, [_stateDir UTF8String], OPTION_PRIORITY_HIGH, err);
_machine->add_logerror_callback(error_callback);
_target = _machine->render().target_alloc();
_frameInterval = (NSTimeInterval) ATTOSECONDS_PER_SECOND / _machine->first_screen()->refresh_attoseconds();
NSLog(@"Refresh rate set to %f Hz", _frameInterval);
INT32 width = 0, height = 0;
_target->compute_minimum_size(width, height);
if(width > 0 && height > 0) _bufferSize = OEIntSizeMake(width, height);
_target->set_bounds(_bufferSize.width, _bufferSize.height);
// Add devices for 8 players
for (int i = 0; i < 8; i++) {
input_device *input = _machine->input().device_class(DEVICE_CLASS_JOYSTICK).add_device([[NSString stringWithFormat:@"OpenEmu Device %d", i] UTF8String], NULL);
input->add_item("X Axis", ITEM_ID_XAXIS, joystick_get_state, &_axes[i][0]);
input->add_item("Y Axis", ITEM_ID_YAXIS, joystick_get_state, &_axes[i][1]);
input->add_item("Start", ITEM_ID_START, joystick_get_state, &_buttons[i][OEArcadeButtonP1Start]);
input->add_item("Select", ITEM_ID_SELECT, joystick_get_state, &_buttons[i][OEArcadeButtonInsertCoin]);
input->add_item("Button 1", ITEM_ID_BUTTON1, joystick_get_state, &_buttons[i][OEArcadeButton1]);
input->add_item("Button 2", ITEM_ID_BUTTON2, joystick_get_state, &_buttons[i][OEArcadeButton2]);
input->add_item("Button 3", ITEM_ID_BUTTON3, joystick_get_state, &_buttons[i][OEArcadeButton3]);
input->add_item("Button 4", ITEM_ID_BUTTON4, joystick_get_state, &_buttons[i][OEArcadeButton4]);
input->add_item("Button 5", ITEM_ID_BUTTON5, joystick_get_state, &_buttons[i][OEArcadeButton5]);
input->add_item("Button 6", ITEM_ID_BUTTON6, joystick_get_state, &_buttons[i][OEArcadeButton6]);
}
// Special keys
input_device *inputKeys = _machine->input().device_class(DEVICE_CLASS_KEYBOARD).add_device("OpenEmu Keys", NULL);
inputKeys->add_item("Service", ITEM_ID_F2, joystick_get_state, &_buttons[0][OEArcadeButtonService]);
_initializing = NO;
}
- (void)osd_exit:(running_machine *)machine
{
NSParameterAssert(_machine == machine);
_machine->render().target_free(_target);
_target = NULL;
_machine = NULL;
dispatch_semaphore_signal(_exitEvent);
}
#pragma mark - Execution
- (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error
{
_romDir = [path stringByDeletingLastPathComponent];
if(!_romDir) return NO;
// Need a better way to identify the ROM driver from the archive path
// The code below works by hashing the individual files and checking each
// but takes *forever* and does not scale at O(n)
//media_identifier ident(options);
//ident.identify([path cStringUsingEncoding:NSUTF8StringEncoding]);
//NSLog(@"I found this many matches: %i", ident.matches());
// The temporary solution is to take the file basename
// Easily broken by misnamed ROM archives
_driverName = [[path lastPathComponent] stringByDeletingPathExtension];
std::string err;
emu_options options = emu_options();
options.set_value(OPTION_MEDIAPATH, [_romDir UTF8String], OPTION_PRIORITY_HIGH, err);
game_driver driver;
driver_enumerator drivlist(options, [_driverName UTF8String]);
media_auditor auditor(drivlist);
BOOL verified = NO;
while(drivlist.next() && !verified)
{
media_auditor::summary summary = auditor.audit_media(AUDIT_VALIDATE_FAST);
if(summary == media_auditor::CORRECT || summary == media_auditor::BEST_AVAILABLE)
{
driver = drivlist.driver();
verified = YES;
}
else
{
std::string *output = new std::string();
auditor.summarize(drivlist.driver().name, output);
NSString *message = [NSString stringWithCString:output->c_str() encoding:NSASCIIStringEncoding];
delete output;
NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: message };
*error = [NSError errorWithDomain:OEGameCoreErrorDomain code:-1 userInfo:userInfo];
}
}
return verified;
}
- (void)startEmulation
{
[super startEmulation];
[NSThread detachNewThreadSelector:@selector(mameEmuThread) toTarget:self withObject:nil];
}
- (void)stopEmulation
{
if(_machine != NULL) _machine->schedule_exit();
// Wait for MAME to shut down correctly
dispatch_semaphore_wait(_exitEvent, dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC));
if(_texture)
{
glDeleteTextures(1, &_texture);
_texture = 0;
}
[super stopEmulation];
}
- (void)setPauseEmulation:(BOOL)pauseEmulation
{
if(_machine != NULL)
{
if(pauseEmulation) _machine->pause();
else _machine->resume();
}
[super setPauseEmulation:pauseEmulation];
}
- (void)resetEmulation
{
if(_machine != NULL) _machine->schedule_hard_reset();
}
- (void)mameEmuThread
{
std::string err;
osd_options options = osd_options();
options.set_value(OPTION_MEDIAPATH, [_romDir UTF8String], OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_SAMPLEPATH,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"samples"] UTF8String],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_CFG_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"cfg"] UTF8String],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_NVRAM_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"nvram"]UTF8String],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_INPUT_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"inp"] UTF8String],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_DIFF_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"diff"] UTF8String],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_COMMENT_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"comments"] UTF8String],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_SYSTEMNAME, [_driverName UTF8String], OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_SAMPLERATE, (int)[self audioSampleRate], OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_SKIP_GAMEINFO, true, OPTION_PRIORITY_HIGH, err);
#if 0
options.set_value(OPTION_VERBOSE, true, OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_LOG, true, OPTION_PRIORITY_HIGH, err);
#endif
osx_osd_interface osd = osx_osd_interface(self, options);
osd.register_options();
DLog(@"MAME: Starting game execution thread");
machine_manager *manager = machine_manager::instance(options, osd);
manager->execute();
global_free(manager);
DLog(@"MAME: Game execution thread exiting");
}
#pragma mark - Video
- (OEGameCoreRendering)gameCoreRendering
{
return OEGameCoreRenderingOpenGL2Video;
}
- (OEIntSize)bufferSize
{
return _bufferSize;
}
- (OEIntSize)aspectSize
{
if(_machine != NULL)
{
switch(_machine->system().flags & ORIENTATION_MASK)
{
case ROT0:
case ROT180:
return OEIntSizeMake(4, 3);
break;
case ROT90:
case ROT270:
return OEIntSizeMake(3, 4);
break;
default:
break;
}
}
return OEIntSizeMake(4, 3);
}
- (void)osd_update:(bool)skip_redraw
{
if (!skip_redraw && !_machine->save_or_load_pending())
{
dispatch_semaphore_wait(_renderEvent, dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC));
}
}
- (void)executeFrame
{
if(self.shouldSkipFrame || _target == NULL) return;
if(!_texture)
{
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glGenTextures(1, &_texture);
}
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glDisable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0.0, 0.0, (GLsizei)_bufferSize.width, (GLsizei)_bufferSize.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)_bufferSize.width, (GLdouble)_bufferSize.height, 0.0, 0.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnableClientState(GL_VERTEX_ARRAY);
render_primitive_list &primitives = _target->get_primitives();
primitives.acquire_lock();
for(render_primitive *prim = primitives.first(); prim != NULL; prim = prim->next())
{
GLfloat color[4];
color[0] = prim->color.r;
color[1] = prim->color.g;
color[2] = prim->color.b;
color[3] = prim->color.a;
switch(PRIMFLAG_GET_BLENDMODE(prim->flags))
{
case BLENDMODE_NONE:
glDisable(GL_BLEND);
break;
case BLENDMODE_ALPHA:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case BLENDMODE_RGB_MULTIPLY:
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
break;
case BLENDMODE_ADD:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
break;
default:
break;
}
if(prim->type == render_primitive::LINE)
{
GLfloat vertices[] = { prim->bounds.x0, prim->bounds.y0, prim->bounds.x1, prim->bounds.y1 };
glColor4fv(color);
BOOL line = ((prim->bounds.x1 != prim->bounds.x0) || (prim->bounds.y1 != prim->bounds.y0));
if(line) glLineWidth(prim->width);
else glPointSize(prim->width);
glVertexPointer(2, GL_FLOAT, 0, vertices);
if(line) glDrawArrays(GL_LINES, 0, 2);
else glDrawArrays(GL_POINTS, 0, 1);
}
else if(prim->type == render_primitive::QUAD)
{
GLfloat vertices[] = { prim->bounds.x0, prim->bounds.y1,
prim->bounds.x0, prim->bounds.y0,
prim->bounds.x1, prim->bounds.y1,
prim->bounds.x1, prim->bounds.y0 };
glVertexPointer(2, GL_FLOAT, 0, vertices);
if(prim->texture.base == NULL)
{
glColor4fv(color);
glLineWidth(1.0f);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
else
{
render_texinfo texinfo = prim->texture;
unsigned int width = texinfo.width, height = texinfo.height, rowpixels = texinfo.rowpixels;
if(_buffer) { free(_buffer); _buffer = NULL; }
int texformat = PRIMFLAG_GET_TEXFORMAT(prim->flags);
if(texformat == TEXFORMAT_PALETTE16 || texformat == TEXFORMAT_PALETTEA16)
{
uint32_t *bufferPointer = _buffer = (uint32_t *) malloc(width * height * sizeof(uint32_t));
uint16_t *base = (uint16_t *)texinfo.base;
for(int y = 0; y < height; ++y)
{
for(int x = 0; x < width; ++x)
*bufferPointer++ = texinfo.palette[*base++];
base += rowpixels - width;
}
rowpixels = width;
}
glEnable(GL_TEXTURE_RECTANGLE_EXT);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
// Resize if the texture isn't big enough
if(rowpixels > _textureWidth || height > _textureHeight)
{
_textureWidth = MAX(rowpixels, _textureWidth);
_textureHeight = MAX(height, _textureHeight);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA8, _textureWidth, _textureHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _buffer ?: texinfo.base);
}
else
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, _buffer ? width : rowpixels, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, _buffer ?: texinfo.base);
GLfloat texCoords[] = { width * prim->texcoords.bl.u, height * prim->texcoords.bl.v,
width * prim->texcoords.tl.u, height * prim->texcoords.tl.v,
width * prim->texcoords.br.u, height * prim->texcoords.br.v,
width * prim->texcoords.tr.u, height * prim->texcoords.tr.v };
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_RECTANGLE_EXT);
}
}
}
glFlushRenderAPPLE();
primitives.release_lock();
dispatch_semaphore_signal(_renderEvent);
}
- (NSTimeInterval)frameInterval
{
return _frameInterval;
}
#pragma mark - Audio
- (void)osd_update_audio_stream:(const INT16 *)buffer samples:(int)samples_this_frame
{
OERingBuffer *ringBuffer = [self ringBufferAtIndex:0];
NSUInteger bytesPerSample = (self.audioBitDepth * self.channelCount) / 8;
NSUInteger bytesToWrite = samples_this_frame * bytesPerSample;
NSUInteger bytesAvailableToWrite = ringBuffer.availableBytes;
if(bytesToWrite > bytesAvailableToWrite)
{
NSLog(@"MAME: Audio buffer overflow");
bytesToWrite = bytesAvailableToWrite;
}
[ringBuffer write:buffer maxLength:bytesToWrite];
}
- (double)audioSampleRate
{
return 48000;
}
- (NSUInteger)channelCount
{
return 2;
}
#pragma mark - Input
- (void)setState:(BOOL)pressed ofButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
{
_buttons[player-1][button] = pressed ? 1 : 0;
_axes[player-1][0] = _buttons[player-1][OEArcadeButtonLeft] ? INPUT_ABSOLUTE_MIN : (_buttons[player-1][OEArcadeButtonRight] ? INPUT_ABSOLUTE_MAX : 0);
_axes[player-1][1] = _buttons[player-1][OEArcadeButtonUp] ? INPUT_ABSOLUTE_MIN : (_buttons[player-1][OEArcadeButtonDown] ? INPUT_ABSOLUTE_MAX : 0);
}
- (oneway void)didPushArcadeButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
{
[self setState:YES ofButton:button forPlayer:player];
}
- (oneway void)didReleaseArcadeButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
{
[self setState:NO ofButton:button forPlayer:player];
}
#pragma mark - Save State
- (void)waitForSaveOrLoad {
while (_machine->save_or_load_pending())
{
usleep(50 * 1000);
}
}
- (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
{
BOOL saved = NO;
if(_machine != NULL && _machine->system().flags & MACHINE_SUPPORTS_SAVE)
{
_machine->schedule_save("gamestate");
[self waitForSaveOrLoad];
[_fileManager moveItemAtPath:_stateFile toPath:fileName error:nil];
saved = YES;
}
block(saved, nil);
}
- (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
{
// Wait until machine is initialized and ready to load a save state
while(_initializing) usleep(100);
BOOL loaded = NO;
if(_machine != NULL && _machine->system().flags & MACHINE_SUPPORTS_SAVE)
{
[_fileManager removeItemAtPath:_stateFile error:nil];
[_fileManager copyItemAtPath:fileName toPath:_stateFile error:nil];
_machine->schedule_load("gamestate");
[self waitForSaveOrLoad];
loaded = YES;
}
block(loaded, nil);
}
@end
+8 -15
View File
@@ -6,22 +6,15 @@ OpenEmu Core plugin for UME
Building
--------
You must build the `libmame_x64.a` static library before building the MAME Game core, outlined in the following steps.
You must build the `mamearcade_headless.dylib` dynamic library before building the MAME Game core:
**Step 1: Apply patch**
```sh
$ cd deps/mame
$ make macosx_x64_clang OSD="headless" verbose=1 TARGETOS="macosx" CONFIG="release" TARGET=mame SUBTARGET=arcade MACOSX_DEPLOYMENT_TARGET=12.4 -j8
$ install_name_tool -id mamearcade_headless.dylib mamearcade_headless.dylib
```
cd mame
git apply ../lib/mame.patch
Depending on your hardware, this could take a _long_ time, but if successful, you will have a file named `mamearcade_headless.dylib` in the current directory.
**Step 2: Build mame**
The following commands will build all the MAME object files. Ignore the final link error, which is only to build the executable we don't use the midi support.
cd mame
make -j 4 macosx_x64_clang SUBTARGET=arcade NOWERROR=1
**Step 3: Build libmame_x64.a**
cd ../lib
make SUBTARGET=arcade
Build the UME project, which will link and embed this binary and update the loader path automatically.
Vendored Submodule
+1
Submodule deps/mame added at 4fc1f9f16b
-60
View File
@@ -1,60 +0,0 @@
# makefile to build libmame.a and copy any public header files
TARGET := mame
MAMEPATH := ../mame
CONFIG := Release
ifndef SUBTARGET
SUBTARGET := tiny
endif
ifndef ARCHITECTURE
ARCHITECTURE := x64
endif
OUTPUT := libmame.a
OBJDIR := $(MAMEPATH)/build/osx_clang/obj/$(ARCHITECTURE)/$(CONFIG)
OBJECTS := \
$(OBJDIR)/src/mame/mame.o \
$(OBJDIR)/src/version.o \
$(OBJDIR)/generated/$(TARGET)/$(SUBTARGET)/drivlist.o
LIBDIR := $(MAMEPATH)/build/osx_clang/bin/$(ARCHITECTURE)/$(CONFIG)
LIBS := \
$(LIBDIR)/lib7z.a \
$(LIBDIR)/libbgfx.a \
$(LIBDIR)/libexpat.a \
$(LIBDIR)/libflac.a \
$(LIBDIR)/libformats.a \
$(LIBDIR)/libgtest.a \
$(LIBDIR)/libjpeg.a \
$(LIBDIR)/liblsqlite3.a \
$(LIBDIR)/liblua.a \
$(LIBDIR)/libnetlist.a \
$(LIBDIR)/libosd_osdmini.a \
$(LIBDIR)/libportaudio.a \
$(LIBDIR)/libportmidi.a \
$(LIBDIR)/libqtdbg_osdmini.a \
$(LIBDIR)/libsoftfloat.a \
$(LIBDIR)/libsqllite3.a \
$(LIBDIR)/libutils.a \
$(LIBDIR)/libzlib.a \
$(wildcard $(LIBDIR)/$(TARGET)_$(SUBTARGET)/*.a) \
$(info Generating $(OUTPUT) $(TARGET)_$(SUBTARGET)-$(ARCHITECTURE) using $(CONFIG) build)
libmame: libmame_$(ARCHITECTURE).a
libmame_$(ARCHITECTURE).a: libmain.a libocore_osdmimi_x.a $(LIBS)
libtool -s -static -o libmame_$(ARCHITECTURE).a $?
libmain.a: $(OBJECTS)
ar -rcs libmain.a $(OBJECTS)
libocore_osdmimi_x.a: $(LIBDIR)/libocore_osdmini.a
ar -x $?
rm minidir.o
ar -rcs libocore_osdmimi_x.a *.o
rm *.o "__.SYMDEF SORTED"
-17
View File
@@ -1,17 +0,0 @@
diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp
index 39eeb6e..f9f5711 100644
--- a/src/emu/ui/ui.cpp
+++ b/src/emu/ui/ui.cpp
@@ -321,10 +321,10 @@ void ui_manager::display_startup_screens(bool first_time, bool show_disclaimer)
if (!first_time || (str > 0 && str < 60*5) || &machine().system() == &GAME_NAME(___empty) || (machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
show_gameinfo = show_warnings = show_disclaimer = show_mandatory_fileman = FALSE;
- #if defined(EMSCRIPTEN)
+ //#if defined(EMSCRIPTEN)
// also disable for the JavaScript port since the startup screens do not run asynchronously
show_gameinfo = show_warnings = show_disclaimer = FALSE;
- #endif
+ //#endif
// loop over states
set_handler(handler_ingame, 0);
Submodule mame deleted from 048fd105db
-59
View File
@@ -1,59 +0,0 @@
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
//============================================================
//
// minidir.c - Minimal core directory access functions
//
//============================================================
#include "osdcore.h"
//============================================================
// osd_opendir
//============================================================
osd_directory *osd_opendir(const char *dirname)
{
// since there are no standard C library routines for walking directories,
// we always return an error here
return nullptr;
}
//============================================================
// osd_readdir
//============================================================
const osd_directory_entry *osd_readdir(osd_directory *dir)
{
// since there are no standard C library routines for walking directories,
// we always return an error here
return nullptr;
}
//============================================================
// osd_closedir
//============================================================
void osd_closedir(osd_directory *dir)
{
// since there are no standard C library routines for walking directories,
// we do nothing
}
int osd_is_absolute_path(const char *path)
{
int result;
if (path[0] == '/')
result = TRUE;
else if (path[0] == '.')
result = TRUE;
else
result = FALSE;
return result;
}
-42
View File
@@ -1,42 +0,0 @@
/*
Copyright (c) 2013, OpenEmu Team
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the OpenEmu Team nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "osdobj_common.h"
@class MAMEGameCore;
class osx_osd_interface : public osd_common_t
{
public:
osx_osd_interface(MAMEGameCore *, osd_options &options);
MAMEGameCore *core() const { return m_core; }
void init(running_machine &machine);
void update(bool skip_redraw);
void update_audio_stream(const INT16 *buffer, int samples_this_frame);
void osd_exit();
private:
MAMEGameCore *m_core;
};
-59
View File
@@ -1,59 +0,0 @@
/*
Copyright (c) 2013, 2016 OpenEmu Team
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the OpenEmu Team nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "MAMEGameCore.h"
#include "osx_osd_interface.h"
osx_osd_interface::osx_osd_interface(MAMEGameCore *core, osd_options &options)
:osd_common_t(options), m_core(core)
{
}
void osx_osd_interface::init(running_machine &machine)
{
osd_common_t::init(machine);
osd_common_t::init_subsystems();
[m_core osd_init:&machine];
}
void osx_osd_interface::update(bool skip_redraw)
{
[m_core osd_update:skip_redraw];
}
void osx_osd_interface::update_audio_stream(const INT16 *buffer, int samples_this_frame)
{
[m_core osd_update_audio_stream:buffer samples:samples_this_frame];
}
void osx_osd_interface::osd_exit()
{
[m_core osd_exit:&machine()];
}