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:
parent
e4d487bf14
commit
2ae5f548f9
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
#endif
|
||||
OGLLoadEntryPoints_3_2_Func = NULL;
|
||||
OGLCreateRenderer_3_2_Func = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetOpenGLRendererFunctions(bool (*initFunction)(),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
*/
|
||||
|
||||
#import "cocoa_videofilter.h"
|
||||
#import "cocoa_util.h"
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include "utilities.h"
|
||||
|
||||
@implementation CocoaVideoFilter
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
AudioComponent audioComponent = AudioComponentFindNext(NULL, &audioDesc);
|
||||
if (audioComponent == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
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 comp = FindNextComponent(NULL, &desc);
|
||||
if (comp == NULL)
|
||||
Component audioComponent = FindNextComponent(NULL, &audioDesc);
|
||||
if (audioComponent == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
error = OpenAComponent(comp, &_au);
|
||||
if (error != noErr || comp == NULL)
|
||||
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,12 +242,12 @@ void CoreAudioSound::setVolume(float vol)
|
|||
OSSpinLockUnlock(this->_spinlockAU);
|
||||
}
|
||||
|
||||
OSStatus RenderCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData)
|
||||
OSStatus CoreAudioOutputRenderCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData)
|
||||
{
|
||||
RingBuffer *__restrict__ audioBuffer = (RingBuffer *)inRefCon;
|
||||
UInt8 *__restrict__ playbackBuffer = (UInt8 *)ioData->mBuffers[0].mData;
|
||||
|
|
|
@ -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,26 +33,26 @@ 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,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData);
|
||||
OSStatus CoreAudioOutputRenderCallback(void *inRefCon,
|
||||
AudioUnitRenderActionFlags *ioActionFlags,
|
||||
const AudioTimeStamp *inTimeStamp,
|
||||
UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames,
|
||||
AudioBufferList *ioData);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
delete oldcoreAudioPlaybackManager;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
||||
if (mutexAudioSampleReadWrite == NULL)
|
||||
{
|
||||
|
@ -95,65 +88,73 @@ 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)
|
||||
{
|
||||
float newVolumeScalar = (float)volume / 100.0f;
|
||||
|
||||
if(volume > 100)
|
||||
{
|
||||
newVolumeScalar = 1.0f;
|
||||
}
|
||||
else if(volume < 0)
|
||||
{
|
||||
newVolumeScalar = 0.0f;
|
||||
}
|
||||
|
||||
coreAudioPlaybackManager->setVolume(newVolumeScalar);
|
||||
return;
|
||||
}
|
||||
|
||||
float newVolumeScalar = (float)volume / 100.0f;
|
||||
|
||||
if(volume > 100)
|
||||
{
|
||||
newVolumeScalar = 1.0f;
|
||||
}
|
||||
else if(volume < 0)
|
||||
{
|
||||
newVolumeScalar = 0.0f;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_
|
Loading…
Reference in New Issue