aboutsummaryrefslogtreecommitdiff
path: root/macosx/PcsxPlugin.m
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/PcsxPlugin.m')
-rw-r--r--macosx/PcsxPlugin.m303
1 files changed, 303 insertions, 0 deletions
diff --git a/macosx/PcsxPlugin.m b/macosx/PcsxPlugin.m
new file mode 100644
index 0000000..9ee3111
--- /dev/null
+++ b/macosx/PcsxPlugin.m
@@ -0,0 +1,303 @@
+//
+// PcsxPlugin.m
+// Pcsx
+//
+// Created by Gil Pedersen on Fri Oct 03 2003.
+// Copyright (c) 2003 __MyCompanyName__. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "PcsxPlugin.h"
+#include "psxcommon.h"
+#include "plugins.h"
+
+@implementation PcsxPlugin
+
++ (NSString *)getPrefixForType:(int)aType
+{
+ switch (aType) {
+ case PSE_LT_GPU: return @"GPU";
+ case PSE_LT_CDR: return @"CDR";
+ case PSE_LT_SPU: return @"SPU";
+ case PSE_LT_PAD: return @"PAD";
+ case PSE_LT_NET: return @"NET";
+ }
+
+ return @"";
+}
+
++ (NSString *)getDefaultKeyForType:(int)aType
+{
+ //return @"Plugin" [PcsxPlugin getPrefixForType:aType];
+ switch (aType) {
+ case PSE_LT_GPU: return @"PluginGPU";
+ case PSE_LT_CDR: return @"PluginCDR";
+ case PSE_LT_SPU: return @"PluginSPU";
+ case PSE_LT_PAD: return @"PluginPAD";
+ case PSE_LT_NET: return @"PluginNET";
+ }
+
+ return @"";
+}
+
++ (char **)getConfigEntriesForType:(int)aType
+{
+ static char *gpu[2] = {(char *)&Config.Gpu, NULL};
+ static char *cdr[2] = {(char *)&Config.Cdr, NULL};
+ static char *spu[2] = {(char *)&Config.Spu, NULL};
+ static char *pad[3] = {(char *)&Config.Pad1, (char *)&Config.Pad2, NULL};
+ static char *net[2] = {(char *)&Config.Net, NULL};
+
+ switch (aType) {
+ case PSE_LT_GPU: return (char **)gpu;
+ case PSE_LT_CDR: return (char **)cdr;
+ case PSE_LT_SPU: return (char **)spu;
+ case PSE_LT_PAD: return (char **)pad;
+ case PSE_LT_NET: return (char **)net;
+ }
+
+ return nil;
+}
+
+- (id)initWithPath:(NSString *)aPath
+{
+ if (!(self = [super init])) {
+ return nil;
+ }
+
+ PSEgetLibType PSE_getLibType = NULL;
+ PSEgetLibVersion PSE_getLibVersion = NULL;
+ PSEgetLibName PSE_getLibName = NULL;
+
+ pluginRef = nil;
+ name = nil;
+ path = [aPath retain];
+ NSString *fullPath = [[NSString stringWithCString:Config.PluginsDir] stringByAppendingPathComponent:path];
+
+ pluginRef = SysLoadLibrary([fullPath fileSystemRepresentation]);
+ if (pluginRef == nil) {
+ [self release];
+ return nil;
+ }
+
+ // TODO: add support for plugins with multiple functionalities???
+ PSE_getLibType = (PSEgetLibType) SysLoadSym(pluginRef, "PSEgetLibType");
+ if (SysLibError() != nil) {
+ if (([path rangeOfString: @"gpu" options:NSCaseInsensitiveSearch]).length != 0)
+ type = PSE_LT_GPU;
+ else if (([path rangeOfString: @"cdr" options:NSCaseInsensitiveSearch]).length != 0)
+ type = PSE_LT_CDR;
+ else if (([path rangeOfString: @"spu" options:NSCaseInsensitiveSearch]).length != 0)
+ type = PSE_LT_SPU;
+ else if (([path rangeOfString: @"pad" options:NSCaseInsensitiveSearch]).length != 0)
+ type = PSE_LT_PAD;
+ else {
+ [self release];
+ return nil;
+ }
+ } else {
+ type = (int)PSE_getLibType();
+ if (type != PSE_LT_GPU && type != PSE_LT_CDR && type != PSE_LT_SPU && type != PSE_LT_PAD) {
+ [self release];
+ return nil;
+ }
+ }
+
+ PSE_getLibName = (PSEgetLibName) SysLoadSym(pluginRef, "PSEgetLibName");
+ if (SysLibError() == nil) {
+ name = [[NSString alloc] initWithCString:PSE_getLibName()];
+ }
+
+ PSE_getLibVersion = (PSEgetLibVersion) SysLoadSym(pluginRef, "PSEgetLibVersion");
+ if (SysLibError() == nil) {
+ version = PSE_getLibVersion();
+ }
+ else {
+ version = -1;
+ }
+
+ // save the current modification date
+ NSDictionary *fattrs = [[NSFileManager defaultManager] fileAttributesAtPath:fullPath traverseLink:YES];
+ modDate = [[fattrs fileModificationDate] retain];
+
+ active = 0;
+
+ return self;
+}
+
+- (void)dealloc
+{
+ int i;
+
+ // shutdown if we had previously been inited
+ for (i=0; i<32; i++) {
+ if (active & (1 << i)) {
+ [self shutdownAs:(1 << i)];
+ }
+ }
+
+ if (pluginRef) SysCloseLibrary(pluginRef);
+
+ [path release];
+ [name release];
+
+ [super dealloc];
+}
+
+- (void)runCommand:(id)arg
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSString *funcName = [arg objectAtIndex:0];
+ long (*func)(void);
+
+ func = SysLoadSym(pluginRef, [funcName lossyCString]);
+ if (SysLibError() == nil) {
+ func();
+ } else {
+ NSBeep();
+ }
+
+ [arg release];
+ [pool release];
+ return;
+}
+
+- (long)initAs:(int)aType
+{
+ char symbol[255];
+ long (*init)(void);
+ long (*initArg)(long arg);
+ int res = PSE_ERR_FATAL;
+
+ if ((active & aType) == aType) {
+ return 0;
+ }
+
+ sprintf(symbol, "%sinit", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
+ init = initArg = SysLoadSym(pluginRef, symbol);
+ if (SysLibError() == nil) {
+ if (aType != PSE_LT_PAD)
+ res = init();
+ else
+ res = initArg(1|2);
+ }
+
+ if (0 == res) {
+ active |= aType;
+ } else {
+ NSRunCriticalAlertPanel(NSLocalizedString(@"Plugin Initialization Failed!", nil),
+ [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],
+ nil, nil, nil);
+ }
+
+ return res;
+}
+
+- (long)shutdownAs:(int)aType
+{
+ char symbol[255];
+ long (*shutdown)(void);
+
+ sprintf(symbol, "%sshutdown", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
+ shutdown = SysLoadSym(pluginRef, symbol);
+ if (SysLibError() == nil) {
+ active &= ~aType;
+ return shutdown();
+ }
+
+ return PSE_ERR_FATAL;
+}
+
+- (BOOL)hasAboutAs:(int)aType
+{
+ char symbol[255];
+
+ sprintf(symbol, "%sabout", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
+ SysLoadSym(pluginRef, symbol);
+
+ return (SysLibError() == nil);
+}
+
+- (BOOL)hasConfigureAs:(int)aType
+{
+ char symbol[255];
+
+ sprintf(symbol, "%sconfigure", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
+ SysLoadSym(pluginRef, symbol);
+
+ return (SysLibError() == nil);
+}
+
+- (void)aboutAs:(int)aType
+{
+ NSArray *arg;
+ char symbol[255];
+
+ sprintf(symbol, "%sabout", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
+ arg = [[NSArray alloc] initWithObjects:[NSString stringWithCString:symbol],
+ [NSNumber numberWithInt:0], nil];
+
+ // detach a new thread
+ [NSThread detachNewThreadSelector:@selector(runCommand:) toTarget:self
+ withObject:arg];
+}
+
+- (void)configureAs:(int)aType
+{
+ NSArray *arg;
+ char symbol[255];
+
+ sprintf(symbol, "%sconfigure", [[PcsxPlugin getPrefixForType:aType] lossyCString]);
+ arg = [[NSArray alloc] initWithObjects:[NSString stringWithCString:symbol],
+ [NSNumber numberWithInt:1], nil];
+
+ // detach a new thread
+ [NSThread detachNewThreadSelector:@selector(runCommand:) toTarget:self
+ withObject:arg];
+}
+
+- (NSString *)getDisplayVersion
+{
+ if (version == -1)
+ return @"";
+
+ return [NSString stringWithFormat:@"v%ld.%ld.%ld", version>>16,(version>>8)&0xff,version&0xff];
+}
+
+- (int)getType
+{
+ return type;
+}
+
+- (NSString *)path
+{
+ return path;
+}
+
+- (unsigned)hash
+{
+ return [path hash];
+}
+
+- (NSString *)description
+{
+ if (name == nil)
+ return [path lastPathComponent];
+
+ return [NSString stringWithFormat:@"%@ %@ [%@]", name, [self getDisplayVersion], [path lastPathComponent]];
+}
+
+// the plugin will check if it's still valid and return the status
+- (BOOL)verifyOK
+{
+ // check that the file is still there with the same modification date
+ NSFileManager *dfm = [NSFileManager defaultManager];
+ NSString *fullPath = [[NSString stringWithCString:Config.PluginsDir] stringByAppendingPathComponent:path];
+ if (![dfm fileExistsAtPath:fullPath])
+ return NO;
+
+ NSDictionary *fattrs = [dfm fileAttributesAtPath:fullPath traverseLink:YES];
+ return [[fattrs fileModificationDate] isEqualToDate:modDate];
+}
+
+@end