diff --git a/Info.plist b/Info.plist index a00d7d4f0..5092a6acf 100644 --- a/Info.plist +++ b/Info.plist @@ -22,6 +22,20 @@ CFBundleTypeRole None + + CFBundleTypeExtensions + + mo3 + + LSTypeIsPackage + + CFBundleTypeRole + Viewer + CFBundleTypeIconFile + song.icns + CFBundleTypeName + MO3 Audio File + CFBundleTypeExtensions diff --git a/Plugins/Dumb/Dumb.xcodeproj/project.pbxproj b/Plugins/Dumb/Dumb.xcodeproj/project.pbxproj index a7d281006..ccd30fa76 100644 --- a/Plugins/Dumb/Dumb.xcodeproj/project.pbxproj +++ b/Plugins/Dumb/Dumb.xcodeproj/project.pbxproj @@ -19,6 +19,9 @@ 8337AAEE17FFA0000081AFF8 /* unrealfmtdata.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8337AAEA17FFA0000081AFF8 /* unrealfmtdata.cpp */; }; 8337AAF117FFA2D30081AFF8 /* j2b.c in Sources */ = {isa = PBXBuildFile; fileRef = 8337AAEF17FFA2D30081AFF8 /* j2b.c */; }; 8337AAF317FFA7640081AFF8 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8337AAF217FFA7640081AFF8 /* libz.dylib */; }; + 83527EE818242FD5002F170E /* libunmo3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83527EE618242FD5002F170E /* libunmo3.dylib */; }; + 83527EEB18243069002F170E /* mo3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83527EEA18243069002F170E /* mo3.c */; }; + 83527EED182432CA002F170E /* libunmo3.dylib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83527EE618242FD5002F170E /* libunmo3.dylib */; }; 8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -53,6 +56,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 83527EEC182432BD002F170E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 6; + files = ( + 83527EED182432CA002F170E /* libunmo3.dylib in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -78,6 +91,10 @@ 8337AAEF17FFA2D30081AFF8 /* j2b.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = j2b.c; sourceTree = ""; }; 8337AAF017FFA2D30081AFF8 /* j2b.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = j2b.h; sourceTree = ""; }; 8337AAF217FFA7640081AFF8 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 83527EE618242FD5002F170E /* libunmo3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libunmo3.dylib; path = ../../../ThirdParty/BASS/libunmo3.dylib; sourceTree = ""; }; + 83527EE718242FD5002F170E /* unmo3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unmo3.h; path = ../../../ThirdParty/BASS/unmo3.h; sourceTree = ""; }; + 83527EE918243029002F170E /* mo3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mo3.h; path = mo3/mo3.h; sourceTree = ""; }; + 83527EEA18243069002F170E /* mo3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mo3.c; path = mo3/mo3.c; sourceTree = ""; }; 8384912B1808155E00E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* Dumb.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Dumb.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -90,6 +107,7 @@ buildActionMask = 2147483647; files = ( 8337AAF317FFA7640081AFF8 /* libz.dylib in Frameworks */, + 83527EE818242FD5002F170E /* libunmo3.dylib in Frameworks */, 17C8F7B90CBEF380008D969D /* Dumb.framework in Frameworks */, 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, ); @@ -191,6 +209,7 @@ 8337AAE317FFA0000081AFF8 /* archive */ = { isa = PBXGroup; children = ( + 83527EE518242FBE002F170E /* mo3 */, 8337AAE417FFA0000081AFF8 /* j2b */, 8337AAE517FFA0000081AFF8 /* umx */, ); @@ -219,6 +238,17 @@ path = umx; sourceTree = ""; }; + 83527EE518242FBE002F170E /* mo3 */ = { + isa = PBXGroup; + children = ( + 83527EEA18243069002F170E /* mo3.c */, + 83527EE918243029002F170E /* mo3.h */, + 83527EE618242FD5002F170E /* libunmo3.dylib */, + 83527EE718242FD5002F170E /* unmo3.h */, + ); + name = mo3; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -230,6 +260,7 @@ 8D5B49B1048680CD000E48DA /* Sources */, 8D5B49B3048680CD000E48DA /* Frameworks */, 17C8F6A20CBEE86E008D969D /* CopyFiles */, + 83527EEC182432BD002F170E /* CopyFiles */, ); buildRules = ( ); @@ -303,6 +334,7 @@ 8337AAEC17FFA0000081AFF8 /* umx.mm in Sources */, 8335FF6717FF6FD9002D8DD2 /* DumbContainer.m in Sources */, 17C8F6950CBEE846008D969D /* DumbDecoder.m in Sources */, + 83527EEB18243069002F170E /* mo3.c in Sources */, 8337AAEE17FFA0000081AFF8 /* unrealfmtdata.cpp in Sources */, 17DA363E0CC0600E0003F6B2 /* DumbMetadataReader.m in Sources */, ); @@ -347,6 +379,10 @@ ); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /Users/Chris/Source/Repos/cog/ThirdParty/BASS, + ); OBJROOT = ../../build; PRODUCT_NAME = Dumb; SKIP_INSTALL = YES; @@ -369,6 +405,10 @@ ); INFOPLIST_FILE = Info.plist; INSTALL_PATH = "$(HOME)/Library/Bundles"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + /Users/Chris/Source/Repos/cog/ThirdParty/BASS, + ); OBJROOT = ../../build; PRODUCT_NAME = Dumb; SKIP_INSTALL = YES; diff --git a/Plugins/Dumb/DumbDecoder.m b/Plugins/Dumb/DumbDecoder.m index af52f3c6a..f4d18a894 100755 --- a/Plugins/Dumb/DumbDecoder.m +++ b/Plugins/Dumb/DumbDecoder.m @@ -10,6 +10,7 @@ #import "umx.h" #import "j2b.h" +#import "mo3.h" #import "Logging.h" @@ -19,6 +20,7 @@ struct MEMANDFREEFILE { char *ptr, *ptr_begin; long left, size; + int is_mo3; }; static int dumb_maffile_skip(void *f, long n) @@ -51,7 +53,8 @@ static long dumb_maffile_getnc(char *ptr, long n, void *f) static void dumb_maffile_close(void *f) { struct MEMANDFREEFILE *m = f; - free(m->ptr_begin); + if (m->is_mo3) freeMo3(m->ptr_begin); + else free(m->ptr_begin); free(f); } @@ -83,17 +86,26 @@ static const DUMBFILE_SYSTEM maffile_dfs = { DUMBFILE *dumbfile_open_memory_and_free(char *data, long size) { - char * try_data = unpackUmx( data, &size ); + int is_mo3 = 0; + char * try_data = unpackMo3( data, &size ); if ( try_data ) { free( data ); data = try_data; + is_mo3 = 1; } else { - try_data = unpackJ2b( data, &size ); + try_data = unpackUmx( data, &size ); if ( try_data ) { free( data ); data = try_data; } + else { + try_data = unpackJ2b( data, &size ); + if ( try_data ) { + free( data ); + data = try_data; + } + } } struct MEMANDFREEFILE *m = malloc(sizeof(*m)); @@ -103,6 +115,7 @@ DUMBFILE *dumbfile_open_memory_and_free(char *data, long size) m->ptr = data; m->left = size; m->size = size; + m->is_mo3 = is_mo3; return dumbfile_open_ex(m, &maffile_dfs); } @@ -319,7 +332,7 @@ int callbackLoop(void *data) + (NSArray *)fileTypes { - return [NSArray arrayWithObjects:@"it", @"itz", @"xm", @"xmz", @"s3m", @"s3z", @"mod", @"mdz", @"stm", @"stz", @"ptm", @"mtm", @"669", @"psm", @"am", @"j2b", @"dsm", @"amf", @"okt", @"okta", @"umx", nil]; + return [NSArray arrayWithObjects:@"it", @"itz", @"xm", @"xmz", @"s3m", @"s3z", @"mod", @"mdz", @"stm", @"stz", @"ptm", @"mtm", @"669", @"psm", @"am", @"j2b", @"dsm", @"amf", @"okt", @"okta", @"umx", @"mo3", nil]; } + (NSArray *)mimeTypes diff --git a/Plugins/Dumb/archive/j2b/j2b.h b/Plugins/Dumb/archive/j2b/j2b.h index 6042b2a46..95c9b745b 100644 --- a/Plugins/Dumb/archive/j2b/j2b.h +++ b/Plugins/Dumb/archive/j2b/j2b.h @@ -1,5 +1,5 @@ // -// umx.h +// j2b.h // Dumb J2B Archive parser // // Created by Christopher Snowhill on 10/4/13. diff --git a/Plugins/Dumb/archive/mo3/mo3.c b/Plugins/Dumb/archive/mo3/mo3.c new file mode 100644 index 000000000..eacbdc2d0 --- /dev/null +++ b/Plugins/Dumb/archive/mo3/mo3.c @@ -0,0 +1,44 @@ +// +// mo3.c +// Dumb MO3 Archive parser +// +// Created by Christopher Snowhill on 11/1/13. +// Copyright 2013 __NoWork, Inc__. All rights reserved. +// + +#include "mo3.h" + +#include +typedef uint32_t DWORD; + +#include "unmo3.h" + +#include +#include + +void * unpackMo3( const void * in, long * size ) +{ + void * data; + int len; + + if ( *size > INT_MAX ) + return 0; + + if ( memcmp( in, "MO3", 3 ) != 0 ) + return 0; + + data = (void *) in; + len = (int) *size; + + if ( UNMO3_Decode( &data, &len, 0 ) != 0 ) + return 0; + + *size = len; + + return data; +} + +void freeMo3( void * in ) +{ + UNMO3_Free( in ); +} diff --git a/Plugins/Dumb/archive/mo3/mo3.h b/Plugins/Dumb/archive/mo3/mo3.h new file mode 100644 index 000000000..ad73dea22 --- /dev/null +++ b/Plugins/Dumb/archive/mo3/mo3.h @@ -0,0 +1,16 @@ +// +// mo3.h +// Dumb MO3 Archive parser +// +// Created by Christopher Snowhill on 11/1/13. +// Copyright 2013 __NoWork, Inc__. All rights reserved. +// + +#ifdef __cplusplus +extern "C" { +#endif + extern void * unpackMo3( const void * in, long * size ); + extern void freeMo3( void * in ); +#ifdef __cplusplus +}; +#endif diff --git a/ThirdParty/BASS/libunmo3.dylib b/ThirdParty/BASS/libunmo3.dylib new file mode 100755 index 000000000..67e9ced3b Binary files /dev/null and b/ThirdParty/BASS/libunmo3.dylib differ diff --git a/ThirdParty/BASS/unmo3.h b/ThirdParty/BASS/unmo3.h new file mode 100755 index 000000000..88a2c114f --- /dev/null +++ b/ThirdParty/BASS/unmo3.h @@ -0,0 +1,33 @@ +/* + UNMO3 library C/C++ header file + Copyright (c) 2010-2013 Un4seen Developments Ltd. + + Free for non-commercial use +*/ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _WIN32 +#define WINAPI +#endif + +// Get the UNMO3 library version +DWORD WINAPI UNMO3_GetVersion(); + +// Decode a MO3 file +// in: data/len = MO3 data/len +// out: data/len = decoded data/len (if successful) +// return: 0 = Success, 2 = It isn't a MO3 file, 3 = There was a problem decoding the MO3 file +int WINAPI UNMO3_Decode(void **data, int *len, DWORD flags); + +// UNMO3_Decode flags +#define UNMO3_DECODE_NOSAMPLES 1 // don't process sample data + +// Free the data returned by UNMO3_Decode +void WINAPI UNMO3_Free(void *data); + +#ifdef __cplusplus +} +#endif