2009-06-09 13:34:52 +02:00
|
|
|
//
|
|
|
|
// PluginList.m
|
2011-06-08 11:27:25 +02:00
|
|
|
// Pcsxr
|
2009-06-09 13:34:52 +02:00
|
|
|
//
|
|
|
|
// Created by Gil Pedersen on Sun Sep 21 2003.
|
|
|
|
// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "EmuThread.h"
|
|
|
|
#import "PluginList.h"
|
2011-06-08 11:27:25 +02:00
|
|
|
#import "PcsxrPlugin.h"
|
2009-06-09 13:34:52 +02:00
|
|
|
#include "psxcommon.h"
|
|
|
|
#include "plugins.h"
|
|
|
|
|
2013-09-10 20:18:15 +02:00
|
|
|
static PluginList __weak *sPluginList = nil;
|
2013-07-05 03:04:08 +02:00
|
|
|
const static int typeList[] = {PSE_LT_GPU, PSE_LT_SPU, PSE_LT_CDR, PSE_LT_PAD, PSE_LT_NET, PSE_LT_SIO1};
|
2009-06-09 13:34:52 +02:00
|
|
|
|
2013-09-13 23:31:56 +02:00
|
|
|
@interface PluginList ()
|
|
|
|
@property (strong) NSMutableArray *pluginList;
|
|
|
|
@property BOOL missingPlugins;
|
|
|
|
@property (strong) PcsxrPlugin *activeGpuPlugin;
|
|
|
|
@property (strong) PcsxrPlugin *activeSpuPlugin;
|
|
|
|
@property (strong) PcsxrPlugin *activeCdrPlugin;
|
|
|
|
@property (strong) PcsxrPlugin *activePadPlugin;
|
|
|
|
@property (strong) PcsxrPlugin *activeNetPlugin;
|
|
|
|
@property (strong) PcsxrPlugin *activeSIO1Plugin;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
2009-06-09 13:34:52 +02:00
|
|
|
@implementation PluginList
|
2013-09-13 23:31:56 +02:00
|
|
|
@synthesize missingPlugins;
|
2009-06-09 13:34:52 +02:00
|
|
|
|
|
|
|
+ (PluginList *)list
|
|
|
|
{
|
|
|
|
return sPluginList;
|
|
|
|
}
|
|
|
|
|
2014-07-21 22:24:55 +02:00
|
|
|
- (instancetype)init
|
2009-06-09 13:34:52 +02:00
|
|
|
{
|
2011-11-09 21:49:54 +01:00
|
|
|
NSUInteger i;
|
2009-06-09 13:34:52 +02:00
|
|
|
|
|
|
|
if (!(self = [super init]))
|
2011-11-12 21:07:20 +01:00
|
|
|
{
|
2009-06-09 13:34:52 +02:00
|
|
|
return nil;
|
2011-11-12 21:07:20 +01:00
|
|
|
}
|
2009-06-09 13:34:52 +02:00
|
|
|
|
|
|
|
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
2013-09-13 23:31:56 +02:00
|
|
|
self.pluginList = [[NSMutableArray alloc] initWithCapacity:20];
|
2009-06-09 13:34:52 +02:00
|
|
|
|
2013-09-13 23:31:56 +02:00
|
|
|
self.activeGpuPlugin = self.activeSpuPlugin = self.activeCdrPlugin = self.activePadPlugin = self.activeNetPlugin = self.activeSIO1Plugin = nil;
|
2009-06-09 13:34:52 +02:00
|
|
|
|
|
|
|
missingPlugins = NO;
|
2013-01-10 21:46:32 +01:00
|
|
|
for (i = 0; i < sizeof(typeList) / sizeof(typeList[0]); i++) {
|
2011-11-12 23:50:37 +01:00
|
|
|
NSString *path = [defaults stringForKey:[PcsxrPlugin defaultKeyForType:typeList[i]]];
|
2009-06-09 13:34:52 +02:00
|
|
|
if (nil == path) {
|
|
|
|
missingPlugins = YES;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ([path isEqualToString:@"Disabled"])
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (![self hasPluginAtPath:path]) {
|
2013-01-29 20:16:02 +01:00
|
|
|
@autoreleasepool {
|
|
|
|
PcsxrPlugin *plugin = [[PcsxrPlugin alloc] initWithPath:path];
|
|
|
|
if (plugin) {
|
2013-09-13 23:31:56 +02:00
|
|
|
[self.pluginList addObject:plugin];
|
2013-01-29 20:16:02 +01:00
|
|
|
if (![self setActivePlugin:plugin forType:typeList[i]])
|
|
|
|
missingPlugins = YES;
|
|
|
|
} else {
|
2009-06-09 13:34:52 +02:00
|
|
|
missingPlugins = YES;
|
2013-01-29 20:16:02 +01:00
|
|
|
}
|
2009-06-09 13:34:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-10 21:46:32 +01:00
|
|
|
|
2009-06-09 13:34:52 +02:00
|
|
|
if (missingPlugins) {
|
|
|
|
[self refreshPlugins];
|
|
|
|
}
|
|
|
|
|
|
|
|
sPluginList = self;
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)refreshPlugins
|
|
|
|
{
|
|
|
|
NSDirectoryEnumerator *dirEnum;
|
2013-01-29 20:16:02 +01:00
|
|
|
NSString *pname;
|
2011-11-09 21:49:54 +01:00
|
|
|
NSUInteger i;
|
2009-06-09 13:34:52 +02:00
|
|
|
|
|
|
|
// verify that the ones that are in list still works
|
2013-09-13 23:31:56 +02:00
|
|
|
for (i=0; i < [self.pluginList count]; i++) {
|
|
|
|
if (![(self.pluginList)[i] verifyOK]) {
|
|
|
|
[self.pluginList removeObjectAtIndex:i]; i--;
|
2009-06-09 13:34:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-17 21:41:31 +01:00
|
|
|
for (NSString *plugDir in [PcsxrPlugin pluginsPaths])
|
|
|
|
{
|
|
|
|
// look for new ones in the plugin directory
|
|
|
|
dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:plugDir];
|
|
|
|
|
|
|
|
while ((pname = [dirEnum nextObject])) {
|
|
|
|
if ([[pname pathExtension] isEqualToString:@"psxplugin"] ||
|
|
|
|
[[pname pathExtension] isEqualToString:@"so"]) {
|
|
|
|
[dirEnum skipDescendents]; /* don't enumerate this
|
|
|
|
directory */
|
|
|
|
|
|
|
|
if (![self hasPluginAtPath:pname]) {
|
2013-01-29 20:16:02 +01:00
|
|
|
@autoreleasepool {
|
|
|
|
PcsxrPlugin *plugin = [[PcsxrPlugin alloc] initWithPath:pname];
|
|
|
|
if (plugin != nil) {
|
2013-09-13 23:31:56 +02:00
|
|
|
[self.pluginList addObject:plugin];
|
2013-01-29 20:16:02 +01:00
|
|
|
}
|
2011-12-17 21:41:31 +01:00
|
|
|
}
|
2009-06-09 13:34:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// check the we have the needed plugins
|
|
|
|
missingPlugins = NO;
|
2013-07-09 09:07:15 +02:00
|
|
|
for (i=0; i < 4 /*sizeof(*typeList)*/; i++) {
|
2011-06-08 11:27:25 +02:00
|
|
|
PcsxrPlugin *plugin = [self activePluginForType:typeList[i]];
|
2009-06-09 13:34:52 +02:00
|
|
|
if (nil == plugin) {
|
|
|
|
NSArray *list = [self pluginsForType:typeList[i]];
|
2011-11-09 21:49:54 +01:00
|
|
|
NSUInteger j;
|
2009-06-09 13:34:52 +02:00
|
|
|
|
2012-10-13 22:39:01 +02:00
|
|
|
for (j=0; j < [list count]; j++) {
|
2013-09-10 20:43:18 +02:00
|
|
|
if ([self setActivePlugin:list[j] forType:typeList[i]])
|
2009-06-09 13:34:52 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (j == [list count])
|
|
|
|
missingPlugins = YES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *)pluginsForType:(int)typeMask
|
|
|
|
{
|
|
|
|
NSMutableArray *types = [NSMutableArray array];
|
|
|
|
|
2013-09-13 23:31:56 +02:00
|
|
|
for (PcsxrPlugin *plugin in self.pluginList) {
|
2011-11-12 23:50:37 +01:00
|
|
|
if ([plugin type] & typeMask) {
|
2009-06-09 13:34:52 +02:00
|
|
|
[types addObject:plugin];
|
|
|
|
}
|
|
|
|
}
|
2012-09-23 21:24:03 +02:00
|
|
|
|
2009-06-09 13:34:52 +02:00
|
|
|
return types;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)hasPluginAtPath:(NSString *)path
|
|
|
|
{
|
|
|
|
if (nil == path)
|
|
|
|
return NO;
|
|
|
|
|
2013-09-13 23:31:56 +02:00
|
|
|
for (PcsxrPlugin *plugin in self.pluginList) {
|
2012-09-23 21:24:03 +02:00
|
|
|
if ([[plugin path] isEqualToString:path])
|
2009-06-09 13:34:52 +02:00
|
|
|
return YES;
|
|
|
|
}
|
2012-09-23 21:24:03 +02:00
|
|
|
|
2009-06-09 13:34:52 +02:00
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
// returns if all the required plugins are available
|
|
|
|
- (BOOL)configured
|
|
|
|
{
|
|
|
|
return !missingPlugins;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)doInitPlugins
|
|
|
|
{
|
|
|
|
BOOL bad = NO;
|
|
|
|
|
2014-04-08 04:39:38 +02:00
|
|
|
if ([self.activeGpuPlugin runAs:PSE_LT_GPU] != 0)
|
|
|
|
bad = YES;
|
|
|
|
if ([self.activeSpuPlugin runAs:PSE_LT_SPU] != 0)
|
|
|
|
bad = YES;
|
|
|
|
if ([self.activeCdrPlugin runAs:PSE_LT_CDR] != 0)
|
|
|
|
bad = YES;
|
|
|
|
if ([self.activePadPlugin runAs:PSE_LT_PAD] != 0)
|
|
|
|
bad = YES;
|
|
|
|
if ([self.activeNetPlugin runAs:PSE_LT_NET] != 0)
|
|
|
|
bad = YES;
|
|
|
|
if ([self.activeSIO1Plugin runAs:PSE_LT_SIO1] != 0)
|
|
|
|
bad = YES;
|
2009-06-09 13:34:52 +02:00
|
|
|
|
|
|
|
return !bad;
|
|
|
|
}
|
|
|
|
|
2011-06-08 11:27:25 +02:00
|
|
|
- (PcsxrPlugin *)activePluginForType:(int)type
|
2009-06-09 13:34:52 +02:00
|
|
|
{
|
|
|
|
switch (type) {
|
2013-09-13 23:31:56 +02:00
|
|
|
case PSE_LT_GPU: return self.activeGpuPlugin; break;
|
|
|
|
case PSE_LT_CDR: return self.activeCdrPlugin; break;
|
|
|
|
case PSE_LT_SPU: return self.activeSpuPlugin; break;
|
|
|
|
case PSE_LT_PAD: return self.activePadPlugin; break;
|
|
|
|
case PSE_LT_NET: return self.activeNetPlugin; break;
|
|
|
|
case PSE_LT_SIO1: return self.activeSIO1Plugin; break;
|
2009-06-09 13:34:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
2011-06-08 11:27:25 +02:00
|
|
|
- (BOOL)setActivePlugin:(PcsxrPlugin *)plugin forType:(int)type
|
2009-06-09 13:34:52 +02:00
|
|
|
{
|
2013-01-09 02:50:38 +01:00
|
|
|
PcsxrPlugin *pluginPtr = nil;
|
|
|
|
|
|
|
|
switch (type) {
|
2013-07-05 03:04:08 +02:00
|
|
|
case PSE_LT_SIO1:
|
|
|
|
case PSE_LT_GPU:
|
|
|
|
case PSE_LT_CDR:
|
|
|
|
case PSE_LT_SPU:
|
|
|
|
case PSE_LT_PAD:
|
2013-01-10 02:02:14 +01:00
|
|
|
case PSE_LT_NET: pluginPtr = [self activePluginForType:type]; break;
|
|
|
|
default: return NO; break;
|
2013-01-09 02:50:38 +01:00
|
|
|
}
|
2013-01-10 02:02:14 +01:00
|
|
|
if (plugin == pluginPtr) {
|
2013-01-09 02:50:38 +01:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL active = pluginPtr && [EmuThread active];
|
|
|
|
BOOL wasPaused = NO;
|
|
|
|
if (active) {
|
|
|
|
// TODO: temporary freeze?
|
|
|
|
wasPaused = [EmuThread pauseSafe];
|
|
|
|
ClosePlugins();
|
|
|
|
ReleasePlugins();
|
|
|
|
}
|
|
|
|
|
|
|
|
// stop the old plugin and start the new one
|
|
|
|
if (pluginPtr) {
|
|
|
|
[pluginPtr shutdownAs:type];
|
2013-09-13 23:31:56 +02:00
|
|
|
pluginPtr = nil;
|
2013-01-09 02:50:38 +01:00
|
|
|
}
|
|
|
|
|
2013-01-10 02:02:14 +01:00
|
|
|
if ([plugin runAs:type] != 0) {
|
|
|
|
plugin = nil;
|
2013-01-09 02:50:38 +01:00
|
|
|
}
|
2014-04-08 04:39:38 +02:00
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case PSE_LT_GPU:
|
|
|
|
self.activeGpuPlugin = plugin;
|
|
|
|
break;
|
|
|
|
case PSE_LT_CDR:
|
|
|
|
self.activeCdrPlugin = plugin;
|
|
|
|
break;
|
|
|
|
case PSE_LT_SPU:
|
|
|
|
self.activeSpuPlugin = plugin;
|
|
|
|
break;
|
|
|
|
case PSE_LT_PAD:
|
|
|
|
self.activePadPlugin = plugin;
|
|
|
|
break;
|
|
|
|
case PSE_LT_NET:
|
|
|
|
self.activeNetPlugin = plugin;
|
|
|
|
break;
|
|
|
|
case PSE_LT_SIO1:
|
|
|
|
self.activeSIO1Plugin = plugin;
|
|
|
|
break;
|
2013-01-09 02:50:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// write path to the correct config entry
|
|
|
|
const char *str;
|
2013-01-10 02:02:14 +01:00
|
|
|
if (plugin != nil) {
|
2013-01-09 02:50:38 +01:00
|
|
|
str = [[plugin path] fileSystemRepresentation];
|
2013-01-10 21:46:32 +01:00
|
|
|
if (str == NULL) {
|
2013-01-09 02:50:38 +01:00
|
|
|
str = "Invalid Plugin";
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
str = "Invalid Plugin";
|
|
|
|
}
|
|
|
|
|
|
|
|
char **dst = [PcsxrPlugin configEntriesForType:type];
|
|
|
|
while (*dst) {
|
2013-01-10 02:02:14 +01:00
|
|
|
strlcpy(*dst, str, MAXPATHLEN);
|
2013-01-09 02:50:38 +01:00
|
|
|
dst++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (active) {
|
|
|
|
LoadPlugins();
|
|
|
|
OpenPlugins();
|
|
|
|
|
|
|
|
if (!wasPaused) {
|
|
|
|
[EmuThread resume];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-10 02:02:14 +01:00
|
|
|
return plugin != nil;
|
2009-06-09 13:34:52 +02:00
|
|
|
}
|
|
|
|
|
2013-01-10 21:46:32 +01:00
|
|
|
- (void)disableNetPlug
|
|
|
|
{
|
|
|
|
char **dst = [PcsxrPlugin configEntriesForType:PSE_LT_NET];
|
|
|
|
while (*dst) {
|
|
|
|
strcpy(*dst, "Disabled");
|
|
|
|
dst++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)enableNetPlug
|
|
|
|
{
|
|
|
|
PcsxrPlugin *netPlug = [self activePluginForType:PSE_LT_NET];
|
|
|
|
|
|
|
|
const char *str = NULL;
|
|
|
|
if (netPlug) {
|
|
|
|
str = [[netPlug path] fileSystemRepresentation];
|
|
|
|
}
|
|
|
|
if (str) {
|
|
|
|
char **dst = [PcsxrPlugin configEntriesForType:PSE_LT_NET];
|
|
|
|
while (*dst) {
|
|
|
|
strlcpy(*dst, str, MAXPATHLEN);
|
|
|
|
dst++;
|
|
|
|
}
|
|
|
|
}
|
2014-09-27 21:35:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSInteger)count;
|
|
|
|
{
|
|
|
|
return self.pluginList.count;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(__unsafe_unretained id [])buffer count:(NSUInteger)len
|
|
|
|
{
|
|
|
|
return [self.pluginList countByEnumeratingWithState:state objects:buffer count:len];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (PcsxrPlugin*)objectAtIndexedSubscript:(NSInteger)index
|
|
|
|
{
|
|
|
|
return self.pluginList[index];
|
2013-01-10 21:46:32 +01:00
|
|
|
}
|
|
|
|
|
2009-06-09 13:34:52 +02:00
|
|
|
@end
|