pcsxr-1.9.92
[pcsx_rearmed.git] / macosx / PluginList.m
... / ...
CommitLineData
1//
2// PluginList.m
3// Pcsx
4//
5// Created by Gil Pedersen on Sun Sep 21 2003.
6// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
7//
8
9#import "EmuThread.h"
10#import "PluginList.h"
11#import "PcsxPlugin.h"
12#include "psxcommon.h"
13#include "plugins.h"
14
15//NSMutableArray *plugins;
16static PluginList *sPluginList = nil;
17const static int typeList[4] = {PSE_LT_GPU, PSE_LT_SPU, PSE_LT_CDR, PSE_LT_PAD};
18
19@implementation PluginList
20
21+ (PluginList *)list
22{
23 return sPluginList;
24}
25
26#if 0
27+ (void)loadPlugins
28{
29 NSDirectoryEnumerator *dirEnum;
30 NSString *pname, *dir;
31
32 // Make sure we only load the plugins once
33 if (plugins != nil)
34 return;
35
36 plugins = [[NSMutableArray alloc] initWithCapacity: 20];
37
38 dir = [NSString stringWithCString:Config.PluginsDir];
39 dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dir];
40
41 while (pname = [dirEnum nextObject]) {
42 if ([[pname pathExtension] isEqualToString:@"psxplugin"] ||
43 [[pname pathExtension] isEqualToString:@"so"]) {
44 [dirEnum skipDescendents]; /* don't enumerate this
45 directory */
46
47 PcsxPlugin *plugin = [[PcsxPlugin alloc] initWithPath:pname];
48 if (plugin != nil) {
49 [plugins addObject:plugin];
50 }
51 }
52 }
53}
54
55- (id)initWithType:(int)typeMask
56{
57 unsigned int i;
58
59 self = [super init];
60
61 [PluginList loadPlugins];
62 list = [[NSMutableArray alloc] initWithCapacity: 5];
63
64 type = typeMask;
65 for (i=0; i<[plugins count]; i++) {
66 PcsxPlugin *plugin = [plugins objectAtIndex:i];
67 if ([plugin getType] == type) {
68 [list addObject:plugin];
69 }
70 }
71
72 return self;
73}
74
75- (int)numberOfItems
76{
77 return [list count];
78}
79
80- (id)objectAtIndex:(unsigned)index
81{
82 return [list objectAtIndex:index];
83}
84#endif
85
86
87
88- (id)init
89{
90 int i;
91
92 if (!(self = [super init]))
93 return nil;
94
95 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
96 pluginList = [[NSMutableArray alloc] initWithCapacity:20];
97
98 activeGpuPlugin = activeSpuPlugin = activeCdrPlugin = activePadPlugin = nil;
99
100 missingPlugins = NO;
101 for (i=0; i<sizeof(*typeList); i++) {
102 NSString *path = [defaults stringForKey:[PcsxPlugin getDefaultKeyForType:typeList[i]]];
103 if (nil == path) {
104 missingPlugins = YES;
105 continue;
106 }
107 if ([path isEqualToString:@"Disabled"])
108 continue;
109
110 if (![self hasPluginAtPath:path]) {
111 PcsxPlugin *plugin = [[PcsxPlugin alloc] initWithPath:path];
112 if (plugin) {
113 [pluginList addObject:plugin];
114 if (![self setActivePlugin:plugin forType:typeList[i]])
115 missingPlugins = YES;
116 } else {
117 missingPlugins = YES;
118 }
119 }
120 }
121
122 if (missingPlugins) {
123 [self refreshPlugins];
124 }
125
126 sPluginList = self;
127
128 return self;
129}
130
131- (void)dealloc
132{
133 [activeGpuPlugin release];
134 [activeSpuPlugin release];
135 [activeCdrPlugin release];
136 [activePadPlugin release];
137
138 [pluginList release];
139
140 if (sPluginList == self)
141 sPluginList = nil;
142
143 [super dealloc];
144}
145
146- (void)refreshPlugins
147{
148 NSDirectoryEnumerator *dirEnum;
149 NSString *pname, *dir;
150 int i;
151
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--;
156 }
157 }
158
159 // look for new ones in the plugin directory
160 dir = [NSString stringWithCString:Config.PluginsDir];
161 dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dir];
162
163 while (pname = [dirEnum nextObject]) {
164 if ([[pname pathExtension] isEqualToString:@"psxplugin"] ||
165 [[pname pathExtension] isEqualToString:@"so"]) {
166 [dirEnum skipDescendents]; /* don't enumerate this
167 directory */
168
169 if (![self hasPluginAtPath:pname]) {
170 PcsxPlugin *plugin = [[PcsxPlugin alloc] initWithPath:pname];
171 if (plugin != nil) {
172 [pluginList addObject:plugin];
173 }
174 }
175 }
176 }
177
178 // check the we have the needed plugins
179 missingPlugins = NO;
180 for (i=0; i<sizeof(*typeList); i++) {
181 PcsxPlugin *plugin = [self activePluginForType:typeList[i]];
182 if (nil == plugin) {
183 NSArray *list = [self pluginsForType:typeList[i]];
184 int j;
185
186 for (j=0; j<[list count]; j++) {
187 if ([self setActivePlugin:[list objectAtIndex:j] forType:typeList[i]])
188 break;
189 }
190 if (j == [list count])
191 missingPlugins = YES;
192 }
193 }
194}
195
196- (NSArray *)pluginsForType:(int)typeMask
197{
198 NSMutableArray *types = [NSMutableArray array];
199 int i;
200
201 for (i=0; i<[pluginList count]; i++) {
202 PcsxPlugin *plugin = [pluginList objectAtIndex:i];
203
204 if ([plugin getType] & typeMask) {
205 [types addObject:plugin];
206 }
207 }
208
209 return types;
210}
211
212- (BOOL)hasPluginAtPath:(NSString *)path
213{
214 if (nil == path)
215 return NO;
216
217 int i;
218 for (i=0; i<[pluginList count]; i++) {
219 if ([[[pluginList objectAtIndex:i] path] isEqualToString:path])
220 return YES;
221 }
222
223 return NO;
224}
225
226// returns if all the required plugins are available
227- (BOOL)configured
228{
229 return !missingPlugins;
230}
231
232- (BOOL)doInitPlugins
233{
234 BOOL bad = NO;
235
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;
240
241 return !bad;
242}
243
244- (PcsxPlugin *)activePluginForType:(int)type
245{
246 switch (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;
252 }
253
254 return nil;
255}
256
257- (BOOL)setActivePlugin:(PcsxPlugin *)plugin forType:(int)type
258{
259 PcsxPlugin **pluginPtr;
260 switch (type) {
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;
266 default: return NO;
267 }
268
269 if (plugin == *pluginPtr)
270 return YES;
271
272 BOOL active = (*pluginPtr) && [EmuThread active];
273 BOOL wasPaused = NO;
274 if (active) {
275 // TODO: temporary freeze?
276 wasPaused = [EmuThread pauseSafe];
277 ClosePlugins();
278 ReleasePlugins();
279 }
280
281 // stop the old plugin and start the new one
282 if (*pluginPtr) {
283 [*pluginPtr shutdownAs:type];
284
285 [*pluginPtr release];
286 }
287 *pluginPtr = [plugin retain];
288 if (*pluginPtr) {
289 if ([*pluginPtr initAs:type] != 0) {
290 [*pluginPtr release];
291 *pluginPtr = nil;
292 }
293 }
294
295 // write path to the correct config entry
296 const char *str;
297 if (*pluginPtr != nil) {
298 str = [[plugin path] fileSystemRepresentation];
299 if (str == nil) {
300 str = "Invalid Plugin";
301 }
302 } else {
303 str = "Invalid Plugin";
304 }
305
306 char **dst = [PcsxPlugin getConfigEntriesForType:type];
307 while (*dst) {
308 strncpy(*dst, str, 255);
309 dst++;
310 }
311
312 if (active) {
313 LoadPlugins();
314 OpenPlugins();
315
316 if (!wasPaused) {
317 [EmuThread resume];
318 }
319 }
320
321 return *pluginPtr != nil;
322}
323
324@end