5 // Created by Gil Pedersen on Fri Oct 03 2003.
6 // Copyright (c) 2003 __MyCompanyName__. All rights reserved.
9 #import <Cocoa/Cocoa.h>
10 #import "PcsxPlugin.h"
11 #include "psxcommon.h"
14 @implementation PcsxPlugin
16 + (NSString *)getPrefixForType:(int)aType
19 case PSE_LT_GPU: return @"GPU";
20 case PSE_LT_CDR: return @"CDR";
21 case PSE_LT_SPU: return @"SPU";
22 case PSE_LT_PAD: return @"PAD";
23 case PSE_LT_NET: return @"NET";
29 + (NSString *)getDefaultKeyForType:(int)aType
31 //return @"Plugin" [PcsxPlugin getPrefixForType:aType];
33 case PSE_LT_GPU: return @"PluginGPU";
34 case PSE_LT_CDR: return @"PluginCDR";
35 case PSE_LT_SPU: return @"PluginSPU";
36 case PSE_LT_PAD: return @"PluginPAD";
37 case PSE_LT_NET: return @"PluginNET";
43 + (char **)getConfigEntriesForType:(int)aType
45 static char *gpu[2] = {(char *)&Config.Gpu, NULL};
46 static char *cdr[2] = {(char *)&Config.Cdr, NULL};
47 static char *spu[2] = {(char *)&Config.Spu, NULL};
48 static char *pad[3] = {(char *)&Config.Pad1, (char *)&Config.Pad2, NULL};
49 static char *net[2] = {(char *)&Config.Net, NULL};
52 case PSE_LT_GPU: return (char **)gpu;
53 case PSE_LT_CDR: return (char **)cdr;
54 case PSE_LT_SPU: return (char **)spu;
55 case PSE_LT_PAD: return (char **)pad;
56 case PSE_LT_NET: return (char **)net;
62 - (id)initWithPath:(NSString *)aPath
64 if (!(self = [super init])) {
68 PSEgetLibType PSE_getLibType = NULL;
69 PSEgetLibVersion PSE_getLibVersion = NULL;
70 PSEgetLibName PSE_getLibName = NULL;
74 path = [aPath retain];
75 NSString *fullPath = [[NSString stringWithCString:Config.PluginsDir] stringByAppendingPathComponent:path];
77 pluginRef = SysLoadLibrary([fullPath fileSystemRepresentation]);
78 if (pluginRef == nil) {
83 // TODO: add support for plugins with multiple functionalities???
84 PSE_getLibType = (PSEgetLibType) SysLoadSym(pluginRef, "PSEgetLibType");
85 if (SysLibError() != nil) {
86 if (([path rangeOfString: @"gpu" options:NSCaseInsensitiveSearch]).length != 0)
88 else if (([path rangeOfString: @"cdr" options:NSCaseInsensitiveSearch]).length != 0)
90 else if (([path rangeOfString: @"spu" options:NSCaseInsensitiveSearch]).length != 0)
92 else if (([path rangeOfString: @"pad" options:NSCaseInsensitiveSearch]).length != 0)
99 type = (int)PSE_getLibType();
100 if (type != PSE_LT_GPU && type != PSE_LT_CDR && type != PSE_LT_SPU && type != PSE_LT_PAD) {
106 PSE_getLibName = (PSEgetLibName) SysLoadSym(pluginRef, "PSEgetLibName");
107 if (SysLibError() == nil) {
108 name = [[NSString alloc] initWithCString:PSE_getLibName()];
111 PSE_getLibVersion = (PSEgetLibVersion) SysLoadSym(pluginRef, "PSEgetLibVersion");
112 if (SysLibError() == nil) {
113 version = PSE_getLibVersion();
119 // save the current modification date
120 NSDictionary *fattrs = [[NSFileManager defaultManager] fileAttributesAtPath:fullPath traverseLink:YES];
121 modDate = [[fattrs fileModificationDate] retain];
132 // shutdown if we had previously been inited
133 for (i=0; i<32; i++) {
134 if (active & (1 << i)) {
135 [self shutdownAs:(1 << i)];
139 if (pluginRef) SysCloseLibrary(pluginRef);
147 - (void)runCommand:(id)arg
149 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
150 NSString *funcName = [arg objectAtIndex:0];
153 func = SysLoadSym(pluginRef, [funcName lossyCString]);
154 if (SysLibError() == nil) {
165 - (long)initAs:(int)aType
169 long (*initArg)(long arg);
170 int res = PSE_ERR_FATAL;
172 if ((active & aType) == aType) {
176 sprintf(symbol, "%sinit", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
177 init = initArg = SysLoadSym(pluginRef, symbol);
178 if (SysLibError() == nil) {
179 if (aType != PSE_LT_PAD)
188 NSRunCriticalAlertPanel(NSLocalizedString(@"Plugin Initialization Failed!", nil),
189 [NSString stringWithFormat:NSLocalizedString(@"Pcsx failed to initialize the selected %s plugin (error=%i).\nThe plugin might not work with your system.", nil), [PcsxPlugin getPrefixForType:aType], res],
196 - (long)shutdownAs:(int)aType
199 long (*shutdown)(void);
201 sprintf(symbol, "%sshutdown", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
202 shutdown = SysLoadSym(pluginRef, symbol);
203 if (SysLibError() == nil) {
208 return PSE_ERR_FATAL;
211 - (BOOL)hasAboutAs:(int)aType
215 sprintf(symbol, "%sabout", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
216 SysLoadSym(pluginRef, symbol);
218 return (SysLibError() == nil);
221 - (BOOL)hasConfigureAs:(int)aType
225 sprintf(symbol, "%sconfigure", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
226 SysLoadSym(pluginRef, symbol);
228 return (SysLibError() == nil);
231 - (void)aboutAs:(int)aType
236 sprintf(symbol, "%sabout", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
237 arg = [[NSArray alloc] initWithObjects:[NSString stringWithCString:symbol],
238 [NSNumber numberWithInt:0], nil];
240 // detach a new thread
241 [NSThread detachNewThreadSelector:@selector(runCommand:) toTarget:self
245 - (void)configureAs:(int)aType
250 sprintf(symbol, "%sconfigure", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
251 arg = [[NSArray alloc] initWithObjects:[NSString stringWithCString:symbol],
252 [NSNumber numberWithInt:1], nil];
254 // detach a new thread
255 [NSThread detachNewThreadSelector:@selector(runCommand:) toTarget:self
259 - (NSString *)getDisplayVersion
264 return [NSString stringWithFormat:@"v%ld.%ld.%ld", version>>16,(version>>8)&0xff,version&0xff];
282 - (NSString *)description
285 return [path lastPathComponent];
287 return [NSString stringWithFormat:@"%@ %@ [%@]", name, [self getDisplayVersion], [path lastPathComponent]];
290 // the plugin will check if it's still valid and return the status
293 // check that the file is still there with the same modification date
294 NSFileManager *dfm = [NSFileManager defaultManager];
295 NSString *fullPath = [[NSString stringWithCString:Config.PluginsDir] stringByAppendingPathComponent:path];
296 if (![dfm fileExistsAtPath:fullPath])
299 NSDictionary *fattrs = [dfm fileAttributesAtPath:fullPath traverseLink:YES];
300 return [[fattrs fileModificationDate] isEqualToDate:modDate];