9 Commits

3 changed files with 107 additions and 27 deletions
+1 -1
View File
@@ -19,7 +19,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>0.149.1</string>
<string>0.149.4</string>
<key>NSPrincipalClass</key>
<string>OEGameCoreController</string>
<key>OEGameCoreClass</key>
+103 -23
View File
@@ -53,7 +53,7 @@
GLuint _textureHeight;
uint32_t *_buffer;
NSString *_romDir;
NSURL *_romDir;
NSString *_driverName;
NSTimeInterval _frameInterval;
@@ -65,7 +65,7 @@
static void output_callback(delegate_late_bind *param, const char *format, va_list argptr)
{
NSLog(@"MAME: %@", [[NSString alloc] initWithFormat:[NSString stringWithUTF8String:format] arguments:argptr]);
NSLog(@"MAME: %@", [[NSString alloc] initWithFormat:@(format) arguments:argptr]);
}
static void error_callback(running_machine &machine, const char *string)
@@ -192,8 +192,7 @@ static INT32 joystick_get_state(void *device_internal, void *item_internal)
- (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error
{
_romDir = [path stringByDeletingLastPathComponent];
if(!_romDir) return NO;
_romDir = [NSURL fileURLWithPath:[path stringByDeletingLastPathComponent]];
// Need a better way to identify the ROM driver from the archive path
@@ -209,7 +208,7 @@ static INT32 joystick_get_state(void *device_internal, void *item_internal)
astring err;
emu_options options = emu_options();
options.set_value(OPTION_MEDIAPATH, [_romDir UTF8String], OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_MEDIAPATH, _romDir.fileSystemRepresentation, OPTION_PRIORITY_HIGH, err);
game_driver driver;
driver_enumerator drivlist(options, [_driverName UTF8String]);
@@ -223,24 +222,100 @@ static INT32 joystick_get_state(void *device_internal, void *item_internal)
{
driver = drivlist.driver();
verified = YES;
[NSThread detachNewThreadSelector:@selector(mameEmuThread) toTarget:self withObject:nil];
}
else
{
astring *output = new astring();
auditor.summarize(drivlist.driver().name, output);
NSString *auditOutput = @(output->cstr());
NSLog(@"MAME: Audit failed with output:\n%s", output->cstr());
delete output;
// Parse MAME's audit report and build a list of missing/incomplete required files
NSMutableOrderedSet *missingFilesSet = [NSMutableOrderedSet new];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(?<=NOT FOUND \\()(.*?)(?=\\)\n)|(?<=: )([^\\s]+)(.*?)(?= - NOT FOUND\n)" options:NSRegularExpressionCaseInsensitive error:nil];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:auditOutput options:0 range:NSMakeRange(0, auditOutput.length)];
DLog(@"regex matches: %lu", numberOfMatches);
NSString *gameDriverName = @(drivlist.driver().name);
[regex enumerateMatchesInString:auditOutput options:0 range:NSMakeRange(0, auditOutput.length) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
if (result == nil) return;
NSRange range = result.range;
NSRange secondGroup = [result rangeAtIndex:2];
NSRange thirdGroup = [result rangeAtIndex:3];
NSString *match = [auditOutput substringWithRange:range];
NSMutableString *fileName = [NSMutableString stringWithString:match];
// Assumed missing/incomplete parent, device or BIOS ROM
if(secondGroup.location == NSNotFound && thirdGroup.location == NSNotFound)
{
[fileName appendString:@".zip"];
}
// Assumed missing CHD
else if(secondGroup.location != NSNotFound && [auditOutput substringWithRange:thirdGroup].length == 0)
{
[fileName appendString:@".chd"];
}
// Assumed driver/clone ROM loaded is missing files
else
{
//NSString *match = [auditOutput substringWithRange:secondGroup];
fileName = [NSMutableString stringWithFormat:@"%@.zip", gameDriverName];
}
[missingFilesSet addObject:fileName];
}];
// Sort missing files by ascending order
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self"
ascending:YES];
[missingFilesSet sortUsingDescriptors:@[sortDescriptor]];
// Determine if ROMs exist with missing files, or are not found
NSMutableString *missingFilesList = [NSMutableString string];
for(NSString *missingFile in missingFilesSet)
{
NSURL *missingFileURL = [_romDir URLByAppendingPathComponent:missingFile];
if([missingFileURL checkResourceIsReachableAndReturnError:nil])
{
[missingFilesList appendString:[NSString stringWithFormat:@"%@ \t- INCORRECT SET\n", missingFile]];
}
else
{
[missingFilesList appendString:[NSString stringWithFormat:@"%@ \t- NOT FOUND\n", missingFile]];
}
}
// Give an audit report to the user
NSString *game = [NSString stringWithFormat:@"%@ (%@.zip)", @(drivlist.driver().description), @(drivlist.driver().name)];
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],
}];
*error = outErr;
}
}
return verified;
}
- (void)startEmulation
{
[super startEmulation];
[NSThread detachNewThreadSelector:@selector(mameEmuThread) toTarget:self withObject:nil];
}
// FIXME: Weird bug. This is not being called when restoring an autosave state on launch.
//- (void)startEmulation
//{
// [super startEmulation];
// [NSThread detachNewThreadSelector:@selector(mameEmuThread) toTarget:self withObject:nil];
//}
- (void)stopEmulation
{
@@ -279,27 +354,27 @@ static INT32 joystick_get_state(void *device_internal, void *item_internal)
astring err;
emu_options options = emu_options();
options.set_value(OPTION_MEDIAPATH, [_romDir UTF8String], OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_MEDIAPATH, _romDir.fileSystemRepresentation, OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_SAMPLEPATH,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"samples"] UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"samples"] fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_CFG_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"cfg"] UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"cfg"] fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_NVRAM_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"nvram"]UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"nvram"]fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_MEMCARD_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"memcard"] UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"memcard"] fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_INPUT_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"inp"] UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"inp"] fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_DIFF_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"diff"] UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"diff"] fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_COMMENT_DIRECTORY,
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"comments"] UTF8String],
[[[self supportDirectoryPath] stringByAppendingPathComponent:@"comments"] fileSystemRepresentation],
OPTION_PRIORITY_HIGH, err);
options.set_value(OPTION_SYSTEMNAME, [_driverName UTF8String], OPTION_PRIORITY_HIGH, err);
@@ -358,6 +433,11 @@ static INT32 joystick_get_state(void *device_internal, void *item_internal)
- (void)osd_update:(bool)skip_redraw
{
osd_event_set(_renderEvent);
if (!skip_redraw && !_machine->save_or_load_pending())
{
osd_event_set(_renderEvent);
}
}
- (void)executeFrame
@@ -511,11 +591,11 @@ static INT32 joystick_get_state(void *device_internal, void *item_internal)
OERingBuffer *ringBuffer = [self ringBufferAtIndex:0];
NSUInteger bytesPerSample = (self.audioBitDepth * self.channelCount) / 8;
NSUInteger bytesToWrite = samples_this_frame * bytesPerSample;
NSUInteger bytesAvailableToWrite = ringBuffer.availableBytes;
NSUInteger bytesAvailableToWrite = ringBuffer.freeBytes;
if(bytesToWrite > bytesAvailableToWrite)
{
NSLog(@"MAME: Audio buffer overflow");
DLog(@"MAME: Audio buffer overflow");
bytesToWrite = bytesAvailableToWrite;
}
@@ -567,7 +647,7 @@ static void _OESaveStateCallback(running_machine *machine)
_OESaveStateBlock = (__bridge_retained void *)[block copy];
if(_machine != NULL && _machine->system().flags & GAME_SUPPORTS_SAVE)
_machine->schedule_save([fileName UTF8String]);
_machine->schedule_save(fileName.fileSystemRepresentation);
else
{
NSLog(@"This game does not support save states!");
@@ -583,7 +663,7 @@ static void _OESaveStateCallback(running_machine *machine)
while(_initializing) usleep(100);
if(_machine != NULL && _machine->system().flags & GAME_SUPPORTS_SAVE)
_machine->schedule_load([fileName UTF8String]);
_machine->schedule_load(fileName.fileSystemRepresentation);
else
block(NO, nil);
}
+3 -3
View File
@@ -868,7 +868,7 @@ static INPUT_PORTS_START( outrun_generic )
PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_LOW )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Gear Shift") PORT_CODE(KEYCODE_SPACE) PORT_TOGGLE
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Gear Shift") PORT_TOGGLE
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_COIN2 )
@@ -946,7 +946,7 @@ static INPUT_PORTS_START( toutrun )
PORT_INCLUDE( outrun_generic )
PORT_MODIFY("SERVICE")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Turbo") PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Turbo")
PORT_MODIFY("DSW")
PORT_DIPNAME( 0x03, 0x01, DEF_STR( Cabinet ) ) PORT_DIPLOCATION("SWB:1,2")
@@ -1012,7 +1012,7 @@ static INPUT_PORTS_START( shangon )
PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Supercharger") PORT_CODE(KEYCODE_LSHIFT)
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Supercharger")
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )