pcsxr/macosx/Source/PluginList.m

333 lines
7.1 KiB
Objective-C

//
// PluginList.m
// Pcsxr
//
// Created by Gil Pedersen on Sun Sep 21 2003.
// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//
#import "EmuThread.h"
#import "PluginList.h"
#import "PcsxrPlugin.h"
#include "psxcommon.h"
#include "plugins.h"
static PluginList __weak *sPluginList = nil;
const static int typeList[] = {PSE_LT_GPU, PSE_LT_SPU, PSE_LT_CDR, PSE_LT_PAD, PSE_LT_NET, PSE_LT_SIO1};
@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
@implementation PluginList
@synthesize missingPlugins;
+ (PluginList *)list
{
return sPluginList;
}
- (instancetype)init
{
NSUInteger i;
if (!(self = [super init]))
{
return nil;
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.pluginList = [[NSMutableArray alloc] initWithCapacity:20];
self.activeGpuPlugin = self.activeSpuPlugin = self.activeCdrPlugin = self.activePadPlugin = self.activeNetPlugin = self.activeSIO1Plugin = nil;
missingPlugins = NO;
for (i = 0; i < sizeof(typeList) / sizeof(typeList[0]); i++) {
NSString *path = [defaults stringForKey:[PcsxrPlugin defaultKeyForType:typeList[i]]];
if (nil == path) {
missingPlugins = YES;
continue;
}
if ([path isEqualToString:@"Disabled"])
continue;
if (![self hasPluginAtPath:path]) {
@autoreleasepool {
PcsxrPlugin *plugin = [[PcsxrPlugin alloc] initWithPath:path];
if (plugin) {
[self.pluginList addObject:plugin];
if (![self setActivePlugin:plugin forType:typeList[i]])
missingPlugins = YES;
} else {
missingPlugins = YES;
}
}
}
}
if (missingPlugins) {
[self refreshPlugins];
}
sPluginList = self;
return self;
}
- (void)refreshPlugins
{
NSDirectoryEnumerator *dirEnum;
NSString *pname;
NSUInteger i;
// verify that the ones that are in list still works
for (i=0; i < [self.pluginList count]; i++) {
if (![(self.pluginList)[i] verifyOK]) {
[self.pluginList removeObjectAtIndex:i]; i--;
}
}
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]) {
@autoreleasepool {
PcsxrPlugin *plugin = [[PcsxrPlugin alloc] initWithPath:pname];
if (plugin != nil) {
[self.pluginList addObject:plugin];
}
}
}
}
}
}
// check the we have the needed plugins
missingPlugins = NO;
for (i=0; i < 4 /*sizeof(*typeList)*/; i++) {
PcsxrPlugin *plugin = [self activePluginForType:typeList[i]];
if (nil == plugin) {
NSArray *list = [self pluginsForType:typeList[i]];
NSUInteger j;
for (j=0; j < [list count]; j++) {
if ([self setActivePlugin:list[j] forType:typeList[i]])
break;
}
if (j == [list count])
missingPlugins = YES;
}
}
}
- (NSArray *)pluginsForType:(int)typeMask
{
NSMutableArray *types = [NSMutableArray array];
for (PcsxrPlugin *plugin in self.pluginList) {
if ([plugin type] & typeMask) {
[types addObject:plugin];
}
}
return types;
}
- (BOOL)hasPluginAtPath:(NSString *)path
{
if (nil == path)
return NO;
for (PcsxrPlugin *plugin in self.pluginList) {
if ([[plugin path] isEqualToString:path])
return YES;
}
return NO;
}
// returns if all the required plugins are available
- (BOOL)configured
{
return !missingPlugins;
}
- (BOOL)doInitPlugins
{
BOOL bad = NO;
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;
return !bad;
}
- (PcsxrPlugin *)activePluginForType:(int)type
{
switch (type) {
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;
}
return nil;
}
- (BOOL)setActivePlugin:(PcsxrPlugin *)plugin forType:(int)type
{
PcsxrPlugin *pluginPtr = nil;
switch (type) {
case PSE_LT_SIO1:
case PSE_LT_GPU:
case PSE_LT_CDR:
case PSE_LT_SPU:
case PSE_LT_PAD:
case PSE_LT_NET: pluginPtr = [self activePluginForType:type]; break;
default: return NO; break;
}
if (plugin == pluginPtr) {
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];
pluginPtr = nil;
}
if ([plugin runAs:type] != 0) {
plugin = nil;
}
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;
}
// write path to the correct config entry
const char *str;
if (plugin != nil) {
str = [[plugin path] fileSystemRepresentation];
if (str == NULL) {
str = "Invalid Plugin";
}
} else {
str = "Invalid Plugin";
}
char **dst = [PcsxrPlugin configEntriesForType:type];
while (*dst) {
strlcpy(*dst, str, MAXPATHLEN);
dst++;
}
if (active) {
LoadPlugins();
OpenPlugins();
if (!wasPaused) {
[EmuThread resume];
}
}
return plugin != nil;
}
- (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++;
}
}
}
- (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];
}
@end