Cocoa Port:

- In coreaudiosound.cpp, do not use deprecated Component Manager functions when running on OS X v10.6 or later.
- When checking the OS version, read SystemVersion.plist only once.
- Move the lowest-level utility functions to their own file, utilities.c.
- Geometry-based utility functions no longer take NSPoint and NSSize parameters, instead favoring raw double values.
- Disable JIT in the Legacy port, since it no longer works there and is too low priority an issue to make working again.
- Do a bunch of code cleanup.
This commit is contained in:
rogerman 2013-03-28 22:37:38 +00:00
parent e4d487bf14
commit 2ae5f548f9
19 changed files with 817 additions and 566 deletions

View File

@ -736,6 +736,13 @@
AB1816B615D216EC007A6CC3 /* OGLRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB06CD2E135B8ACE00E977B3 /* OGLRender.cpp */; };
AB1816B715D216F2007A6CC3 /* OGLRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB06CD2E135B8ACE00E977B3 /* OGLRender.cpp */; };
AB1816B815D216F5007A6CC3 /* OGLRender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB06CD2E135B8ACE00E977B3 /* OGLRender.cpp */; };
AB2F5B031704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB2F5B041704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB2F5B051704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB2F5B061704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB2F5B071704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB2F5B081704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB2F5B091704EE0100E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F5B021704EE0100E28885 /* utilities.c */; };
AB3AD16C14C4F6AD00D7D192 /* FileTypeInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB3AD16B14C4F6AD00D7D192 /* FileTypeInfo.plist */; };
AB3AD16D14C4F6AD00D7D192 /* FileTypeInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB3AD16B14C4F6AD00D7D192 /* FileTypeInfo.plist */; };
AB3AD16E14C4F6AD00D7D192 /* FileTypeInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB3AD16B14C4F6AD00D7D192 /* FileTypeInfo.plist */; };
@ -1310,6 +1317,8 @@
AB18155715D212B4007A6CC3 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; };
AB1815F315D21469007A6CC3 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; };
AB18169615D214F2007A6CC3 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; };
AB2F5B011704EE0100E28885 /* utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utilities.h; sourceTree = "<group>"; };
AB2F5B021704EE0100E28885 /* utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utilities.c; sourceTree = "<group>"; };
AB3AD16B14C4F6AD00D7D192 /* FileTypeInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = FileTypeInfo.plist; sourceTree = "<group>"; };
AB46780614ABD4890002FF94 /* AppIcon_DeSmuME.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_DeSmuME.icns; sourceTree = "<group>"; };
AB46780714ABD4890002FF94 /* AppIcon_NintendoDS_ROM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_NintendoDS_ROM.icns; sourceTree = "<group>"; };
@ -1539,6 +1548,7 @@
isa = PBXGroup;
children = (
ABC3ADEC14B7DC6E00D5B13D /* userinterface */,
AB2F5B021704EE0100E28885 /* utilities.c */,
ABD0A5621501AC5C0074A094 /* coreaudiosound.cpp */,
ABD0A5631501AC5C0074A094 /* ringbuffer.cpp */,
ABF4007E14B4F1C000578AE7 /* sndOSX.cpp */,
@ -1554,6 +1564,7 @@
ABD0A5651501AC5C0074A094 /* ringbuffer.h */,
ABE240FB14BE3169006EA2D5 /* screen_state_legacy.h */,
AB06CB49135B8A4D00E977B3 /* sndOSX.h */,
AB2F5B011704EE0100E28885 /* utilities.h */,
ABE240FD14BE3169006EA2D5 /* video_output_view_legacy.h */,
ABE240FC14BE3169006EA2D5 /* screen_state_legacy.m */,
ABBF052F14B5436E00E505A0 /* cocoa_file.mm */,
@ -2859,6 +2870,7 @@
ABF50C03169F61540018C08D /* x86func.cpp in Sources */,
ABF50C04169F61540018C08D /* x86operand.cpp in Sources */,
ABF50C05169F61540018C08D /* x86util.cpp in Sources */,
AB2F5B051704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2999,6 +3011,7 @@
ABF50C5A169F61540018C08D /* x86func.cpp in Sources */,
ABF50C5B169F61540018C08D /* x86operand.cpp in Sources */,
ABF50C5C169F61540018C08D /* x86util.cpp in Sources */,
AB2F5B081704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3139,6 +3152,7 @@
ABF50BC9169F61540018C08D /* x86func.cpp in Sources */,
ABF50BCA169F61540018C08D /* x86operand.cpp in Sources */,
ABF50BCB169F61540018C08D /* x86util.cpp in Sources */,
AB2F5B031704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3249,6 +3263,7 @@
AB18153D15D212B4007A6CC3 /* coreaudiosound.cpp in Sources */,
AB18153E15D212B4007A6CC3 /* ringbuffer.cpp in Sources */,
AB1816B615D216EC007A6CC3 /* OGLRender.cpp in Sources */,
AB2F5B071704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3359,6 +3374,7 @@
AB1815D915D21469007A6CC3 /* coreaudiosound.cpp in Sources */,
AB1815DA15D21469007A6CC3 /* ringbuffer.cpp in Sources */,
AB4F981716C30117000E90EA /* OGLRender.cpp in Sources */,
AB2F5B091704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3479,6 +3495,7 @@
AB18167F15D214F2007A6CC3 /* coreaudiosound.cpp in Sources */,
AB18168015D214F2007A6CC3 /* ringbuffer.cpp in Sources */,
AB1816B815D216F5007A6CC3 /* OGLRender.cpp in Sources */,
AB2F5B041704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3619,6 +3636,7 @@
ABF50C20169F61540018C08D /* x86func.cpp in Sources */,
ABF50C21169F61540018C08D /* x86operand.cpp in Sources */,
ABF50C22169F61540018C08D /* x86util.cpp in Sources */,
AB2F5B061704EE0100E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -234,6 +234,10 @@
AB2F3C3F15CF9C6000858373 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB350BA41478AC96007165AC /* IOKit.framework */; };
AB2F3C4015CF9C6000858373 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABC570D4134431DA00E7B0B1 /* OpenGL.framework */; };
AB2F3C4115CF9C6000858373 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0A0D1914AACA9600E83E91 /* libz.dylib */; };
AB2F56F01704C86900E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F56EF1704C86900E28885 /* utilities.c */; };
AB2F56F11704C86900E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F56EF1704C86900E28885 /* utilities.c */; };
AB2F56F21704C86900E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F56EF1704C86900E28885 /* utilities.c */; };
AB2F56F31704C86900E28885 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB2F56EF1704C86900E28885 /* utilities.c */; };
AB3ACB7814C2361100D7D192 /* appDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3ACB6714C2361100D7D192 /* appDelegate.mm */; };
AB3ACB7914C2361100D7D192 /* cheatWindowDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3ACB6914C2361100D7D192 /* cheatWindowDelegate.mm */; };
AB3ACB7C14C2361100D7D192 /* inputPrefsView.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3ACB6F14C2361100D7D192 /* inputPrefsView.mm */; };
@ -922,6 +926,8 @@
AB0F29A414BE7213009ABC6F /* Icon_ShowHUD_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_ShowHUD_420x420.png; path = images/Icon_ShowHUD_420x420.png; sourceTree = "<group>"; };
AB0F29A514BE7213009ABC6F /* Icon_Speaker_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Speaker_420x420.png; path = images/Icon_Speaker_420x420.png; sourceTree = "<group>"; };
AB2F3C4515CF9C6000858373 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; };
AB2F56EE1704C86900E28885 /* utilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utilities.h; sourceTree = "<group>"; };
AB2F56EF1704C86900E28885 /* utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utilities.c; sourceTree = "<group>"; };
AB350BA41478AC96007165AC /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
AB350D38147A1D8D007165AC /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = English; path = translations/English.lproj/HID_usage_strings.plist; sourceTree = "<group>"; };
AB3ACB6614C2361100D7D192 /* appDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = appDelegate.h; sourceTree = "<group>"; };
@ -1356,6 +1362,7 @@
isa = PBXGroup;
children = (
AB3ACB6514C2361100D7D192 /* userinterface */,
AB2F56EF1704C86900E28885 /* utilities.c */,
ABD0A5341501AA5A0074A094 /* coreaudiosound.cpp */,
ABD0A5351501AA5A0074A094 /* ringbuffer.cpp */,
ABD104141346652500AF11D1 /* sndOSX.cpp */,
@ -1374,6 +1381,7 @@
ABD0A5361501AA5A0074A094 /* coreaudiosound.h */,
ABD0A5371501AA5A0074A094 /* ringbuffer.h */,
ABD104011346652500AF11D1 /* sndOSX.h */,
AB2F56EE1704C86900E28885 /* utilities.h */,
ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */,
ABD104121346652500AF11D1 /* cocoa_core.mm */,
AB58F32C1364F44B0074C376 /* cocoa_file.mm */,
@ -2641,6 +2649,7 @@
AB4C4C5016F55C64002E07CD /* sse_optimized.cpp in Sources */,
AB4C4C5116F55C64002E07CD /* TDStretch.cpp in Sources */,
AB4C4C5216F55C64002E07CD /* WavFile.cpp in Sources */,
AB2F56F11704C86900E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2797,6 +2806,7 @@
AB4C4C4616F55C64002E07CD /* sse_optimized.cpp in Sources */,
AB4C4C4716F55C64002E07CD /* TDStretch.cpp in Sources */,
AB4C4C4816F55C64002E07CD /* WavFile.cpp in Sources */,
AB2F56F01704C86900E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2953,6 +2963,7 @@
AB4C4C6416F55C64002E07CD /* sse_optimized.cpp in Sources */,
AB4C4C6516F55C64002E07CD /* TDStretch.cpp in Sources */,
AB4C4C6616F55C64002E07CD /* WavFile.cpp in Sources */,
AB2F56F31704C86900E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3079,6 +3090,7 @@
AB4C4C5A16F55C64002E07CD /* sse_optimized.cpp in Sources */,
AB4C4C5B16F55C64002E07CD /* TDStretch.cpp in Sources */,
AB4C4C5C16F55C64002E07CD /* WavFile.cpp in Sources */,
AB2F56F21704C86900E28885 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -378,6 +378,9 @@
AB796D6B15CDCBA200C59155 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABC570D4134431DA00E7B0B1 /* OpenGL.framework */; };
AB796D6C15CDCBA200C59155 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0A0D1914AACA9600E83E91 /* libz.dylib */; };
AB80E04D142BC4A800A52038 /* cocoa_util.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB80E04C142BC4A800A52038 /* cocoa_util.mm */; };
AB82445B1704AE9A00B8EE20 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB82445A1704AE9A00B8EE20 /* utilities.c */; };
AB82445C1704AE9A00B8EE20 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB82445A1704AE9A00B8EE20 /* utilities.c */; };
AB82445D1704AE9A00B8EE20 /* utilities.c in Sources */ = {isa = PBXBuildFile; fileRef = AB82445A1704AE9A00B8EE20 /* utilities.c */; };
AB8967D916D2ED0700F826F1 /* DisplayWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */; };
AB8967DA16D2ED0700F826F1 /* DisplayWindowController.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */; };
AB8967DD16D2ED2700F826F1 /* DisplayWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB8967DB16D2ED2700F826F1 /* DisplayWindow.xib */; };
@ -675,10 +678,10 @@
AB0F29A314BE7213009ABC6F /* Icon_RotateCW_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_RotateCW_420x420.png; path = images/Icon_RotateCW_420x420.png; sourceTree = "<group>"; };
AB0F29A414BE7213009ABC6F /* Icon_ShowHUD_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_ShowHUD_420x420.png; path = images/Icon_ShowHUD_420x420.png; sourceTree = "<group>"; };
AB0F29A514BE7213009ABC6F /* Icon_Speaker_420x420.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_Speaker_420x420.png; path = images/Icon_Speaker_420x420.png; sourceTree = "<group>"; };
AB1B9E5F1501A78000464647 /* coreaudiosound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coreaudiosound.cpp; sourceTree = SOURCE_ROOT; };
AB1B9E601501A78000464647 /* ringbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ringbuffer.cpp; sourceTree = SOURCE_ROOT; };
AB1B9E611501A78000464647 /* coreaudiosound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coreaudiosound.h; sourceTree = SOURCE_ROOT; };
AB1B9E621501A78000464647 /* ringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ringbuffer.h; sourceTree = SOURCE_ROOT; };
AB1B9E5F1501A78000464647 /* coreaudiosound.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coreaudiosound.cpp; sourceTree = "<group>"; };
AB1B9E601501A78000464647 /* ringbuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ringbuffer.cpp; sourceTree = "<group>"; };
AB1B9E611501A78000464647 /* coreaudiosound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coreaudiosound.h; sourceTree = "<group>"; };
AB1B9E621501A78000464647 /* ringbuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ringbuffer.h; sourceTree = "<group>"; };
AB23567216C2F6F400DA782E /* macosx_10_5_compat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = macosx_10_5_compat.cpp; sourceTree = "<group>"; };
AB29B32F16D4BEBF000EF671 /* InputManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputManager.h; sourceTree = "<group>"; };
AB29B33016D4BEBF000EF671 /* InputManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = InputManager.mm; sourceTree = "<group>"; };
@ -787,6 +790,8 @@
AB80E050142BC4FA00A52038 /* cocoa_util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_util.h; sourceTree = "<group>"; };
AB817A34143EE2DB00A7DFE9 /* videofilter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = videofilter.h; sourceTree = "<group>"; };
AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = videofilter.cpp; sourceTree = "<group>"; };
AB82445A1704AE9A00B8EE20 /* utilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utilities.c; sourceTree = "<group>"; };
AB82445E1704AEC400B8EE20 /* utilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utilities.h; sourceTree = "<group>"; };
AB8967D716D2ED0700F826F1 /* DisplayWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisplayWindowController.h; sourceTree = "<group>"; };
AB8967D816D2ED0700F826F1 /* DisplayWindowController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DisplayWindowController.mm; sourceTree = "<group>"; };
AB8967DC16D2ED2700F826F1 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = translations/English.lproj/DisplayWindow.xib; sourceTree = "<group>"; };
@ -1105,6 +1110,7 @@
children = (
ABB3C63A1501BB8300E0C22E /* openemu */,
AB3ACB6514C2361100D7D192 /* userinterface */,
AB82445A1704AE9A00B8EE20 /* utilities.c */,
AB1B9E5F1501A78000464647 /* coreaudiosound.cpp */,
AB23567216C2F6F400DA782E /* macosx_10_5_compat.cpp */,
AB1B9E601501A78000464647 /* ringbuffer.cpp */,
@ -1124,6 +1130,7 @@
AB1B9E611501A78000464647 /* coreaudiosound.h */,
AB1B9E621501A78000464647 /* ringbuffer.h */,
ABD104011346652500AF11D1 /* sndOSX.h */,
AB82445E1704AEC400B8EE20 /* utilities.h */,
ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */,
ABD104121346652500AF11D1 /* cocoa_core.mm */,
AB58F32C1364F44B0074C376 /* cocoa_file.mm */,
@ -2239,6 +2246,7 @@
AB3A656216CC5438001F5D4A /* cocoa_GPU.mm in Sources */,
AB8967DA16D2ED0700F826F1 /* DisplayWindowController.mm in Sources */,
AB29B33216D4BEBF000EF671 /* InputManager.mm in Sources */,
AB82445C1704AE9A00B8EE20 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2396,6 +2404,7 @@
AB3A656116CC5438001F5D4A /* cocoa_GPU.mm in Sources */,
AB8967D916D2ED0700F826F1 /* DisplayWindowController.mm in Sources */,
AB29B33116D4BEBF000EF671 /* InputManager.mm in Sources */,
AB82445B1704AE9A00B8EE20 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2541,6 +2550,7 @@
AB405695169F5DCC0016AC3E /* x86util.cpp in Sources */,
AB68A0DD16B139BC00DE0546 /* OGLRender_3_2.cpp in Sources */,
AB3A656316CC5438001F5D4A /* cocoa_GPU.mm in Sources */,
AB82445D1704AE9A00B8EE20 /* utilities.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -17,7 +17,7 @@
#import "cocoa_GPU.h"
#import "cocoa_globals.h"
#import "cocoa_util.h"
#include "utilities.h"
#include "../NDSSystem.h"
#include "../GPU.h"
@ -717,7 +717,7 @@ bool CreateOpenGLRenderer()
#ifdef MAC_OS_X_VERSION_10_7
// If we can support a 3.2 Core Profile context, then request that in our
// pixel format attributes.
useContext_3_2 = [CocoaDSUtil OSVersionCheckMajor:10 minor:7 revision:0] ? true : false;
useContext_3_2 = IsOSXVersionSupported(10, 7, 0);
if (useContext_3_2)
{
attrs[9] = kCGLPFAOpenGLProfile;
@ -789,16 +789,11 @@ void RequestOpenGLRenderer_3_2(bool request_3_2)
{
OGLLoadEntryPoints_3_2_Func = &OGLLoadEntryPoints_3_2;
OGLCreateRenderer_3_2_Func = &OGLCreateRenderer_3_2;
return;
}
else
{
OGLLoadEntryPoints_3_2_Func = NULL;
OGLCreateRenderer_3_2_Func = NULL;
}
#else
OGLLoadEntryPoints_3_2_Func = NULL;
OGLCreateRenderer_3_2_Func = NULL;
#endif
OGLLoadEntryPoints_3_2_Func = NULL;
OGLCreateRenderer_3_2_Func = NULL;
}
void SetOpenGLRendererFunctions(bool (*initFunction)(),

View File

@ -17,6 +17,7 @@
*/
#import <Foundation/Foundation.h>
#include "utilities.h"
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
#include "macosx_10_4_compat.h"
@ -48,7 +49,6 @@
+ (NSString *) operatingSystemString;
+ (NSString *) modelIdentifierString;
+ (BOOL) OSVersionCheckMajor:(NSUInteger)checkMajor minor:(NSUInteger)checkMinor revision:(NSUInteger)checkRevision;
@end
@ -88,21 +88,3 @@
- (void)postNotificationOnMainThreadName:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;
@end
#ifdef __cplusplus
extern "C"
{
#endif
uint32_t RGB555ToRGBA8888(const uint16_t color16);
uint32_t RGBA8888ForceOpaque(const uint32_t color32);
void RGB555ToRGBA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels);
void RGBA8888ForceOpaqueBuffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels);
NSSize GetTransformedBounds(NSSize normalBounds, double scalar, double angleDegrees);
double GetMaxScalarInBounds(double normalBoundsWidth, double normalBoundsHeight, double keepInBoundsWidth, double keepInBoundsHeight);
NSPoint GetNormalPointFromTransformedPoint(NSPoint transformedPt, NSSize normalBounds, NSSize transformBounds, double scalar, double angleDegrees);
uint32_t GetNearestPositivePOT(uint32_t value);
#ifdef __cplusplus
}
#endif

View File

@ -21,7 +21,6 @@
#import "types.h"
#import <Cocoa/Cocoa.h>
#include <Accelerate/Accelerate.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include "../version.h"
@ -217,29 +216,6 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain];
return modelIdentifierStr;
}
+ (BOOL) OSVersionCheckMajor:(NSUInteger)checkMajor minor:(NSUInteger)checkMinor revision:(NSUInteger)checkRevision
{
BOOL result = NO;
NSDictionary *systemDict = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
NSString *versionString = (NSString *)[systemDict objectForKey:@"ProductVersion"];
const char *versionCString = [versionString cStringUsingEncoding:NSUTF8StringEncoding];
unsigned int OSMajor = 0;
unsigned int OSMinor = 0;
unsigned int OSRevision = 0;
sscanf(versionCString, "%u.%u.%u", &OSMajor, &OSMinor, &OSRevision);
if ((OSMajor > checkMajor) ||
(OSMajor >= checkMajor && OSMinor > checkMinor) ||
(OSMajor >= checkMajor && OSMinor >= checkMinor && OSRevision >= checkRevision) )
{
result = YES;
}
return result;
}
@end
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4
@ -364,380 +340,3 @@ static NSDate *distantFutureDate = [[NSDate distantFuture] retain];
}
@end
/********************************************************************************************
RGB555ToRGBA8888() - INLINE
Converts a color from 15-bit RGB555 format into 32-bit RGBA8888 format.
Takes:
color16 - The pixel in 15-bit RGB555 format.
Returns:
A 32-bit unsigned integer containing the RGBA8888 formatted color.
Details:
The input and output pixels are expected to have little-endian byte order.
********************************************************************************************/
FORCEINLINE uint32_t RGB555ToRGBA8888(const uint16_t color16)
{
return ((color16 & 0x001F) << 3) |
((color16 & 0x03E0) << 6) |
((color16 & 0x7C00) << 9) |
0xFF000000;
}
/********************************************************************************************
RGBA8888ForceOpaque() - INLINE
Forces the alpha channel of a 32-bit RGBA8888 color to a value of 0xFF.
Takes:
color32 - The pixel in 32-bit RGBA8888 format.
Returns:
A 32-bit unsigned integer containing the RGBA8888 formatted color.
Details:
The input and output pixels are expected to have little-endian byte order.
********************************************************************************************/
FORCEINLINE uint32_t RGBA8888ForceOpaque(const uint32_t color32)
{
return color32 | 0xFF000000;
}
/********************************************************************************************
RGB555ToRGBA8888Buffer()
Copies a 15-bit RGB555 pixel buffer into a 32-bit RGBA8888 pixel buffer.
Takes:
srcBuffer - Pointer to the source 15-bit RGB555 pixel buffer.
destBuffer - Pointer to the destination 32-bit RGBA8888 pixel buffer.
numberPixels - The number of pixels to copy.
Returns:
Nothing.
Details:
The source and destination pixels are expected to have little-endian byte order.
Also, it is the caller's responsibility to ensure that the source and destination
buffers are large enough to accomodate the requested number of pixels.
********************************************************************************************/
void RGB555ToRGBA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels)
{
const uint32_t *__restrict__ destBufferEnd = destBuffer + numberPixels;
while (destBuffer < destBufferEnd)
{
*destBuffer++ = RGB555ToRGBA8888(*srcBuffer++);
}
}
/********************************************************************************************
RGBA8888ForceOpaqueBuffer()
Copies a 32-bit RGBA8888 pixel buffer into another 32-bit RGBA8888 pixel buffer.
The pixels in the destination buffer will have an alpha value of 0xFF.
Takes:
srcBuffer - Pointer to the source 32-bit RGBA8888 pixel buffer.
destBuffer - Pointer to the destination 32-bit RGBA8888 pixel buffer.
numberPixels - The number of pixels to copy.
Returns:
Nothing.
Details:
The source and destination pixels are expected to have little-endian byte order.
Also, it is the caller's responsibility to ensure that the source and destination
buffers are large enough to accomodate the requested number of pixels.
********************************************************************************************/
void RGBA8888ForceOpaqueBuffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels)
{
const uint32_t *__restrict__ destBufferEnd = destBuffer + numberPixels;
while (destBuffer < destBufferEnd)
{
*destBuffer++ = RGBA8888ForceOpaque(*srcBuffer++);
}
}
/********************************************************************************************
GetTransformedBounds()
Returns the bounds of a normalized 2D surface using affine transformations.
Takes:
normalBounds - The rectangular bounds of the normal 2D surface.
scalar - The scalar used to transform the 2D surface.
angleDegrees - The rotation angle, in degrees, to transform the 2D surface.
Returns:
The bounds of a normalized 2D surface using affine transformations.
Details:
The returned bounds is always a normal rectangle. Ignoring the scaling, the
returned bounds will always be at its smallest when the angle is at 0, 90, 180,
or 270 degrees, and largest when the angle is at 45, 135, 225, or 315 degrees.
********************************************************************************************/
NSSize GetTransformedBounds(NSSize normalBounds, double scalar, double angleDegrees)
{
const double angleRadians = angleDegrees * (M_PI/180.0);
// The points are as follows:
//
// (x[3], y[3]) (x[2], y[2])
//
//
//
// (x[0], y[0]) (x[1], y[1])
// Do our scale and rotate transformations.
#ifdef __ACCELERATE__
// Note that although we only need to calculate 3 points, we include 4 points
// here because Accelerate prefers 16-byte alignment.
double x[] = {0.0, normalBounds.width, normalBounds.width, 0.0};
double y[] = {0.0, 0.0, normalBounds.height, normalBounds.height};
cblas_drot(4, x, 1, y, 1, scalar * cos(angleRadians), scalar * sin(angleRadians));
#else // Keep a C-version of this transformation for reference purposes.
const double w = scalar * normalBounds.width;
const double h = scalar * normalBounds.height;
const double d = hypot(w, h);
const double dAngle = atan2(h, w);
const double px = w * cos(angleRadians);
const double py = w * sin(angleRadians);
const double qx = d * cos(dAngle + angleRadians);
const double qy = d * sin(dAngle + angleRadians);
const double rx = h * cos((M_PI/2.0) + angleRadians);
const double ry = h * sin((M_PI/2.0) + angleRadians);
const double x[] = {0.0, px, qx, rx};
const double y[] = {0.0, py, qy, ry};
#endif
// Determine the transformed width, which is dependent on the location of
// the x-coordinate of point (x[2], y[2]).
NSSize transformBounds = {0.0, 0.0};
if (x[2] > 0.0)
{
if (x[2] < x[3])
{
transformBounds.width = x[3] - x[1];
}
else if (x[2] < x[1])
{
transformBounds.width = x[1] - x[3];
}
else
{
transformBounds.width = x[2];
}
}
else if (x[2] < 0.0)
{
if (x[2] > x[3])
{
transformBounds.width = -(x[3] - x[1]);
}
else if (x[2] > x[1])
{
transformBounds.width = -(x[1] - x[3]);
}
else
{
transformBounds.width = -x[2];
}
}
else
{
transformBounds.width = abs(x[1] - x[3]);
}
// Determine the transformed height, which is dependent on the location of
// the y-coordinate of point (x[2], y[2]).
if (y[2] > 0.0)
{
if (y[2] < y[3])
{
transformBounds.height = y[3] - y[1];
}
else if (y[2] < y[1])
{
transformBounds.height = y[1] - y[3];
}
else
{
transformBounds.height = y[2];
}
}
else if (y[2] < 0.0)
{
if (y[2] > y[3])
{
transformBounds.height = -(y[3] - y[1]);
}
else if (y[2] > y[1])
{
transformBounds.height = -(y[1] - y[3]);
}
else
{
transformBounds.height = -y[2];
}
}
else
{
transformBounds.height = abs(y[3] - y[1]);
}
return transformBounds;
}
/********************************************************************************************
GetMaxScalarInBounds()
Returns the maximum scalar that a rectangle can grow, while maintaining its aspect
ratio, within a boundary.
Takes:
normalBoundsWidth - The rectangular width of the normal 2D surface.
normalBoundsHeight - The rectangular height of the normal 2D surface.
keepInBoundsWidth - The rectangular width of the keep in 2D surface.
keepInBoundsHeight - The rectangular height of the keep in 2D surface.
Returns:
The maximum scalar that a rectangle can grow, while maintaining its aspect ratio,
within a boundary.
Details:
If keepInBoundsWidth or keepInBoundsHeight are less than or equal to zero, the
returned scalar will be zero.
********************************************************************************************/
double GetMaxScalarInBounds(double normalBoundsWidth, double normalBoundsHeight, double keepInBoundsWidth, double keepInBoundsHeight)
{
const double maxX = (normalBoundsWidth <= 0.0) ? 0.0 : keepInBoundsWidth / normalBoundsWidth;
const double maxY = (normalBoundsHeight <= 0.0) ? 0.0 : keepInBoundsHeight / normalBoundsHeight;
return (maxX <= maxY) ? maxX : maxY;
}
/********************************************************************************************
GetNormalPointFromTransformedPoint()
Returns a normalized point from a point from a 2D transformed surface.
Takes:
transformedPt - A point as it exists on a 2D transformed surface.
normalBounds - The rectangular bounds of the normal 2D surface.
transformedBounds - The rectangular bounds of the transformed 2D surface.
scalar - The scalar used on the transformed 2D surface.
angleDegrees - The rotation angle, in degrees, of the transformed 2D surface.
Returns:
A normalized point from a point from a 2D transformed surface.
Details:
It may help to call GetTransformedBounds() for the transformBounds parameter.
********************************************************************************************/
NSPoint GetNormalPointFromTransformedPoint(NSPoint transformedPt, NSSize normalBounds, NSSize transformBounds, double scalar, double angleDegrees)
{
const double angleRadians = angleDegrees * (M_PI/180.0);
// Get the coordinates of the transformed point and translate the coordinate
// system so that the origin becomes the center.
const double transformedX = transformedPt.x - (transformBounds.width / 2.0);
const double transformedY = transformedPt.y - (transformBounds.height / 2.0);
// Perform rect-polar conversion.
// Get the radius r with respect to the origin.
const double r = hypot(transformedX, transformedY);
// Get the angle theta with respect to the origin.
double theta = 0.0;
if (transformedX == 0.0)
{
if (transformedY > 0.0)
{
theta = M_PI / 2.0;
}
else if (transformedY < 0.0)
{
theta = M_PI * 1.5;
}
}
else if (transformedX < 0.0)
{
theta = M_PI - atan2(transformedY, -transformedX);
}
else if (transformedY < 0.0)
{
theta = atan2(transformedY, transformedX) + (M_PI * 2.0);
}
else
{
theta = atan2(transformedY, transformedX);
}
// Get the normalized angle and use it to rotate about the origin.
// Then do polar-rect conversion and translate back to transformed coordinates
// with a 0 degree rotation.
const double normalizedAngle = theta - angleRadians;
const double normalizedX = (r * cos(normalizedAngle)) + (normalBounds.width * scalar / 2.0);
const double normalizedY = (r * sin(normalizedAngle)) + (normalBounds.height * scalar / 2.0);
// Scale the location to get a one-to-one correlation to normal coordinates.
const NSPoint normalizedPt = { (CGFloat)(normalizedX / scalar), (CGFloat)(normalizedY / scalar) };
return normalizedPt;
}
/********************************************************************************************
GetNearestPositivePOT()
Returns the next highest power of two of a 32-bit integer value.
Takes:
value - A 32-bit integer value.
Returns:
A 32-bit integer with the next highest power of two compared to the input value.
Details:
If the input value is already a power of two, this function returns the same
value.
********************************************************************************************/
uint32_t GetNearestPositivePOT(uint32_t value)
{
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value++;
return value;
}

View File

@ -17,8 +17,8 @@
*/
#import "cocoa_videofilter.h"
#import "cocoa_util.h"
#import <Cocoa/Cocoa.h>
#include "utilities.h"
@implementation CocoaVideoFilter

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -17,8 +17,10 @@
#include "coreaudiosound.h"
#include "cocoa_globals.h"
#include "utilities.h"
CoreAudioSound::CoreAudioSound(size_t bufferSamples, size_t sampleSize)
CoreAudioOutput::CoreAudioOutput(size_t bufferSamples, size_t sampleSize)
{
OSStatus error = noErr;
@ -29,28 +31,73 @@ CoreAudioSound::CoreAudioSound(size_t bufferSamples, size_t sampleSize)
_volume = 1.0f;
// Create a new audio unit
ComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if (IsOSXVersionSupported(10, 6, 0))
{
AudioComponentDescription audioDesc;
audioDesc.componentType = kAudioUnitType_Output;
audioDesc.componentSubType = kAudioUnitSubType_DefaultOutput;
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
audioDesc.componentFlags = 0;
audioDesc.componentFlagsMask = 0;
Component comp = FindNextComponent(NULL, &desc);
if (comp == NULL)
AudioComponent audioComponent = AudioComponentFindNext(NULL, &audioDesc);
if (audioComponent == NULL)
{
return;
}
error = OpenAComponent(comp, &_au);
if (error != noErr || comp == NULL)
error = AudioComponentInstanceNew(audioComponent, &_au);
if (error != noErr)
{
return;
}
}
else
{
ComponentDescription audioDesc;
audioDesc.componentType = kAudioUnitType_Output;
audioDesc.componentSubType = kAudioUnitSubType_DefaultOutput;
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
audioDesc.componentFlags = 0;
audioDesc.componentFlagsMask = 0;
Component audioComponent = FindNextComponent(NULL, &audioDesc);
if (audioComponent == NULL)
{
return;
}
error = OpenAComponent(audioComponent, &_au);
if (error != noErr)
{
return;
}
}
#else
ComponentDescription audioDesc;
audioDesc.componentType = kAudioUnitType_Output;
audioDesc.componentSubType = kAudioUnitSubType_DefaultOutput;
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
audioDesc.componentFlags = 0;
audioDesc.componentFlagsMask = 0;
Component audioComponent = FindNextComponent(NULL, &audioDesc);
if (audioComponent == NULL)
{
return;
}
error = OpenAComponent(audioComponent, &_au);
if (error != noErr)
{
return;
}
#endif
// Set the render callback
AURenderCallbackStruct callback;
callback.inputProc = &RenderCallback;
callback.inputProc = &CoreAudioOutputRenderCallback;
callback.inputProcRefCon = _buffer;
error = AudioUnitSetProperty(_au,
@ -66,22 +113,22 @@ CoreAudioSound::CoreAudioSound(size_t bufferSamples, size_t sampleSize)
}
// Set up the audio unit for audio streaming
AudioStreamBasicDescription audio_format;
audio_format.mSampleRate = SPU_SAMPLE_RATE;
audio_format.mFormatID = kAudioFormatLinearPCM;
audio_format.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked;
audio_format.mBytesPerPacket = SPU_SAMPLE_SIZE;
audio_format.mFramesPerPacket = 1;
audio_format.mBytesPerFrame = SPU_SAMPLE_SIZE;
audio_format.mChannelsPerFrame = SPU_NUMBER_CHANNELS;
audio_format.mBitsPerChannel = SPU_SAMPLE_RESOLUTION;
AudioStreamBasicDescription outputFormat;
outputFormat.mSampleRate = SPU_SAMPLE_RATE;
outputFormat.mFormatID = kAudioFormatLinearPCM;
outputFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kLinearPCMFormatFlagIsPacked;
outputFormat.mBytesPerPacket = SPU_SAMPLE_SIZE;
outputFormat.mFramesPerPacket = 1;
outputFormat.mBytesPerFrame = SPU_SAMPLE_SIZE;
outputFormat.mChannelsPerFrame = SPU_NUMBER_CHANNELS;
outputFormat.mBitsPerChannel = SPU_SAMPLE_RESOLUTION;
error = AudioUnitSetProperty(_au,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&audio_format,
sizeof(audio_format) );
&outputFormat,
sizeof(outputFormat) );
if(error != noErr)
{
@ -96,7 +143,7 @@ CoreAudioSound::CoreAudioSound(size_t bufferSamples, size_t sampleSize)
}
}
CoreAudioSound::~CoreAudioSound()
CoreAudioOutput::~CoreAudioOutput()
{
OSSpinLockLock(_spinlockAU);
@ -104,6 +151,18 @@ CoreAudioSound::~CoreAudioSound()
{
AudioOutputUnitStop(_au);
AudioUnitUninitialize(_au);
#if defined(MAC_OS_X_VERSION_10_6) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
if (IsOSXVersionSupported(10, 6, 0))
{
AudioComponentInstanceDispose(_au);
}
else
{
CloseComponent(_au);
}
#else
CloseComponent(_au);
#endif
_au = NULL;
}
@ -116,12 +175,12 @@ CoreAudioSound::~CoreAudioSound()
_spinlockAU = NULL;
}
RingBuffer* CoreAudioSound::getBuffer()
RingBuffer* CoreAudioOutput::getBuffer() const
{
return this->_buffer;
}
void CoreAudioSound::start()
void CoreAudioOutput::start()
{
this->clearBuffer();
@ -131,7 +190,7 @@ void CoreAudioSound::start()
OSSpinLockUnlock(this->_spinlockAU);
}
void CoreAudioSound::stop()
void CoreAudioOutput::stop()
{
OSSpinLockLock(this->_spinlockAU);
AudioOutputUnitStop(this->_au);
@ -140,41 +199,41 @@ void CoreAudioSound::stop()
this->clearBuffer();
}
void CoreAudioSound::writeToBuffer(const void *buffer, size_t numberBytes)
void CoreAudioOutput::writeToBuffer(const void *buffer, size_t numberBytes)
{
this->getBuffer()->write(buffer, numberBytes);
}
void CoreAudioSound::clearBuffer()
void CoreAudioOutput::clearBuffer()
{
this->_buffer->clear();
}
void CoreAudioSound::mute()
void CoreAudioOutput::mute()
{
OSSpinLockLock(this->_spinlockAU);
AudioUnitSetParameter(this->_au, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, 0.0f, 0);
OSSpinLockUnlock(this->_spinlockAU);
}
void CoreAudioSound::unmute()
void CoreAudioOutput::unmute()
{
OSSpinLockLock(this->_spinlockAU);
AudioUnitSetParameter(this->_au, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, this->_volume, 0);
OSSpinLockUnlock(this->_spinlockAU);
}
size_t CoreAudioSound::getAvailableSamples()
size_t CoreAudioOutput::getAvailableSamples() const
{
return this->_buffer->getAvailableElements();
}
float CoreAudioSound::getVolume()
float CoreAudioOutput::getVolume() const
{
return this->_volume;
}
void CoreAudioSound::setVolume(float vol)
void CoreAudioOutput::setVolume(float vol)
{
this->_volume = vol;
@ -183,7 +242,7 @@ void CoreAudioSound::setVolume(float vol)
OSSpinLockUnlock(this->_spinlockAU);
}
OSStatus RenderCallback(void *inRefCon,
OSStatus CoreAudioOutputRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -24,7 +24,7 @@
#include <libkern/OSAtomic.h>
#include "ringbuffer.h"
class CoreAudioSound
class CoreAudioOutput
{
private:
AudioUnit _au;
@ -33,22 +33,22 @@ private:
float _volume;
public:
CoreAudioSound(size_t bufferSamples, size_t sampleSize);
~CoreAudioSound();
CoreAudioOutput(size_t bufferSamples, size_t sampleSize);
~CoreAudioOutput();
void start();
void stop();
void writeToBuffer(const void *buffer, size_t numberBytes);
void clearBuffer();
size_t getAvailableSamples();
RingBuffer* getBuffer();
size_t getAvailableSamples() const;
RingBuffer* getBuffer() const;
void mute();
void unmute();
float getVolume();
float getVolume() const;
void setVolume(float vol);
};
OSStatus RenderCallback(void *inRefCon,
OSStatus CoreAudioOutputRenderCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,

View File

@ -130,7 +130,7 @@ bool OSXOpenGLRendererInit()
timer_based = ([NSObject instancesRespondToSelector:@selector(performSelector:onThread:withObject:waitUntilDone:)]==NO)?true:false;
#ifdef HAVE_JIT
CommonSettings.use_jit = true;
CommonSettings.use_jit = false;
#endif
//Firmware setup

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -21,7 +21,7 @@
#include <libkern/OSAtomic.h>
RingBuffer::RingBuffer(size_t numberElements, size_t newBufferElementSize)
RingBuffer::RingBuffer(const size_t numberElements, const size_t newBufferElementSize)
{
_buffer = (uint8_t *)calloc(numberElements + 1, newBufferElementSize);
_bufferSize = (numberElements + 1) * newBufferElementSize;
@ -176,17 +176,17 @@ size_t RingBuffer::write(const void *__restrict__ srcBuffer, size_t requestedNum
return requestedNumberBytes;
}
size_t RingBuffer::getBufferFillSize()
size_t RingBuffer::getBufferFillSize() const
{
return (size_t)this->_bufferFillSize;
}
size_t RingBuffer::getAvailableElements()
size_t RingBuffer::getAvailableElements() const
{
return ((this->_bufferSize - this->_bufferFillSize) / this->_elementSize) - 1;
}
size_t RingBuffer::getElementSize()
size_t RingBuffer::getElementSize() const
{
return this->_elementSize;
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -35,15 +35,15 @@ private:
size_t _writePosition;
public:
RingBuffer(size_t numberElements, size_t newBufferElementSize);
RingBuffer(const size_t numberElements, const size_t newBufferElementSize);
~RingBuffer();
void clear();
size_t read(void *__restrict__ destBuffer, size_t requestedNumberBytes);
size_t write(const void *__restrict__ srcBuffer, size_t requestedNumberBytes);
size_t getBufferFillSize();
size_t getAvailableElements();
size_t getElementSize();
size_t getBufferFillSize() const;
size_t getAvailableElements() const;
size_t getElementSize() const;
};
#endif

View File

@ -135,7 +135,7 @@
}
UInt32 *bitmapData = (UInt32 *)[imageRep bitmapData];
RGBA5551ToRGBA8888Buffer((const uint16_t *)color_data, (uint32_t *)bitmapData, (w * h));
RGB555ToRGBA8888Buffer((const uint16_t *)color_data, (uint32_t *)bitmapData, (w * h));
#ifdef __BIG_ENDIAN__
UInt32 *bitmapDataEnd = bitmapData + (w * h);

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2007 Jeff Bland
Copyright (C) 2007-2012 DeSmuME team
Copyright (C) 2007-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -23,7 +23,7 @@
// Global sound playback manager
static CoreAudioSound *coreAudioPlaybackManager = NULL;
static CoreAudioOutput *coreAudioPlaybackManager = NULL;
static pthread_mutex_t *mutexAudioSampleReadWrite = NULL;
pthread_mutex_t *mutexAudioEmulateCore = NULL;
@ -51,16 +51,9 @@ SoundInterface_struct *SNDCoreList[] = {
int SNDOSXInit(int buffer_size)
{
if (coreAudioPlaybackManager != NULL)
{
CoreAudioSound *oldcoreAudioPlaybackManager = coreAudioPlaybackManager;
coreAudioPlaybackManager = new CoreAudioSound(buffer_size / SPU_SAMPLE_SIZE, SPU_SAMPLE_SIZE);
CoreAudioOutput *oldcoreAudioPlaybackManager = coreAudioPlaybackManager;
coreAudioPlaybackManager = new CoreAudioOutput(buffer_size / SPU_SAMPLE_SIZE, SPU_SAMPLE_SIZE);
delete oldcoreAudioPlaybackManager;
}
else
{
coreAudioPlaybackManager = new CoreAudioSound(buffer_size / SPU_SAMPLE_SIZE, SPU_SAMPLE_SIZE);
}
if (mutexAudioSampleReadWrite == NULL)
{
@ -95,44 +88,51 @@ int SNDOSXReset()
void SNDOSXUpdateAudio(s16 *buffer, u32 num_samples)
{
if (coreAudioPlaybackManager != NULL)
if (coreAudioPlaybackManager == NULL)
{
coreAudioPlaybackManager->writeToBuffer(buffer, coreAudioPlaybackManager->getBuffer()->getElementSize() * (size_t)num_samples);
return;
}
coreAudioPlaybackManager->writeToBuffer(buffer, coreAudioPlaybackManager->getBuffer()->getElementSize() * (size_t)num_samples);
}
u32 SNDOSXGetAudioSpace()
{
u32 availableSamples = 0;
if (coreAudioPlaybackManager != NULL)
if (coreAudioPlaybackManager == NULL)
{
availableSamples = (u32)coreAudioPlaybackManager->getAvailableSamples();
return 0;
}
return availableSamples;
return (u32)coreAudioPlaybackManager->getAvailableSamples();
}
void SNDOSXMuteAudio()
{
if (coreAudioPlaybackManager != NULL)
if (coreAudioPlaybackManager == NULL)
{
coreAudioPlaybackManager->mute();
return;
}
coreAudioPlaybackManager->mute();
}
void SNDOSXUnMuteAudio()
{
if (coreAudioPlaybackManager != NULL)
if (coreAudioPlaybackManager == NULL)
{
coreAudioPlaybackManager->unmute();
return;
}
coreAudioPlaybackManager->unmute();
}
void SNDOSXSetVolume(int volume)
{
if (coreAudioPlaybackManager != NULL)
if (coreAudioPlaybackManager == NULL)
{
return;
}
float newVolumeScalar = (float)volume / 100.0f;
if(volume > 100)
@ -146,14 +146,15 @@ void SNDOSXSetVolume(int volume)
coreAudioPlaybackManager->setVolume(newVolumeScalar);
}
}
void SNDOSXClearBuffer()
{
if (coreAudioPlaybackManager != NULL)
if (coreAudioPlaybackManager == NULL)
{
coreAudioPlaybackManager->clearBuffer();
return;
}
coreAudioPlaybackManager->clearBuffer();
}
void SNDOSXFetchSamples(s16 *sampleBuffer, size_t sampleCount, ESynchMode synchMode, ISynchronizingAudioBuffer *theSynchronizer)

View File

@ -146,7 +146,7 @@
- (void) setupUserDefaults;
- (double) resizeWithTransform:(NSSize)normalBounds scalar:(double)scalar rotation:(double)angleDegrees;
- (double) maxContentScalar:(NSSize)contentBounds;
- (double) maxScalarForContentBoundsWidth:(double)contentBoundsWidth height:(double)contentBoundsHeight;
- (IBAction) copy:(id)sender;
- (IBAction) changeVolume:(id)sender;

View File

@ -210,9 +210,9 @@ enum OGLVertexAttributeID
NSWindow *theWindow = [self window];
// Set the minimum content size for the window, since this will change based on rotation.
NSSize minContentSize = GetTransformedBounds(_minDisplayViewSize, 1.0, CLOCKWISE_DEGREES(newAngleDegrees));
CGSize minContentSize = GetTransformedBounds(_minDisplayViewSize.width, _minDisplayViewSize.height, 1.0, CLOCKWISE_DEGREES(newAngleDegrees));
minContentSize.height += _statusBarHeight;
[theWindow setContentMinSize:minContentSize];
[theWindow setContentMinSize:NSMakeSize(minContentSize.width, minContentSize.height)];
// Resize the window.
const NSSize oldBounds = [theWindow frame].size;
@ -457,9 +457,9 @@ enum OGLVertexAttributeID
}
// Set the minimum content size, keeping the display rotation in mind.
NSSize transformedMinSize = GetTransformedBounds(_minDisplayViewSize, 1.0, CLOCKWISE_DEGREES([self displayRotation]));
CGSize transformedMinSize = GetTransformedBounds(_minDisplayViewSize.width, _minDisplayViewSize.height, 1.0, CLOCKWISE_DEGREES([self displayRotation]));
transformedMinSize.height += _statusBarHeight;
[[self window] setContentMinSize:transformedMinSize];
[[self window] setContentMinSize:NSMakeSize(transformedMinSize.width, transformedMinSize.height)];
}
- (BOOL) isMinSizeNormal
@ -534,15 +534,15 @@ enum OGLVertexAttributeID
angleDegrees = CLOCKWISE_DEGREES(angleDegrees);
// Get the maximum scalar size within drawBounds. Constrain scalar to maxScalar if necessary.
const NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, angleDegrees);
const double maxScalar = [self maxContentScalar:checkSize];
const CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, angleDegrees);
const double maxScalar = [self maxScalarForContentBoundsWidth:checkSize.width height:checkSize.height];
if (scalar > maxScalar)
{
scalar = maxScalar;
}
// Get the new bounds for the window's content view based on the transformed draw bounds.
const NSSize transformedBounds = GetTransformedBounds(normalBounds, scalar, angleDegrees);
const CGSize transformedBounds = GetTransformedBounds(normalBounds.width, normalBounds.height, scalar, angleDegrees);
// Get the center of the content view in screen coordinates.
const NSRect windowContentRect = [[theWindow contentView] bounds];
@ -558,15 +558,15 @@ enum OGLVertexAttributeID
return scalar;
}
- (double) maxContentScalar:(NSSize)contentBounds
- (double) maxScalarForContentBoundsWidth:(double)contentBoundsWidth height:(double)contentBoundsHeight
{
// Determine the maximum scale based on the visible screen size (which
// doesn't include the menu bar or dock).
const NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
const NSRect windowFrame = [[self window] frameRectForContentRect:NSMakeRect(0.0, 0.0, contentBounds.width, contentBounds.height + _statusBarHeight)];
const NSSize visibleScreenBounds = { (screenFrame.size.width - (windowFrame.size.width - contentBounds.width)), (screenFrame.size.height - (windowFrame.size.height - contentBounds.height)) };
const NSRect windowFrame = [[self window] frameRectForContentRect:NSMakeRect(0.0, 0.0, contentBoundsWidth, contentBoundsHeight + _statusBarHeight)];
const NSSize visibleScreenBounds = { (screenFrame.size.width - (windowFrame.size.width - contentBoundsWidth)), (screenFrame.size.height - (windowFrame.size.height - contentBoundsHeight)) };
return GetMaxScalarInBounds(contentBounds.width, contentBounds.height, visibleScreenBounds.width, visibleScreenBounds.height);
return GetMaxScalarInBounds(contentBoundsWidth, contentBoundsHeight, visibleScreenBounds.width, visibleScreenBounds.height);
}
- (void) saveScreenshotAsFinish:(NSNotification *)aNotification
@ -609,7 +609,7 @@ enum OGLVertexAttributeID
[self setIsMinSizeNormal:YES];
// Set the minimum content size, keeping the display rotation in mind.
NSSize transformedMinSize = GetTransformedBounds(_minDisplayViewSize, 1.0, CLOCKWISE_DEGREES([self displayRotation]));
CGSize transformedMinSize = GetTransformedBounds(_minDisplayViewSize.width, _minDisplayViewSize.height, 1.0, CLOCKWISE_DEGREES([self displayRotation]));
transformedMinSize.height += _statusBarHeight;
// Resize the window if it's smaller than the minimum content size.
@ -618,7 +618,7 @@ enum OGLVertexAttributeID
{
// Prepare to resize.
NSRect oldFrameRect = [theWindow frame];
windowContentRect.size = transformedMinSize;
windowContentRect.size = NSMakeSize(transformedMinSize.width, transformedMinSize.height);
NSRect newFrameRect = [theWindow frameRectForContentRect:windowContentRect];
// Keep the window centered when expanding the size.
@ -714,7 +714,8 @@ enum OGLVertexAttributeID
// Find the maximum scalar we can use for the display view, bounded by the
// content Rect.
const NSSize checkSize = GetTransformedBounds([self normalSize], 1.0, [self displayRotation]);
const NSSize normalBounds = [self normalSize];
const CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, [self displayRotation]);
const NSSize contentBounds = NSMakeSize(contentRect.size.width, contentRect.size.height - _statusBarHeight);
const double maxS = GetMaxScalarInBounds(checkSize.width, checkSize.height, contentBounds.width, contentBounds.height);
@ -729,7 +730,8 @@ enum OGLVertexAttributeID
- (void)windowDidResize:(NSNotification *)notification
{
// Get the max scalar within the window's current content bounds.
const NSSize checkSize = GetTransformedBounds([self normalSize], 1.0, [self displayRotation]);
const NSSize normalBounds = [self normalSize];
const CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, [self displayRotation]);
NSSize contentBounds = [[[self window] contentView] bounds].size;
contentBounds.height -= _statusBarHeight;
const double maxS = GetMaxScalarInBounds(checkSize.width, checkSize.height, contentBounds.width, contentBounds.height);
@ -1265,7 +1267,13 @@ enum OGLVertexAttributeID
viewAngle = CLOCKWISE_DEGREES(viewAngle);
}
NSPoint touchLoc = GetNormalPointFromTransformedPoint(clickLoc, [windowController normalSize], [self bounds].size, [windowController displayScale], viewAngle);
const NSSize normalBounds = [windowController normalSize];
const NSSize transformBounds = [self bounds].size;
CGPoint touchLoc = GetNormalPointFromTransformedPoint(clickLoc.x, clickLoc.y,
normalBounds.width, normalBounds.height,
transformBounds.width, transformBounds.height,
[windowController displayScale],
viewAngle);
// Normalize the touch location to the DS.
if ([windowController displayMode] == DS_DISPLAY_TYPE_COMBO)
@ -1304,7 +1312,7 @@ enum OGLVertexAttributeID
touchLoc.y = (GPU_DISPLAY_HEIGHT - 1);
}
return touchLoc;
return NSMakePoint(touchLoc.x, touchLoc.y);
}
#pragma mark InputHIDManagerTarget Protocol

View File

@ -120,9 +120,9 @@
// Set the minimum content size for the window, since this will change based on rotation.
NSSize drawBounds = minDisplayViewSize;
NSSize minContentSize = GetTransformedBounds(drawBounds, 1.0, CLOCKWISE_DEGREES(newAngleDegrees));
CGSize minContentSize = GetTransformedBounds(drawBounds.width, drawBounds.height, 1.0, CLOCKWISE_DEGREES(newAngleDegrees));
minContentSize.height += statusBarHeight;
[window setContentMinSize:minContentSize];
[window setContentMinSize:NSMakeSize(minContentSize.width, minContentSize.height)];
// Resize the window.
NSSize oldBounds = [window frame].size;
@ -144,15 +144,15 @@
angleDegrees = CLOCKWISE_DEGREES(angleDegrees);
// Get the maximum scalar size within drawBounds. Constrain scalar to maxScalar if necessary.
NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, angleDegrees);
double maxScalar = [self maxContentScalar:checkSize];
CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, angleDegrees);
double maxScalar = [self maxContentScalar:NSMakeSize(checkSize.width, checkSize.height)];
if (scalar > maxScalar)
{
scalar = maxScalar;
}
// Get the new bounds for the window's content view based on the transformed draw bounds.
NSSize transformedBounds = GetTransformedBounds(normalBounds, scalar, angleDegrees);
CGSize transformedBounds = GetTransformedBounds(normalBounds.width, normalBounds.height, scalar, angleDegrees);
// Get the center of the content view in screen coordinates.
NSRect windowContentRect = [[window contentView] bounds];
@ -729,9 +729,9 @@
}
// Set the minimum content size, keeping the display rotation in mind.
NSSize transformedMinSize = GetTransformedBounds(minDisplayViewSize, 1.0, CLOCKWISE_DEGREES([displayView rotation]));
CGSize transformedMinSize = GetTransformedBounds(minDisplayViewSize.width, minDisplayViewSize.height, 1.0, CLOCKWISE_DEGREES([displayView rotation]));
transformedMinSize.height += statusBarHeight;
[window setContentMinSize:transformedMinSize];
[window setContentMinSize:NSMakeSize(transformedMinSize.width, transformedMinSize.height)];
// Resize the window if it's smaller than the minimum content size.
NSRect windowContentRect = [window contentRectForFrameRect:[window frame]];
@ -739,7 +739,7 @@
{
// Prepare to resize.
NSRect oldFrameRect = [window frame];
windowContentRect.size = transformedMinSize;
windowContentRect.size = NSMakeSize(transformedMinSize.width, transformedMinSize.height);
NSRect newFrameRect = [window frameRectForContentRect:windowContentRect];
// Keep the window centered when expanding the size.
@ -975,7 +975,7 @@
double r = [displayView rotation];
// Get the max scalar within the window's current content bounds.
NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, r);
CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, r);
NSSize contentBounds = [[window contentView] bounds].size;
contentBounds.height -= statusBarHeight;
double maxS = GetMaxScalarInBounds(checkSize.width, checkSize.height, contentBounds.width, contentBounds.height);
@ -1002,7 +1002,7 @@
// Find the maximum scalar we can use for the display view, bounded by the
// content Rect.
const NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, [displayView rotation]);
const CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, [displayView rotation]);
const NSSize contentBounds = NSMakeSize(contentRect.size.width, contentRect.size.height - statusBarHeight);
const double maxS = GetMaxScalarInBounds(checkSize.width, checkSize.height, contentBounds.width, contentBounds.height);
[displayView setScale:maxS];

View File

@ -0,0 +1,511 @@
/*
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#include "utilities.h"
#include <Accelerate/Accelerate.h>
static CFStringRef OSXProductName = NULL;
static CFStringRef OSXProductVersion = NULL;
static CFStringRef OSXProductBuildVersion = NULL;
static unsigned int OSXVersionMajor = 0;
static unsigned int OSXVersionMinor = 0;
static unsigned int OSXVersionRevision = 0;
static bool isSystemVersionAlreadyRead = false;
static void ReadSystemVersionPListFile()
{
// Read the SystemVersion.plist file.
CFDataRef resourceData = NULL;
CFURLRef systemPListURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/System/Library/CoreServices/SystemVersion.plist"), kCFURLPOSIXPathStyle, false);
Boolean status = CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, systemPListURL, &resourceData, NULL, NULL, NULL);
if (!status)
{
CFRelease(systemPListURL);
return;
}
CFDictionaryRef systemDict = (CFDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorDefault, resourceData, kCFPropertyListImmutable, NULL);
if (systemDict == NULL)
{
CFRelease(resourceData);
CFRelease(systemPListURL);
return;
}
// Get the system version string.
if (OSXProductVersion != NULL)
{
CFRelease(OSXProductVersion);
}
OSXProductVersion = (CFStringRef)CFDictionaryGetValue(systemDict, CFSTR("ProductVersion"));
if (OSXProductVersion != NULL)
{
// Copy the system version.
CFRetain(OSXProductVersion);
char versionCString[256] = {0};
CFStringGetCString(OSXProductVersion, versionCString, 256, kCFStringEncodingUTF8);
sscanf(versionCString, "%u.%u.%u", &OSXVersionMajor, &OSXVersionMinor, &OSXVersionRevision);
}
if (OSXProductName != NULL)
{
CFRelease(OSXProductName);
}
OSXProductName = (CFStringRef)CFDictionaryGetValue(systemDict, CFSTR("ProductName"));
if (OSXProductName != NULL)
{
CFRetain(OSXProductName);
}
if (OSXProductBuildVersion != NULL)
{
CFRelease(OSXProductBuildVersion);
}
OSXProductBuildVersion = (CFStringRef)CFDictionaryGetValue(systemDict, CFSTR("ProductBuildVersion"));
if (OSXProductBuildVersion != NULL)
{
CFRetain(OSXProductBuildVersion);
}
// Release all resources now that the system version string has been copied.
CFRelease(resourceData);
CFRelease(systemPListURL);
CFRelease(systemDict);
// Mark that we've already read the SystemVersion.plist file so that we don't
// have to do this again.
isSystemVersionAlreadyRead = true;
}
bool IsOSXVersionSupported(const unsigned int major, const unsigned int minor, const unsigned int revision)
{
bool result = false;
if (!isSystemVersionAlreadyRead)
{
ReadSystemVersionPListFile();
}
if (isSystemVersionAlreadyRead &&
((OSXVersionMajor > major) ||
(OSXVersionMajor >= major && OSXVersionMinor > minor) ||
(OSXVersionMajor >= major && OSXVersionMinor >= minor && OSXVersionRevision >= revision)) )
{
result = true;
}
return result;
}
/********************************************************************************************
RGB555ToRGBA8888() - INLINE
Converts a color from 15-bit RGB555 format into 32-bit RGBA8888 format.
Takes:
color16 - The pixel in 15-bit RGB555 format.
Returns:
A 32-bit unsigned integer containing the RGBA8888 formatted color.
Details:
The input and output pixels are expected to have little-endian byte order.
********************************************************************************************/
inline uint32_t RGB555ToRGBA8888(const uint16_t color16)
{
return ((color16 & 0x001F) << 3) |
((color16 & 0x03E0) << 6) |
((color16 & 0x7C00) << 9) |
0xFF000000;
}
/********************************************************************************************
RGBA8888ForceOpaque() - INLINE
Forces the alpha channel of a 32-bit RGBA8888 color to a value of 0xFF.
Takes:
color32 - The pixel in 32-bit RGBA8888 format.
Returns:
A 32-bit unsigned integer containing the RGBA8888 formatted color.
Details:
The input and output pixels are expected to have little-endian byte order.
********************************************************************************************/
inline uint32_t RGBA8888ForceOpaque(const uint32_t color32)
{
return color32 | 0xFF000000;
}
/********************************************************************************************
RGB555ToRGBA8888Buffer()
Copies a 15-bit RGB555 pixel buffer into a 32-bit RGBA8888 pixel buffer.
Takes:
srcBuffer - Pointer to the source 15-bit RGB555 pixel buffer.
destBuffer - Pointer to the destination 32-bit RGBA8888 pixel buffer.
numberPixels - The number of pixels to copy.
Returns:
Nothing.
Details:
The source and destination pixels are expected to have little-endian byte order.
Also, it is the caller's responsibility to ensure that the source and destination
buffers are large enough to accomodate the requested number of pixels.
********************************************************************************************/
void RGB555ToRGBA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels)
{
const uint32_t *__restrict__ destBufferEnd = destBuffer + numberPixels;
while (destBuffer < destBufferEnd)
{
*destBuffer++ = RGB555ToRGBA8888(*srcBuffer++);
}
}
/********************************************************************************************
RGBA8888ForceOpaqueBuffer()
Copies a 32-bit RGBA8888 pixel buffer into another 32-bit RGBA8888 pixel buffer.
The pixels in the destination buffer will have an alpha value of 0xFF.
Takes:
srcBuffer - Pointer to the source 32-bit RGBA8888 pixel buffer.
destBuffer - Pointer to the destination 32-bit RGBA8888 pixel buffer.
numberPixels - The number of pixels to copy.
Returns:
Nothing.
Details:
The source and destination pixels are expected to have little-endian byte order.
Also, it is the caller's responsibility to ensure that the source and destination
buffers are large enough to accomodate the requested number of pixels.
********************************************************************************************/
void RGBA8888ForceOpaqueBuffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels)
{
const uint32_t *__restrict__ destBufferEnd = destBuffer + numberPixels;
while (destBuffer < destBufferEnd)
{
*destBuffer++ = RGBA8888ForceOpaque(*srcBuffer++);
}
}
/********************************************************************************************
GetTransformedBounds()
Returns the bounds of a normalized 2D surface using affine transformations.
Takes:
normalBoundsWidth - The width of the normal 2D surface.
normalBoundsHeight - The height of the normal 2D surface.
scalar - The scalar used to transform the 2D surface.
angleDegrees - The rotation angle, in degrees, to transform the 2D surface.
Returns:
The bounds of a normalized 2D surface using affine transformations.
Details:
The returned bounds is always a normal rectangle. Ignoring the scaling, the
returned bounds will always be at its smallest when the angle is at 0, 90, 180,
or 270 degrees, and largest when the angle is at 45, 135, 225, or 315 degrees.
********************************************************************************************/
CGSize GetTransformedBounds(const double normalBoundsWidth, const double normalBoundsHeight,
const double scalar,
const double angleDegrees)
{
const double angleRadians = angleDegrees * (M_PI/180.0);
// The points are as follows:
//
// (x[3], y[3]) (x[2], y[2])
//
//
//
// (x[0], y[0]) (x[1], y[1])
// Do our scale and rotate transformations.
#ifdef __ACCELERATE__
// Note that although we only need to calculate 3 points, we include 4 points
// here because Accelerate prefers 16-byte alignment.
double x[] = {0.0, normalBoundsWidth, normalBoundsWidth, 0.0};
double y[] = {0.0, 0.0, normalBoundsHeight, normalBoundsHeight};
cblas_drot(4, x, 1, y, 1, scalar * cos(angleRadians), scalar * sin(angleRadians));
#else // Keep a C-version of this transformation for reference purposes.
const double w = scalar * normalBoundsWidth;
const double h = scalar * normalBoundsHeight;
const double d = hypot(w, h);
const double dAngle = atan2(h, w);
const double px = w * cos(angleRadians);
const double py = w * sin(angleRadians);
const double qx = d * cos(dAngle + angleRadians);
const double qy = d * sin(dAngle + angleRadians);
const double rx = h * cos((M_PI/2.0) + angleRadians);
const double ry = h * sin((M_PI/2.0) + angleRadians);
const double x[] = {0.0, px, qx, rx};
const double y[] = {0.0, py, qy, ry};
#endif
// Determine the transformed width, which is dependent on the location of
// the x-coordinate of point (x[2], y[2]).
CGSize transformBounds = {0.0, 0.0};
if (x[2] > 0.0)
{
if (x[2] < x[3])
{
transformBounds.width = x[3] - x[1];
}
else if (x[2] < x[1])
{
transformBounds.width = x[1] - x[3];
}
else
{
transformBounds.width = x[2];
}
}
else if (x[2] < 0.0)
{
if (x[2] > x[3])
{
transformBounds.width = -(x[3] - x[1]);
}
else if (x[2] > x[1])
{
transformBounds.width = -(x[1] - x[3]);
}
else
{
transformBounds.width = -x[2];
}
}
else
{
transformBounds.width = abs(x[1] - x[3]);
}
// Determine the transformed height, which is dependent on the location of
// the y-coordinate of point (x[2], y[2]).
if (y[2] > 0.0)
{
if (y[2] < y[3])
{
transformBounds.height = y[3] - y[1];
}
else if (y[2] < y[1])
{
transformBounds.height = y[1] - y[3];
}
else
{
transformBounds.height = y[2];
}
}
else if (y[2] < 0.0)
{
if (y[2] > y[3])
{
transformBounds.height = -(y[3] - y[1]);
}
else if (y[2] > y[1])
{
transformBounds.height = -(y[1] - y[3]);
}
else
{
transformBounds.height = -y[2];
}
}
else
{
transformBounds.height = abs(y[3] - y[1]);
}
return transformBounds;
}
/********************************************************************************************
GetMaxScalarInBounds()
Returns the maximum scalar that a rectangle can grow, while maintaining its aspect
ratio, within a boundary.
Takes:
normalBoundsWidth - The width of the normal 2D surface.
normalBoundsHeight - The height of the normal 2D surface.
keepInBoundsWidth - The width of the keep-in 2D surface.
keepInBoundsHeight - The height of the keep-in 2D surface.
Returns:
The maximum scalar that a rectangle can grow, while maintaining its aspect ratio,
within a boundary.
Details:
If keepInBoundsWidth or keepInBoundsHeight are less than or equal to zero, the
returned scalar will be zero.
********************************************************************************************/
double GetMaxScalarInBounds(const double normalBoundsWidth, const double normalBoundsHeight,
const double keepInBoundsWidth, const double keepInBoundsHeight)
{
const double maxX = (normalBoundsWidth <= 0.0) ? 0.0 : keepInBoundsWidth / normalBoundsWidth;
const double maxY = (normalBoundsHeight <= 0.0) ? 0.0 : keepInBoundsHeight / normalBoundsHeight;
return (maxX <= maxY) ? maxX : maxY;
}
/********************************************************************************************
GetNormalPointFromTransformedPoint()
Returns a normalized point from a point from a 2D transformed surface.
Takes:
transformedPointX - The X coordinate of a 2D point as it exists on a 2D
transformed surface.
transformedPointY - The Y coordinate of a 2D point as it exists on a 2D
transformed surface.
normalBoundsWidth - The width of the normal 2D surface.
normalBoundsHeight - The height of the normal 2D surface.
transformBoundsWidth - The width of the transformed 2D surface.
transformBoundsHeight - The height of the transformed 2D surface.
scalar - The scalar used on the transformed 2D surface.
angleDegrees - The rotation angle, in degrees, of the transformed 2D surface.
Returns:
A normalized point from a point from a 2D transformed surface.
Details:
It may help to call GetTransformedBounds() for the transformBounds parameter.
********************************************************************************************/
CGPoint GetNormalPointFromTransformedPoint(const double transformedPointX, const double transformedPointY,
const double normalBoundsWidth, const double normalBoundsHeight,
const double transformBoundsWidth, const double transformBoundsHeight,
const double scalar,
const double angleDegrees)
{
// Get the coordinates of the transformed point and translate the coordinate
// system so that the origin becomes the center.
const double transformedX = transformedPointX - (transformBoundsWidth / 2.0);
const double transformedY = transformedPointY - (transformBoundsHeight / 2.0);
// Perform rect-polar conversion.
// Get the radius r with respect to the origin.
const double r = hypot(transformedX, transformedY) / scalar;
// Get the angle theta with respect to the origin.
double theta = 0.0;
if (transformedX == 0.0)
{
if (transformedY > 0.0)
{
theta = M_PI / 2.0;
}
else if (transformedY < 0.0)
{
theta = M_PI * 1.5;
}
}
else if (transformedX < 0.0)
{
theta = M_PI - atan2(transformedY, -transformedX);
}
else if (transformedY < 0.0)
{
theta = atan2(transformedY, transformedX) + (M_PI * 2.0);
}
else
{
theta = atan2(transformedY, transformedX);
}
// Get the normalized angle and use it to rotate about the origin.
// Then do polar-rect conversion and translate back to transformed coordinates
// with a 0 degree rotation.
const double angleRadians = angleDegrees * (M_PI/180.0);
const double normalizedAngle = theta - angleRadians;
const double normalizedX = (r * cos(normalizedAngle)) + (normalBoundsWidth / 2.0);
const double normalizedY = (r * sin(normalizedAngle)) + (normalBoundsHeight / 2.0);
return CGPointMake(normalizedX, normalizedY);
}
/********************************************************************************************
GetNearestPositivePOT()
Returns the next highest power of two of a 32-bit integer value.
Takes:
value - A 32-bit integer value.
Returns:
A 32-bit integer with the next highest power of two compared to the input value.
Details:
If the input value is already a power of two, this function returns the same
value.
********************************************************************************************/
uint32_t GetNearestPositivePOT(uint32_t value)
{
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value++;
return value;
}

View File

@ -0,0 +1,56 @@
/*
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with the this software. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _COCOA_PORT_UTILITIES_
#define _COCOA_PORT_UTILITIES_
#include <ApplicationServices/ApplicationServices.h>
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
bool IsOSXVersionSupported(const unsigned int major, const unsigned int minor, const unsigned int revision);
uint32_t RGB555ToRGBA8888(const uint16_t color16);
uint32_t RGBA8888ForceOpaque(const uint32_t color32);
void RGB555ToRGBA8888Buffer(const uint16_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels);
void RGBA8888ForceOpaqueBuffer(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ destBuffer, unsigned int numberPixels);
CGSize GetTransformedBounds(const double normalBoundsWidth, const double normalBoundsHeight,
const double scalar,
const double angleDegrees);
double GetMaxScalarInBounds(const double normalBoundsWidth, const double normalBoundsHeight,
const double keepInBoundsWidth, const double keepInBoundsHeight);
CGPoint GetNormalPointFromTransformedPoint(const double transformedPointX, const double transformedPointY,
const double normalBoundsWidth, const double normalBoundsHeight,
const double transformBoundsWidth, const double transformBoundsHeight,
const double scalar,
const double angleDegrees);
uint32_t GetNearestPositivePOT(uint32_t value);
#ifdef __cplusplus
}
#endif
#endif // _COCOA_PORT_UTILITIES_