├── .gitignore
├── .gitmodules
├── Info.plist
├── MAME.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── MAMEGameCore.h
├── MAMEGameCore.m
├── MAME_Prefix.pch
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | build
3 | */Build/*
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | profile
14 | *.moved-aside
15 | DerivedData/
16 | .idea/
17 | *.hmap
18 |
19 | # MAME
20 | *.a
21 | *.o
22 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "deps/mame"]
2 | path = deps/mame
3 | url = https://github.com/stuartcarnie/mame.git
4 | branch = mame0225-headless
5 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | English
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | BNDL
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 | OEGameCoreController
25 | OEGameCoreClass
26 | MAMEGameCore
27 | OEGameCoreOptions
28 |
29 | openemu.system.arcade
30 |
31 | OEGameCoreRewindBufferSeconds
32 | 10
33 | OEGameCoreRewindInterval
34 | 0
35 | OEGameCoreSupportsDisplayModeChange
36 |
37 | OEGameCoreSupportsRewinding
38 |
39 |
40 |
41 | OEGameCorePlayerCount
42 | 8
43 | OEProjectURL
44 | http://mamedev.org
45 | OESystemIdentifiers
46 |
47 | openemu.system.arcade
48 |
49 | SUEnableAutomaticChecks
50 | 1
51 | SUFeedURL
52 | https://raw.github.com/OpenEmu/OpenEmu-Update/master/mame_appcast.xml
53 |
54 |
55 |
--------------------------------------------------------------------------------
/MAME.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 53;
7 | objects = {
8 |
9 | /* Begin PBXAggregateTarget section */
10 | D0AADE271763813100759E26 /* Build & Install MAME */ = {
11 | isa = PBXAggregateTarget;
12 | buildConfigurationList = D0AADE281763813100759E26 /* Build configuration list for PBXAggregateTarget "Build & Install MAME" */;
13 | buildPhases = (
14 | D0AADE2D1763815000759E26 /* ShellScript */,
15 | );
16 | dependencies = (
17 | D0AADE2C1763813900759E26 /* PBXTargetDependency */,
18 | );
19 | name = "Build & Install MAME";
20 | productName = "Build & Install MAME";
21 | };
22 | /* End PBXAggregateTarget section */
23 |
24 | /* Begin PBXBuildFile section */
25 | 0510AA1E2300825E002028C1 /* mamearcade_headless.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */; };
26 | 0510AA1F23008294002028C1 /* mamearcade_headless.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
27 | D00A068E1763763000C99008 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D00A068D1763763000C99008 /* Cocoa.framework */; };
28 | D00A06A617637E9100C99008 /* MAMEGameCore.m in Sources */ = {isa = PBXBuildFile; fileRef = D00A06A517637E9100C99008 /* MAMEGameCore.m */; };
29 | D0AADE31176382F900759E26 /* OpenEmuBase.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AADE30176382F900759E26 /* OpenEmuBase.framework */; };
30 | /* End PBXBuildFile section */
31 |
32 | /* Begin PBXContainerItemProxy section */
33 | D0AADE2B1763813900759E26 /* PBXContainerItemProxy */ = {
34 | isa = PBXContainerItemProxy;
35 | containerPortal = D00A06821763762F00C99008 /* Project object */;
36 | proxyType = 1;
37 | remoteGlobalIDString = D00A06891763763000C99008;
38 | remoteInfo = MAME;
39 | };
40 | /* End PBXContainerItemProxy section */
41 |
42 | /* Begin PBXCopyFilesBuildPhase section */
43 | 0510AA2023008294002028C1 /* Embed Libraries */ = {
44 | isa = PBXCopyFilesBuildPhase;
45 | buildActionMask = 2147483647;
46 | dstPath = "";
47 | dstSubfolderSpec = 10;
48 | files = (
49 | 0510AA1F23008294002028C1 /* mamearcade_headless.dylib in Embed Libraries */,
50 | );
51 | name = "Embed Libraries";
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | /* End PBXCopyFilesBuildPhase section */
55 |
56 | /* Begin PBXFileReference section */
57 | 050B7E8823775A04000ECB19 /* driver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = driver.h; path = deps/mame/src/osd/headless/public/driver.h; sourceTree = ""; };
58 | 050B7E8923775A04000ECB19 /* oecommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oecommon.h; path = deps/mame/src/osd/headless/public/oecommon.h; sourceTree = ""; };
59 | 050B7E8A23775A04000ECB19 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = options.h; path = deps/mame/src/osd/headless/public/options.h; sourceTree = ""; };
60 | 050B7E8B23775A04000ECB19 /* headless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = headless.h; path = deps/mame/src/osd/headless/public/headless.h; sourceTree = ""; };
61 | 0510AA1B230081F3002028C1 /* inputenum.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = inputenum.h; path = deps/mame/src/osd/headless/public/inputenum.h; sourceTree = ""; };
62 | 0510AA1C230081F3002028C1 /* osd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = osd.h; path = deps/mame/src/osd/headless/public/osd.h; sourceTree = ""; };
63 | 0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = mamearcade_headless.dylib; path = deps/mame/mamearcade_headless.dylib; sourceTree = ""; };
64 | 05334A951C52AEEF0066D493 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = System/Library/Frameworks/CoreMIDI.framework; sourceTree = SDKROOT; };
65 | 05334A981C52AF0E0066D493 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
66 | 8C3132F7177F667D0002D0B9 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
67 | D00A068A1763763000C99008 /* MAME.oecoreplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MAME.oecoreplugin; sourceTree = BUILT_PRODUCTS_DIR; };
68 | D00A068D1763763000C99008 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
69 | D00A06921763763000C99008 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
70 | D00A069F17637AB600C99008 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = SOURCE_ROOT; };
71 | D00A06A417637E9100C99008 /* MAMEGameCore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAMEGameCore.h; sourceTree = ""; };
72 | D00A06A517637E9100C99008 /* MAMEGameCore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MAMEGameCore.m; sourceTree = ""; };
73 | D00A06A717637EB500C99008 /* OEArcadeSystemResponderClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OEArcadeSystemResponderClient.h; path = ../OpenEmu/SystemPlugins/Arcade/OEArcadeSystemResponderClient.h; sourceTree = ""; };
74 | D0AADE2F176381FB00759E26 /* MAME_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MAME_Prefix.pch; sourceTree = ""; };
75 | D0AADE30176382F900759E26 /* OpenEmuBase.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = OpenEmuBase.framework; sourceTree = BUILT_PRODUCTS_DIR; };
76 | D0AADE331763838A00759E26 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
77 | D0AADE341763838A00759E26 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
78 | /* End PBXFileReference section */
79 |
80 | /* Begin PBXFrameworksBuildPhase section */
81 | D00A06871763763000C99008 /* Frameworks */ = {
82 | isa = PBXFrameworksBuildPhase;
83 | buildActionMask = 2147483647;
84 | files = (
85 | 0510AA1E2300825E002028C1 /* mamearcade_headless.dylib in Frameworks */,
86 | D00A068E1763763000C99008 /* Cocoa.framework in Frameworks */,
87 | D0AADE31176382F900759E26 /* OpenEmuBase.framework in Frameworks */,
88 | );
89 | runOnlyForDeploymentPostprocessing = 0;
90 | };
91 | /* End PBXFrameworksBuildPhase section */
92 |
93 | /* Begin PBXGroup section */
94 | D00A06811763762F00C99008 = {
95 | isa = PBXGroup;
96 | children = (
97 | D00A06A317637BDD00C99008 /* Classes */,
98 | D0AADE2E176381E900759E26 /* Other Sources */,
99 | D00A06931763763000C99008 /* Resources */,
100 | D00A068C1763763000C99008 /* Frameworks */,
101 | D00A068B1763763000C99008 /* Products */,
102 | );
103 | sourceTree = "";
104 | };
105 | D00A068B1763763000C99008 /* Products */ = {
106 | isa = PBXGroup;
107 | children = (
108 | D00A068A1763763000C99008 /* MAME.oecoreplugin */,
109 | );
110 | name = Products;
111 | sourceTree = "";
112 | };
113 | D00A068C1763763000C99008 /* Frameworks */ = {
114 | isa = PBXGroup;
115 | children = (
116 | 0510AA1D2300825D002028C1 /* mamearcade_headless.dylib */,
117 | D0AADE30176382F900759E26 /* OpenEmuBase.framework */,
118 | D00A068F1763763000C99008 /* Linked Frameworks */,
119 | D0AADE321763833600759E26 /* Other Frameworks */,
120 | );
121 | name = Frameworks;
122 | sourceTree = "";
123 | };
124 | D00A068F1763763000C99008 /* Linked Frameworks */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 05334A951C52AEEF0066D493 /* CoreMIDI.framework */,
128 | 05334A981C52AF0E0066D493 /* CoreAudio.framework */,
129 | D00A068D1763763000C99008 /* Cocoa.framework */,
130 | 8C3132F7177F667D0002D0B9 /* OpenGL.framework */,
131 | );
132 | name = "Linked Frameworks";
133 | sourceTree = "";
134 | };
135 | D00A06931763763000C99008 /* Resources */ = {
136 | isa = PBXGroup;
137 | children = (
138 | D00A069F17637AB600C99008 /* Info.plist */,
139 | );
140 | name = Resources;
141 | sourceTree = "";
142 | };
143 | D00A06A317637BDD00C99008 /* Classes */ = {
144 | isa = PBXGroup;
145 | children = (
146 | D00A06A717637EB500C99008 /* OEArcadeSystemResponderClient.h */,
147 | D00A06A417637E9100C99008 /* MAMEGameCore.h */,
148 | D00A06A517637E9100C99008 /* MAMEGameCore.m */,
149 | D0BA5A9517645D630033A910 /* osd */,
150 | );
151 | name = Classes;
152 | sourceTree = "";
153 | };
154 | D0AADE2E176381E900759E26 /* Other Sources */ = {
155 | isa = PBXGroup;
156 | children = (
157 | D0AADE2F176381FB00759E26 /* MAME_Prefix.pch */,
158 | );
159 | name = "Other Sources";
160 | sourceTree = "";
161 | };
162 | D0AADE321763833600759E26 /* Other Frameworks */ = {
163 | isa = PBXGroup;
164 | children = (
165 | D0AADE331763838A00759E26 /* AppKit.framework */,
166 | D0AADE341763838A00759E26 /* CoreData.framework */,
167 | D00A06921763763000C99008 /* Foundation.framework */,
168 | );
169 | name = "Other Frameworks";
170 | sourceTree = "";
171 | };
172 | D0BA5A9517645D630033A910 /* osd */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 050B7E8823775A04000ECB19 /* driver.h */,
176 | 050B7E8B23775A04000ECB19 /* headless.h */,
177 | 050B7E8923775A04000ECB19 /* oecommon.h */,
178 | 050B7E8A23775A04000ECB19 /* options.h */,
179 | 0510AA1B230081F3002028C1 /* inputenum.h */,
180 | 0510AA1C230081F3002028C1 /* osd.h */,
181 | );
182 | name = osd;
183 | sourceTree = "";
184 | };
185 | /* End PBXGroup section */
186 |
187 | /* Begin PBXNativeTarget section */
188 | D00A06891763763000C99008 /* MAME */ = {
189 | isa = PBXNativeTarget;
190 | buildConfigurationList = D00A069C1763763000C99008 /* Build configuration list for PBXNativeTarget "MAME" */;
191 | buildPhases = (
192 | D00A06861763763000C99008 /* Sources */,
193 | D00A06871763763000C99008 /* Frameworks */,
194 | D00A06881763763000C99008 /* Resources */,
195 | 0510AA2023008294002028C1 /* Embed Libraries */,
196 | 0510AA2123008883002028C1 /* ShellScript */,
197 | );
198 | buildRules = (
199 | );
200 | dependencies = (
201 | );
202 | name = MAME;
203 | productName = MAME;
204 | productReference = D00A068A1763763000C99008 /* MAME.oecoreplugin */;
205 | productType = "com.apple.product-type.bundle";
206 | };
207 | /* End PBXNativeTarget section */
208 |
209 | /* Begin PBXProject section */
210 | D00A06821763762F00C99008 /* Project object */ = {
211 | isa = PBXProject;
212 | attributes = {
213 | BuildIndependentTargetsInParallel = YES;
214 | LastUpgradeCheck = 1330;
215 | ORGANIZATIONNAME = OpenEmu;
216 | };
217 | buildConfigurationList = D00A06851763762F00C99008 /* Build configuration list for PBXProject "MAME" */;
218 | compatibilityVersion = "Xcode 10.0";
219 | developmentRegion = English;
220 | hasScannedForEncodings = 0;
221 | knownRegions = (
222 | English,
223 | en,
224 | );
225 | mainGroup = D00A06811763762F00C99008;
226 | productRefGroup = D00A068B1763763000C99008 /* Products */;
227 | projectDirPath = "";
228 | projectRoot = "";
229 | targets = (
230 | D00A06891763763000C99008 /* MAME */,
231 | D0AADE271763813100759E26 /* Build & Install MAME */,
232 | );
233 | };
234 | /* End PBXProject section */
235 |
236 | /* Begin PBXResourcesBuildPhase section */
237 | D00A06881763763000C99008 /* Resources */ = {
238 | isa = PBXResourcesBuildPhase;
239 | buildActionMask = 2147483647;
240 | files = (
241 | );
242 | runOnlyForDeploymentPostprocessing = 0;
243 | };
244 | /* End PBXResourcesBuildPhase section */
245 |
246 | /* Begin PBXShellScriptBuildPhase section */
247 | 0510AA2123008883002028C1 /* ShellScript */ = {
248 | isa = PBXShellScriptBuildPhase;
249 | buildActionMask = 2147483647;
250 | files = (
251 | );
252 | inputFileListPaths = (
253 | );
254 | inputPaths = (
255 | );
256 | outputFileListPaths = (
257 | );
258 | outputPaths = (
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | shellPath = /bin/sh;
262 | shellScript = "install_name_tool -change mamearcade_headless.dylib @rpath/mamearcade_headless.dylib ${TARGET_BUILD_DIR}/${EXECUTABLE_PATH}\n";
263 | };
264 | D0AADE2D1763815000759E26 /* ShellScript */ = {
265 | isa = PBXShellScriptBuildPhase;
266 | buildActionMask = 2147483647;
267 | files = (
268 | );
269 | inputPaths = (
270 | );
271 | outputPaths = (
272 | );
273 | runOnlyForDeploymentPostprocessing = 0;
274 | shellPath = /bin/sh;
275 | shellScript = "mkdir -p \"$USER_LIBRARY_DIR/Application Support/OpenEmu/Cores\"\nrm -rf \"$USER_LIBRARY_DIR/Application Support/OpenEmu/Cores/$PROJECT_NAME.oecoreplugin\"{,.dSYM}\ncp -rf \"$BUILT_PRODUCTS_DIR/$PROJECT_NAME.oecoreplugin\"{,.dSYM} \"$USER_LIBRARY_DIR/Application Support/OpenEmu/Cores/\"";
276 | };
277 | /* End PBXShellScriptBuildPhase section */
278 |
279 | /* Begin PBXSourcesBuildPhase section */
280 | D00A06861763763000C99008 /* Sources */ = {
281 | isa = PBXSourcesBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | D00A06A617637E9100C99008 /* MAMEGameCore.m in Sources */,
285 | );
286 | runOnlyForDeploymentPostprocessing = 0;
287 | };
288 | /* End PBXSourcesBuildPhase section */
289 |
290 | /* Begin PBXTargetDependency section */
291 | D0AADE2C1763813900759E26 /* PBXTargetDependency */ = {
292 | isa = PBXTargetDependency;
293 | target = D00A06891763763000C99008 /* MAME */;
294 | targetProxy = D0AADE2B1763813900759E26 /* PBXContainerItemProxy */;
295 | };
296 | /* End PBXTargetDependency section */
297 |
298 | /* Begin XCBuildConfiguration section */
299 | D00A069A1763763000C99008 /* Debug */ = {
300 | isa = XCBuildConfiguration;
301 | buildSettings = {
302 | ARCHS = x86_64;
303 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
304 | CLANG_CXX_LANGUAGE_STANDARD = "c++14";
305 | CLANG_CXX_LIBRARY = "compiler-default";
306 | CLANG_DEBUG_INFORMATION_LEVEL = default;
307 | CLANG_ENABLE_MODULES = YES;
308 | CLANG_ENABLE_OBJC_ARC = YES;
309 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
310 | CLANG_WARN_BOOL_CONVERSION = YES;
311 | CLANG_WARN_COMMA = YES;
312 | CLANG_WARN_CONSTANT_CONVERSION = YES;
313 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
314 | CLANG_WARN_EMPTY_BODY = YES;
315 | CLANG_WARN_ENUM_CONVERSION = YES;
316 | CLANG_WARN_INFINITE_RECURSION = YES;
317 | CLANG_WARN_INT_CONVERSION = YES;
318 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
319 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
320 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
321 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
322 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
323 | CLANG_WARN_STRICT_PROTOTYPES = YES;
324 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
325 | CLANG_WARN_UNREACHABLE_CODE = YES;
326 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
327 | COPY_PHASE_STRIP = YES;
328 | DEAD_CODE_STRIPPING = NO;
329 | DEBUG_INFORMATION_FORMAT = dwarf;
330 | ENABLE_STRICT_OBJC_MSGSEND = YES;
331 | ENABLE_TESTABILITY = YES;
332 | GCC_C_LANGUAGE_STANDARD = gnu89;
333 | GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
334 | GCC_INPUT_FILETYPE = sourcecode.cpp.cpp;
335 | GCC_NO_COMMON_BLOCKS = YES;
336 | GCC_OPTIMIZATION_LEVEL = 0;
337 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
338 | GCC_PREFIX_HEADER = "";
339 | GCC_PREPROCESSOR_DEFINITIONS = (
340 | "DEBUG=1",
341 | "$(inherited)",
342 | );
343 | GCC_SYMBOLS_PRIVATE_EXTERN = YES;
344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
345 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
346 | GCC_WARN_UNDECLARED_SELECTOR = YES;
347 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
348 | GCC_WARN_UNUSED_FUNCTION = YES;
349 | GCC_WARN_UNUSED_VALUE = NO;
350 | GCC_WARN_UNUSED_VARIABLE = YES;
351 | MACOSX_DEPLOYMENT_TARGET = 10.15;
352 | ONLY_ACTIVE_ARCH = YES;
353 | PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
354 | SDKROOT = macosx;
355 | };
356 | name = Debug;
357 | };
358 | D00A069B1763763000C99008 /* Release */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ARCHS = x86_64;
362 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
363 | CLANG_CXX_LANGUAGE_STANDARD = "c++14";
364 | CLANG_CXX_LIBRARY = "compiler-default";
365 | CLANG_DEBUG_INFORMATION_LEVEL = default;
366 | CLANG_ENABLE_MODULES = YES;
367 | CLANG_ENABLE_OBJC_ARC = YES;
368 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
369 | CLANG_WARN_BOOL_CONVERSION = YES;
370 | CLANG_WARN_COMMA = YES;
371 | CLANG_WARN_CONSTANT_CONVERSION = YES;
372 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
373 | CLANG_WARN_EMPTY_BODY = YES;
374 | CLANG_WARN_ENUM_CONVERSION = YES;
375 | CLANG_WARN_INFINITE_RECURSION = YES;
376 | CLANG_WARN_INT_CONVERSION = YES;
377 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
378 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
379 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
380 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
381 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
382 | CLANG_WARN_STRICT_PROTOTYPES = YES;
383 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
384 | CLANG_WARN_UNREACHABLE_CODE = YES;
385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
386 | COPY_PHASE_STRIP = YES;
387 | DEAD_CODE_STRIPPING = NO;
388 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
389 | ENABLE_STRICT_OBJC_MSGSEND = YES;
390 | ENABLE_TESTABILITY = NO;
391 | GCC_C_LANGUAGE_STANDARD = gnu89;
392 | GCC_INCREASE_PRECOMPILED_HEADER_SHARING = YES;
393 | GCC_INPUT_FILETYPE = sourcecode.cpp.cpp;
394 | GCC_NO_COMMON_BLOCKS = YES;
395 | GCC_OPTIMIZATION_LEVEL = 3;
396 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
397 | GCC_PREFIX_HEADER = "";
398 | GCC_SYMBOLS_PRIVATE_EXTERN = YES;
399 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
400 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
401 | GCC_WARN_UNDECLARED_SELECTOR = YES;
402 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
403 | GCC_WARN_UNUSED_FUNCTION = YES;
404 | GCC_WARN_UNUSED_VALUE = NO;
405 | GCC_WARN_UNUSED_VARIABLE = YES;
406 | MACOSX_DEPLOYMENT_TARGET = 10.15;
407 | PRECOMPS_INCLUDE_HEADERS_FROM_BUILT_PRODUCTS_DIR = NO;
408 | SDKROOT = macosx;
409 | };
410 | name = Release;
411 | };
412 | D00A069D1763763000C99008 /* Debug */ = {
413 | isa = XCBuildConfiguration;
414 | buildSettings = {
415 | COMBINE_HIDPI_IMAGES = YES;
416 | CURRENT_PROJECT_VERSION = 0.250.0.1;
417 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
418 | GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
419 | GCC_PRECOMPILE_PREFIX_HEADER = NO;
420 | HEADER_SEARCH_PATHS = (
421 | "$(inherited)",
422 | "\"$(SRCROOT)/../OpenEmu/Arcade\"",
423 | "$(SRCROOT)/deps/mame/src/osd/headless/public",
424 | );
425 | INFOPLIST_FILE = Info.plist;
426 | INSTALL_PATH = "\"$(USER_LIBRARY_DIR)/Application Support/OpenEmu/Cores\"";
427 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
428 | LIBRARY_SEARCH_PATHS = (
429 | "$(inherited)",
430 | "$(PROJECT_DIR)/deps/mame",
431 | );
432 | PRODUCT_BUNDLE_IDENTIFIER = "org.openemu.${PRODUCT_NAME:rfc1034identifier}";
433 | PRODUCT_NAME = "$(TARGET_NAME)";
434 | SKIP_INSTALL = YES;
435 | WRAPPER_EXTENSION = oecoreplugin;
436 | };
437 | name = Debug;
438 | };
439 | D00A069E1763763000C99008 /* Release */ = {
440 | isa = XCBuildConfiguration;
441 | buildSettings = {
442 | COMBINE_HIDPI_IMAGES = YES;
443 | CURRENT_PROJECT_VERSION = 0.250.0.1;
444 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
445 | GCC_INPUT_FILETYPE = sourcecode.cpp.objcpp;
446 | GCC_PRECOMPILE_PREFIX_HEADER = NO;
447 | HEADER_SEARCH_PATHS = (
448 | "$(inherited)",
449 | "\"$(SRCROOT)/../OpenEmu/Arcade\"",
450 | "$(SRCROOT)/deps/mame/src/osd/headless/public",
451 | );
452 | INFOPLIST_FILE = Info.plist;
453 | INSTALL_PATH = "\"$(USER_LIBRARY_DIR)/Application Support/OpenEmu/Cores\"";
454 | LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
455 | LIBRARY_SEARCH_PATHS = (
456 | "$(inherited)",
457 | "$(PROJECT_DIR)/deps/mame",
458 | );
459 | PRODUCT_BUNDLE_IDENTIFIER = "org.openemu.${PRODUCT_NAME:rfc1034identifier}";
460 | PRODUCT_NAME = "$(TARGET_NAME)";
461 | SKIP_INSTALL = YES;
462 | WRAPPER_EXTENSION = oecoreplugin;
463 | };
464 | name = Release;
465 | };
466 | D0AADE291763813100759E26 /* Debug */ = {
467 | isa = XCBuildConfiguration;
468 | buildSettings = {
469 | PRODUCT_NAME = "$(TARGET_NAME)";
470 | };
471 | name = Debug;
472 | };
473 | D0AADE2A1763813100759E26 /* Release */ = {
474 | isa = XCBuildConfiguration;
475 | buildSettings = {
476 | PRODUCT_NAME = "$(TARGET_NAME)";
477 | };
478 | name = Release;
479 | };
480 | /* End XCBuildConfiguration section */
481 |
482 | /* Begin XCConfigurationList section */
483 | D00A06851763762F00C99008 /* Build configuration list for PBXProject "MAME" */ = {
484 | isa = XCConfigurationList;
485 | buildConfigurations = (
486 | D00A069A1763763000C99008 /* Debug */,
487 | D00A069B1763763000C99008 /* Release */,
488 | );
489 | defaultConfigurationIsVisible = 0;
490 | defaultConfigurationName = Release;
491 | };
492 | D00A069C1763763000C99008 /* Build configuration list for PBXNativeTarget "MAME" */ = {
493 | isa = XCConfigurationList;
494 | buildConfigurations = (
495 | D00A069D1763763000C99008 /* Debug */,
496 | D00A069E1763763000C99008 /* Release */,
497 | );
498 | defaultConfigurationIsVisible = 0;
499 | defaultConfigurationName = Release;
500 | };
501 | D0AADE281763813100759E26 /* Build configuration list for PBXAggregateTarget "Build & Install MAME" */ = {
502 | isa = XCConfigurationList;
503 | buildConfigurations = (
504 | D0AADE291763813100759E26 /* Debug */,
505 | D0AADE2A1763813100759E26 /* Release */,
506 | );
507 | defaultConfigurationIsVisible = 0;
508 | defaultConfigurationName = Release;
509 | };
510 | /* End XCConfigurationList section */
511 | };
512 | rootObject = D00A06821763762F00C99008 /* Project object */;
513 | }
514 |
--------------------------------------------------------------------------------
/MAME.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MAMEGameCore.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2013, OpenEmu Team
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the OpenEmu Team nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #import
28 | #import
29 | #import "OEArcadeSystemResponderClient.h"
30 | #import "osd.h"
31 |
32 | OE_EXPORTED_CLASS
33 | @interface MAMEGameCore : OEGameCore
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/MAMEGameCore.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2013, OpenEmu Team
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright
7 | notice, this list of conditions and the following disclaimer.
8 | * Redistributions in binary form must reproduce the above copyright
9 | notice, this list of conditions and the following disclaimer in the
10 | documentation and/or other materials provided with the distribution.
11 | * Neither the name of the OpenEmu Team nor the
12 | names of its contributors may be used to endorse or promote products
13 | derived from this software without specific prior written permission.
14 |
15 | THIS SOFTWARE IS PROVIDED BY OpenEmu Team ''AS IS'' AND ANY
16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 | DISCLAIMED. IN NO EVENT SHALL OpenEmu Team BE LIABLE FOR ANY
19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 | */
26 |
27 | #import "MAMEGameCore.h"
28 |
29 | #import
30 | #import
31 | #import
32 |
33 | @interface MAMEAuditResult: NSObject
34 |
35 | /*! Returns the unique identifier of this result
36 | *
37 | * @remarks
38 | *
39 | * Identifier which groups resources by their driver, parent or CHD name
40 | */
41 | @property (nonatomic, readonly) NSString *identifier;
42 | @property (nonatomic, readonly) NSString *fileName;
43 |
44 | - (instancetype)initWithDriver:(NSString *)driver auditRecord:(AuditRecord *)record;
45 | - (BOOL)checkSetExistsInDir:(NSURL *)dir;
46 |
47 | @end
48 |
49 | @interface MAMEGameCore ()
50 | {
51 | uint32_t _buttons[8][OEArcadeButtonCount];
52 | uint32_t _axes[8][InputMaxAxis];
53 |
54 | uint32_t *_buffer;
55 | OEIntSize _bufferSize;
56 | OEIntRect _screenRect;
57 | OEIntSize _aspectSize;
58 |
59 | NSTimeInterval _frameInterval;
60 |
61 |
62 | // dylib
63 | void *_handle;
64 | OSD *_osd;
65 | BOOL _supportsRewinding;
66 | }
67 |
68 | @end
69 |
70 | static int32_t joystick_get_state(void *device_internal, void *item_internal)
71 | {
72 | return *(int32_t *)item_internal;
73 | }
74 |
75 | static os_log_t OE_CORE_LOG, OE_CORE_AUDIT_LOG;
76 |
77 | @implementation MAMEGameCore
78 |
79 | #pragma mark - Lifecycle
80 |
81 | + (void)initialize
82 | {
83 | OE_CORE_LOG = os_log_create("org.openemu.MAME", "");
84 | OE_CORE_AUDIT_LOG = os_log_create("org.openemu.MAME", "audit");
85 | }
86 |
87 | - (id)init
88 | {
89 | self = [super init];
90 | if(!self)
91 | {
92 | return nil;
93 | }
94 |
95 | // Sensible defaults
96 | _bufferSize = OEIntSizeMake(1024, 1024);
97 | _frameInterval = 60;
98 | _screenRect = { {0,0}, _bufferSize };
99 | _aspectSize = { 4, 3 };
100 |
101 | _osd = [OSD shared];
102 | _osd.delegate = self;
103 |
104 | return self;
105 | }
106 |
107 | #pragma mark - OSDDelegate
108 |
109 | - (void)didInitialize
110 | {
111 | // initialize joysticks
112 | for (int i = 0; i < 8; i++) {
113 | NSString *name = [NSString stringWithFormat:@"OpenEmu Player %d", i];
114 | InputDevice *dev = [_osd.joystick addDeviceNamed:name];
115 | [dev addItemNamed:@"X Axis" id:InputItemID_XAXIS getter:joystick_get_state context:&_axes[i][0]];
116 | [dev addItemNamed:@"Y Axis" id:InputItemID_YAXIS getter:joystick_get_state context:&_axes[i][1]];
117 | [dev addItemNamed:@"Start" id:InputItemID_START getter:joystick_get_state context:&_buttons[i][OEArcadeButtonP1Start]];
118 | [dev addItemNamed:@"Insert Coin" id:InputItemID_SELECT getter:joystick_get_state context:&_buttons[i][OEArcadeButtonInsertCoin]];
119 | [dev addItemNamed:@"Button 1" id:InputItemID_BUTTON1 getter:joystick_get_state context:&_buttons[i][OEArcadeButton1]];
120 | [dev addItemNamed:@"Button 2" id:InputItemID_BUTTON2 getter:joystick_get_state context:&_buttons[i][OEArcadeButton2]];
121 | [dev addItemNamed:@"Button 3" id:InputItemID_BUTTON3 getter:joystick_get_state context:&_buttons[i][OEArcadeButton3]];
122 | [dev addItemNamed:@"Button 4" id:InputItemID_BUTTON4 getter:joystick_get_state context:&_buttons[i][OEArcadeButton4]];
123 | [dev addItemNamed:@"Button 5" id:InputItemID_BUTTON5 getter:joystick_get_state context:&_buttons[i][OEArcadeButton5]];
124 | [dev addItemNamed:@"Button 6" id:InputItemID_BUTTON6 getter:joystick_get_state context:&_buttons[i][OEArcadeButton6]];
125 | }
126 |
127 | // Special keys
128 | InputDevice *kb = [_osd.keyboard addDeviceNamed:@"OpenEmu Keyboard"];
129 | [kb addItemNamed:@"Service" id:InputItemID_F2 getter:joystick_get_state context:&_buttons[0][OEArcadeButtonService]];
130 | [kb addItemNamed:@"UI Configure" id:InputItemID_TAB getter:joystick_get_state context:&_buttons[0][OEArcadeUIConfigure]];
131 | }
132 |
133 | - (void)didChangeDisplayBounds:(NSSize)bounds fps:(double)fps aspect:(NSSize)aspect
134 | {
135 | _screenRect = {{0, 0}, OEIntSizeMake(bounds.width, bounds.height)};
136 |
137 | // for single screen games:
138 | BOOL singleScreen = YES;
139 | if (singleScreen)
140 | {
141 | CGFloat newHeight = (aspect.height / aspect.width) * bounds.width;
142 | _aspectSize = OEIntSizeMake(bounds.width, newHeight);
143 | }
144 | else
145 | {
146 | _aspectSize = OEIntSizeMake(bounds.width, bounds.height);
147 | }
148 |
149 | _frameInterval = fps;
150 | }
151 |
152 | - (void)updateAudioBuffer:(const int16_t *)buffer samples:(NSInteger)samples
153 | {
154 | id buf = [self audioBufferAtIndex:0];
155 | [buf write:buffer maxLength:samples * 2 * sizeof(int16_t)];
156 | }
157 |
158 | - (void)logLevel:(OSDLogLevel)level message:(NSString *)msg
159 | {
160 | switch (level) {
161 | case OSDLogLevelError:
162 | os_log_error(OE_CORE_LOG, "%{public}s", msg.UTF8String);
163 | break;
164 |
165 | case OSDLogLevelVerbose:
166 | os_log_debug(OE_CORE_LOG, "%{public}s", msg.UTF8String);
167 | break;
168 |
169 | default:
170 | os_log_info(OE_CORE_LOG, "%{public}s", msg.UTF8String);
171 | break;
172 | }
173 | }
174 |
175 | #pragma mark - Execution
176 |
177 | BOOL driverIsNotWorking(GameDriverOptions o)
178 | {
179 | if ((o & GameDriverMachineNotWorking) == GameDriverMachineNotWorking) {
180 | return YES;
181 | }
182 |
183 | if ((o & GameDriverMachineIsSkeleton) == GameDriverMachineIsSkeleton) {
184 | return YES;
185 | }
186 |
187 | return NO;
188 | }
189 |
190 | - (BOOL)validateGameDriver:(GameDriver *)driver error:(NSError **)error
191 | {
192 | GameDriverOptions o = driver.flags;
193 |
194 | if (o & (GameDriverMachineClickableArtwork | GameDriverMachineRequiresArtwork | GameDriverMachineMechanical))
195 | {
196 | if (error != nil)
197 | {
198 | *error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:@{
199 | NSLocalizedDescriptionKey : @"Unable to load ROM.",
200 | NSLocalizedRecoverySuggestionErrorKey: [NSString stringWithFormat:@"\"%@\" (%@).\n\nMechanical systems or systems which require artwork to operate are not supported.", driver.fullName, driver.name],
201 | }];
202 | }
203 | return NO;
204 | }
205 |
206 | if (driverIsNotWorking(o)) {
207 | if (error != nil)
208 | {
209 | *error = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:@{
210 | NSLocalizedDescriptionKey : @"Unable to load ROM.",
211 | 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],
212 | }];
213 | }
214 | return NO;
215 | }
216 |
217 | return YES;
218 | }
219 |
220 | - (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error
221 | {
222 | NSString *romDir = [path stringByDeletingLastPathComponent];
223 | Options *opts = _osd.options;
224 | [opts setBasePath:self.supportDirectoryPath];
225 | opts.romsPath = romDir;
226 | BOOL prev;
227 | prev = opts.autoStretchXY;
228 | opts.autoStretchXY = NO;
229 | prev = opts.unevenStretchX;
230 | opts.unevenStretchX = NO;
231 | prev = opts.unevenStretchY;
232 | opts.unevenStretchY = NO;
233 | prev = opts.unevenStretch;
234 | opts.unevenStretch = NO;
235 | opts.keepAspect = YES;
236 |
237 | _osd.verboseOutput = NO; // TODO: debug only; remove later
238 |
239 | NSString *rom = [[path lastPathComponent] stringByDeletingPathExtension];
240 | AuditResult *ar;
241 | BOOL success = [_osd setDriver:rom withAuditResult:&ar error:error];
242 | if (!success)
243 | {
244 | return NO;
245 | }
246 |
247 | if (![self validateGameDriver:_osd.driver error:error])
248 | {
249 | return NO;
250 | }
251 |
252 | if (ar.summary == AuditSummaryIncorrect || ar.summary == AuditSummaryNotFound)
253 | {
254 | if (error != nil)
255 | {
256 | *error = [self processAuditResult:ar forRomDir:romDir];
257 | }
258 | return NO;
259 | }
260 |
261 | if (![_osd initializeWithError:error])
262 | {
263 | return NO;
264 | }
265 |
266 | _supportsRewinding = _osd.supportsSave && _osd.stateSize < 1e6;
267 | if (_osd.supportsSave && !_supportsRewinding)
268 | {
269 | os_log_info(OE_CORE_LOG, "disabling rewind support, save state size too big %{iec-bytes}ld", _osd.stateSize);
270 | }
271 |
272 | return YES;
273 | }
274 |
275 | - (NSError *)processAuditResult:(AuditResult *)ar forRomDir:(NSString *)romDir
276 | {
277 | GameDriver *driver = _osd.driver;
278 | NSString *gameDriverName = driver.name;
279 | NSMutableOrderedSet *results = [NSMutableOrderedSet new];
280 |
281 | for (AuditRecord *rec in ar.records) {
282 |
283 | switch (rec.substatus) {
284 | case AuditSubstatusGood:
285 | continue;
286 |
287 | case AuditSubstatusFoundNodump:
288 | case AuditSubstatusGoodNeedsRedump:
289 | case AuditSubstatusNotFoundNoDump:
290 | case AuditSubstatusNotFoundOptional:
291 | // acceptable conditions, based on audit.cpp:media_auditor::summarize method,
292 | // which all result in a BEST_AVAILABLE status
293 | continue;
294 |
295 | // bad conditions
296 |
297 | case AuditSubstatusFoundWrongLength: {
298 | os_log_debug(OE_CORE_AUDIT_LOG, "wrong length: %{public}@, media type %ld", rec.name, rec.mediaType);
299 | [results addObject:[[MAMEAuditResult alloc] initWithDriver:gameDriverName auditRecord:rec]];
300 | break;
301 | }
302 |
303 | case AuditSubstatusFoundBadChecksum: {
304 | os_log_debug(OE_CORE_AUDIT_LOG, "bad checksum: %{public}@, media type %ld", rec.name, rec.mediaType);
305 | [results addObject:[[MAMEAuditResult alloc] initWithDriver:gameDriverName auditRecord:rec]];
306 | break;
307 | }
308 |
309 | case AuditSubstatusNotFound: {
310 | os_log_debug(OE_CORE_AUDIT_LOG, "not found: %{public}@, media type %ld", rec.name, rec.mediaType);
311 | [results addObject:[[MAMEAuditResult alloc] initWithDriver:gameDriverName auditRecord:rec]];
312 | break;
313 | }
314 |
315 | case AuditSubstatusUnverified:
316 | default:
317 | continue;
318 | }
319 | }
320 |
321 | // Sort missing files by ascending order
322 | NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self"
323 | ascending:YES];
324 | [results sortUsingDescriptors:@[sortDescriptor]];
325 |
326 | // Determine if ROMs exist with missing files, or are not found
327 | NSURL *romDirURL = [NSURL fileURLWithPath:romDir isDirectory:YES];
328 | NSMutableString *missingFilesList = [NSMutableString string];
329 | for(MAMEAuditResult *result in results)
330 | {
331 | if ([result checkSetExistsInDir:romDirURL])
332 | {
333 | [missingFilesList appendString:[NSString stringWithFormat:@"%@ \t- INCORRECT SET\n", result.fileName]];
334 | }
335 | else
336 | {
337 | [missingFilesList appendString:[NSString stringWithFormat:@"%@ \t- NOT FOUND\n", result.fileName]];
338 | }
339 | }
340 |
341 | // Give an audit report to the user
342 | NSString *game = [NSString stringWithFormat:@"%@ (%@.zip)", driver.fullName, gameDriverName];
343 | NSString *versionRequired = [[[[[self owner] bundle] infoDictionary] objectForKey:@"CFBundleVersion"] substringToIndex:5];
344 |
345 | NSError *outErr = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotLoadROMError userInfo:@{
346 | NSLocalizedDescriptionKey : @"Required files are missing.",
347 | 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],
348 | }];
349 |
350 | return outErr;
351 | }
352 |
353 | - (void)resetEmulation
354 | {
355 | [_osd scheduleHardReset];
356 | }
357 |
358 | #pragma mark - Video
359 |
360 | - (const void *)getVideoBufferWithHint:(void *)hint
361 | {
362 | _buffer = (uint32_t *)hint;
363 | [_osd setBuffer:hint size:NSSizeFromOEIntSize(_bufferSize)];
364 | return _buffer;
365 | }
366 |
367 | - (OEIntSize)bufferSize
368 | {
369 | return _bufferSize;
370 | }
371 |
372 | - (OEIntRect)screenRect {
373 | return _screenRect;
374 | }
375 |
376 | - (OEIntSize)aspectSize
377 | {
378 | return _aspectSize;
379 | }
380 |
381 | - (GLenum)pixelFormat
382 | {
383 | return GL_BGRA;
384 | }
385 |
386 | - (GLenum)pixelType
387 | {
388 | return GL_UNSIGNED_INT_8_8_8_8_REV;
389 | }
390 |
391 | #pragma mark - execution
392 |
393 | - (void)executeFrame
394 | {
395 | [_osd execute];
396 | }
397 |
398 | - (void)stopEmulation
399 | {
400 | [_osd unload];
401 | _osd.delegate = nil;
402 | [super stopEmulation];
403 | }
404 |
405 | - (NSTimeInterval)frameInterval
406 | {
407 | return _frameInterval;
408 | }
409 |
410 | #pragma mark - Audio
411 |
412 | - (double)audioSampleRate
413 | {
414 | return 48000;
415 | }
416 |
417 | - (NSUInteger)channelCount
418 | {
419 | return 2;
420 | }
421 |
422 | #pragma mark - Input
423 |
424 | - (void)setState:(BOOL)pressed ofButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
425 | {
426 | _buttons[player-1][button] = pressed ? 1 : 0;
427 | _axes[player-1][0] = _buttons[player-1][OEArcadeButtonLeft] ? InputAbsoluteMin : (_buttons[player-1][OEArcadeButtonRight] ? InputAbsoluteMax : 0);
428 | _axes[player-1][1] = _buttons[player-1][OEArcadeButtonUp] ? InputAbsoluteMin : (_buttons[player-1][OEArcadeButtonDown] ? InputAbsoluteMax : 0);
429 | }
430 |
431 | - (oneway void)didPushArcadeButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
432 | {
433 | [self setState:YES ofButton:button forPlayer:player];
434 | }
435 |
436 | - (oneway void)didReleaseArcadeButton:(OEArcadeButton)button forPlayer:(NSUInteger)player
437 | {
438 | [self setState:NO ofButton:button forPlayer:player];
439 | }
440 |
441 | #pragma mark - Save State
442 |
443 | - (void)saveStateToFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
444 | {
445 | BOOL res = NO;
446 | NSError *err = nil;
447 |
448 | if (_osd.supportsSave)
449 | {
450 | res = [_osd saveStateFromFileAtPath:fileName error:&err];
451 | }
452 | else
453 | {
454 | err = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotSaveStateError userInfo:@{
455 | NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Game \"%@\" does not not support save states.", _osd.driver.fullName],
456 | }];
457 | }
458 |
459 | block(res, err);
460 | }
461 |
462 | - (void)loadStateFromFileAtPath:(NSString *)fileName completionHandler:(void (^)(BOOL, NSError *))block
463 | {
464 | BOOL res = NO;
465 | NSError *err = nil;
466 |
467 | if (_osd.supportsSave)
468 | {
469 | res = [_osd loadStateFromFileAtPath:fileName error:&err];
470 | }
471 | else
472 | {
473 | err = [NSError errorWithDomain:OEGameCoreErrorDomain code:OEGameCoreCouldNotSaveStateError userInfo:@{
474 | NSLocalizedDescriptionKey : [NSString stringWithFormat:@"Game \"%@\" does not not support save states.", _osd.driver.fullName],
475 | }];
476 | }
477 |
478 | block(res, err);
479 | }
480 |
481 | - (BOOL)supportsRewinding
482 | {
483 | return _supportsRewinding;
484 | }
485 |
486 | - (NSData *)serializeStateWithError:(NSError *__autoreleasing *)outError
487 | {
488 | return [_osd serializeState];
489 | }
490 |
491 | - (BOOL)deserializeState:(NSData *)state withError:(NSError *__autoreleasing *)outError
492 | {
493 | return [_osd deserializeState:state];
494 | }
495 |
496 | @end
497 |
498 | @implementation MAMEAuditResult
499 | {
500 | NSString *_driver;
501 | AuditRecord *_record;
502 | }
503 |
504 | - (instancetype)initWithDriver:(NSString *)driver auditRecord:(AuditRecord *)record
505 | {
506 | if ((self = [super init]))
507 | {
508 | _driver = driver;
509 | _record = record;
510 | }
511 | return self;
512 | }
513 |
514 | - (NSString *)identifier
515 | {
516 | if (_record.mediaType == AuditMediaTypeDisk)
517 | {
518 | // a CHD
519 | return _record.name;
520 | }
521 |
522 | Device *parent = _record.sharedDevice;
523 | if (parent)
524 | {
525 | return parent.shortName;
526 | }
527 |
528 | return _driver;
529 | }
530 |
531 | - (NSArray *)extensions
532 | {
533 | if (_record.mediaType == AuditMediaTypeDisk)
534 | {
535 | return @[@".chd"];
536 | }
537 |
538 | return @[@".zip", @".7z"];
539 | }
540 |
541 | - (BOOL)isEqual:(id)object
542 | {
543 | if (object == nil || ![object isKindOfClass:self.class])
544 | {
545 | return NO;
546 | }
547 |
548 | MAMEAuditResult *other = (MAMEAuditResult *)object;
549 | return self.identifier == other.identifier;
550 | }
551 |
552 | - (NSComparisonResult)compare:(MAMEAuditResult *)other
553 | {
554 | return [self.identifier compare:other.identifier];
555 | }
556 |
557 | /*! Returns the first valid file name for this result
558 | */
559 | - (NSString *)fileName
560 | {
561 | return [self.identifier stringByAppendingString:[[self extensions] firstObject]];
562 | }
563 |
564 | /*! Determines if the ROM set exists
565 | */
566 | - (BOOL)checkSetExistsInDir:(NSURL *)dir
567 | {
568 | for (NSString *ext in [self extensions])
569 | {
570 | NSURL *missingFileURL = [dir URLByAppendingPathComponent:[self.identifier stringByAppendingString:ext]];
571 |
572 | if([missingFileURL checkResourceIsReachableAndReturnError:nil])
573 | {
574 | return YES;
575 | }
576 | }
577 | return NO;
578 | }
579 |
580 | - (NSUInteger)hash
581 | {
582 | return self.identifier.hash;
583 | }
584 |
585 | @end
586 |
--------------------------------------------------------------------------------
/MAME_Prefix.pch:
--------------------------------------------------------------------------------
1 | #include "osd_config.h"
2 | #include "osdcomm.h"
3 |
4 | #ifdef __OBJC__
5 | #import
6 | #endif
7 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | UME-Core
2 | ========
3 |
4 | OpenEmu Core plugin for UME
5 |
6 | Building
7 | --------
8 |
9 | You must build the `mamearcade_headless.dylib` dynamic library before building the MAME Game core:
10 |
11 | ```sh
12 | $ cd deps/mame
13 | $ make macosx_x64_clang OSD="headless" verbose=1 TARGETOS="macosx" CONFIG="release" TARGET=mame SUBTARGET=arcade MACOSX_DEPLOYMENT_TARGET=12.4 -j8
14 | $ install_name_tool -id mamearcade_headless.dylib mamearcade_headless.dylib
15 | ```
16 |
17 | 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.
18 |
19 | Build the UME project, which will link and embed this binary and update the loader path automatically.
20 |
21 |
--------------------------------------------------------------------------------