5 // Created by Gil Pedersen on Sun Sep 21 2003.
6 // Copyright (c) 2003 __MyCompanyName__. All rights reserved.
10 #import "PluginList.h"
11 #import "PcsxPlugin.h"
12 #include "psxcommon.h"
15 //NSMutableArray *plugins;
16 static PluginList *sPluginList = nil;
17 const static int typeList[4] = {PSE_LT_GPU, PSE_LT_SPU, PSE_LT_CDR, PSE_LT_PAD};
19 @implementation PluginList
29 NSDirectoryEnumerator *dirEnum;
30 NSString *pname, *dir;
32 // Make sure we only load the plugins once
36 plugins = [[NSMutableArray alloc] initWithCapacity: 20];
38 dir = [NSString stringWithCString:Config.PluginsDir];
39 dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dir];
41 while (pname = [dirEnum nextObject]) {
42 if ([[pname pathExtension] isEqualToString:@"psxplugin"] ||
43 [[pname pathExtension] isEqualToString:@"so"]) {
44 [dirEnum skipDescendents]; /* don't enumerate this
47 PcsxPlugin *plugin = [[PcsxPlugin alloc] initWithPath:pname];
49 [plugins addObject:plugin];
55 - (id)initWithType:(int)typeMask
61 [PluginList loadPlugins];
62 list = [[NSMutableArray alloc] initWithCapacity: 5];
65 for (i=0; i<[plugins count]; i++) {
66 PcsxPlugin *plugin = [plugins objectAtIndex:i];
67 if ([plugin getType] == type) {
68 [list addObject:plugin];
80 - (id)objectAtIndex:(unsigned)index
82 return [list objectAtIndex:index];
92 if (!(self = [super init]))
95 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
96 pluginList = [[NSMutableArray alloc] initWithCapacity:20];
98 activeGpuPlugin = activeSpuPlugin = activeCdrPlugin = activePadPlugin = nil;
101 for (i=0; i<sizeof(*typeList); i++) {
102 NSString *path = [defaults stringForKey:[PcsxPlugin getDefaultKeyForType:typeList[i]]];
104 missingPlugins = YES;
107 if ([path isEqualToString:@"Disabled"])
110 if (![self hasPluginAtPath:path]) {
111 PcsxPlugin *plugin = [[PcsxPlugin alloc] initWithPath:path];
113 [pluginList addObject:plugin];
114 if (![self setActivePlugin:plugin forType:typeList[i]])
115 missingPlugins = YES;
117 missingPlugins = YES;
122 if (missingPlugins) {
123 [self refreshPlugins];
133 [activeGpuPlugin release];
134 [activeSpuPlugin release];
135 [activeCdrPlugin release];
136 [activePadPlugin release];
138 [pluginList release];
140 if (sPluginList == self)
146 - (void)refreshPlugins
148 NSDirectoryEnumerator *dirEnum;
149 NSString *pname, *dir;
152 // verify that the ones that are in list still works
153 for (i=0; i<[pluginList count]; i++) {
154 if (![[pluginList objectAtIndex:i] verifyOK]) {
155 [pluginList removeObjectAtIndex:i]; i--;
159 // look for new ones in the plugin directory
160 dir = [NSString stringWithCString:Config.PluginsDir];
161 dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dir];
163 while (pname = [dirEnum nextObject]) {
164 if ([[pname pathExtension] isEqualToString:@"psxplugin"] ||
165 [[pname pathExtension] isEqualToString:@"so"]) {
166 [dirEnum skipDescendents]; /* don't enumerate this
169 if (![self hasPluginAtPath:pname]) {
170 PcsxPlugin *plugin = [[PcsxPlugin alloc] initWithPath:pname];
172 [pluginList addObject:plugin];
178 // check the we have the needed plugins
180 for (i=0; i<sizeof(*typeList); i++) {
181 PcsxPlugin *plugin = [self activePluginForType:typeList[i]];
183 NSArray *list = [self pluginsForType:typeList[i]];
186 for (j=0; j<[list count]; j++) {
187 if ([self setActivePlugin:[list objectAtIndex:j] forType:typeList[i]])
190 if (j == [list count])
191 missingPlugins = YES;
196 - (NSArray *)pluginsForType:(int)typeMask
198 NSMutableArray *types = [NSMutableArray array];
201 for (i=0; i<[pluginList count]; i++) {
202 PcsxPlugin *plugin = [pluginList objectAtIndex:i];
204 if ([plugin getType] & typeMask) {
205 [types addObject:plugin];
212 - (BOOL)hasPluginAtPath:(NSString *)path
218 for (i=0; i<[pluginList count]; i++) {
219 if ([[[pluginList objectAtIndex:i] path] isEqualToString:path])
226 // returns if all the required plugins are available
229 return !missingPlugins;
232 - (BOOL)doInitPlugins
236 if ([activeGpuPlugin initAs:PSE_LT_GPU] != 0) bad = YES;
237 if ([activeSpuPlugin initAs:PSE_LT_SPU] != 0) bad = YES;
238 if ([activeCdrPlugin initAs:PSE_LT_CDR] != 0) bad = YES;
239 if ([activePadPlugin initAs:PSE_LT_PAD] != 0) bad = YES;
244 - (PcsxPlugin *)activePluginForType:(int)type
247 case PSE_LT_GPU: return activeGpuPlugin;
248 case PSE_LT_CDR: return activeCdrPlugin;
249 case PSE_LT_SPU: return activeSpuPlugin;
250 case PSE_LT_PAD: return activePadPlugin;
251 // case PSE_LT_NET: return activeNetPlugin;
257 - (BOOL)setActivePlugin:(PcsxPlugin *)plugin forType:(int)type
259 PcsxPlugin **pluginPtr;
261 case PSE_LT_GPU: pluginPtr = &activeGpuPlugin; break;
262 case PSE_LT_CDR: pluginPtr = &activeCdrPlugin; break;
263 case PSE_LT_SPU: pluginPtr = &activeSpuPlugin; break;
264 case PSE_LT_PAD: pluginPtr = &activePadPlugin; break;
265 // case PSE_LT_NET: pluginPtr = &activeNetPlugin; break;
269 if (plugin == *pluginPtr)
272 BOOL active = (*pluginPtr) && [EmuThread active];
275 // TODO: temporary freeze?
276 wasPaused = [EmuThread pauseSafe];
281 // stop the old plugin and start the new one
283 [*pluginPtr shutdownAs:type];
285 [*pluginPtr release];
287 *pluginPtr = [plugin retain];
289 if ([*pluginPtr initAs:type] != 0) {
290 [*pluginPtr release];
295 // write path to the correct config entry
297 if (*pluginPtr != nil) {
298 str = [[plugin path] fileSystemRepresentation];
300 str = "Invalid Plugin";
303 str = "Invalid Plugin";
306 char **dst = [PcsxPlugin getConfigEntriesForType:type];
308 strncpy(*dst, str, 255);
321 return *pluginPtr != nil;