Cocoa Port:

- New feature: Displays can be individually set to full screen mode or windowed mode. This feature is multiple monitor aware.
This commit is contained in:
rogerman 2013-05-10 06:38:39 +00:00
parent bd55aae699
commit 41f4653ea0
9 changed files with 1109 additions and 2329 deletions

View File

@ -1012,6 +1012,7 @@
ABAD104315ACE7A00000EC47 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB350BA41478AC96007165AC /* IOKit.framework */; };
ABAD104415ACE7A00000EC47 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABC570D4134431DA00E7B0B1 /* OpenGL.framework */; };
ABAD104515ACE7A00000EC47 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0A0D1914AACA9600E83E91 /* libz.dylib */; };
ABB6AD5D173A3F2B00EC2E8D /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABB6AD5C173A3F2B00EC2E8D /* Carbon.framework */; };
ABBCE29715ACB1FF00A2C965 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */; };
ABBCE29815ACB1FF00A2C965 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABBCE29515ACB1FF00A2C965 /* arm_jit.cpp */; };
ABBF04A614B515F300E505A0 /* AppIcon_ROMCheats.icns in Resources */ = {isa = PBXBuildFile; fileRef = ABBF04A414B515F300E505A0 /* AppIcon_ROMCheats.icns */; };
@ -1227,6 +1228,7 @@
ABAAFBE8172122B6005DDDBE /* FileMigrationDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileMigrationDelegate.h; sourceTree = "<group>"; };
ABAAFBE9172122B6005DDDBE /* FileMigrationDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FileMigrationDelegate.mm; sourceTree = "<group>"; };
ABAD104915ACE7A00000EC47 /* DeSmuME (PPC).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DeSmuME (PPC).app"; sourceTree = BUILT_PRODUCTS_DIR; };
ABB6AD5C173A3F2B00EC2E8D /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
ABB97873144E89CC00793FA3 /* Icon_ActionReplay_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_ActionReplay_32x32.png; path = Images/Icon_ActionReplay_32x32.png; sourceTree = "<group>"; };
ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_CodeBreaker_32x32.png; path = Images/Icon_CodeBreaker_32x32.png; sourceTree = "<group>"; };
ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = Icon_DeSmuME_32x32.png; path = Images/Icon_DeSmuME_32x32.png; sourceTree = "<group>"; };
@ -1536,6 +1538,7 @@
AB2A9A731725F00F0062C1A1 /* OpenGL.framework in Frameworks */,
AB2A9A741725F00F0062C1A1 /* libz.dylib in Frameworks */,
AB2A9A751725F00F0062C1A1 /* AudioToolbox.framework in Frameworks */,
ABB6AD5D173A3F2B00EC2E8D /* Carbon.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1654,6 +1657,7 @@
29B97324FDCFA39411CA2CEA /* AppKit.framework */,
AB213E981710D074006DDB0F /* AudioToolbox.framework */,
ABC570D0134431CE00E7B0B1 /* AudioUnit.framework */,
ABB6AD5C173A3F2B00EC2E8D /* Carbon.framework */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
29B97325FDCFA39411CA2CEA /* Foundation.framework */,
AB350BA41478AC96007165AC /* IOKit.framework */,

View File

@ -74,6 +74,7 @@
AB29B33216D4BEBF000EF671 /* InputManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB29B33016D4BEBF000EF671 /* InputManager.mm */; };
AB350BA51478AC96007165AC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB350BA41478AC96007165AC /* IOKit.framework */; };
AB350D3B147A1D93007165AC /* HID_usage_strings.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB350D3A147A1D93007165AC /* HID_usage_strings.plist */; };
AB3701E5173A3FBF006E573E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB74EC891738499C0026C41E /* Carbon.framework */; };
AB3A655E16CC5421001F5D4A /* EmuControllerDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3A655D16CC5421001F5D4A /* EmuControllerDelegate.mm */; };
AB3A655F16CC5421001F5D4A /* EmuControllerDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3A655D16CC5421001F5D4A /* EmuControllerDelegate.mm */; };
AB3A656116CC5438001F5D4A /* cocoa_GPU.mm in Sources */ = {isa = PBXBuildFile; fileRef = AB3A656016CC5438001F5D4A /* cocoa_GPU.mm */; };
@ -187,6 +188,7 @@
AB64987C13ECC73800EE7DD2 /* FileTypeInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = AB64987B13ECC73800EE7DD2 /* FileTypeInfo.plist */; };
AB68A0DD16B139BC00DE0546 /* OGLRender_3_2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */; };
AB6FBEF6139B6258007BB045 /* slot1_retail_nand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB6FBEF5139B6258007BB045 /* slot1_retail_nand.cpp */; };
AB74EC8A1738499C0026C41E /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB74EC891738499C0026C41E /* Carbon.framework */; };
AB75226E14C7BB51009B97B3 /* AppIcon_FirmwareConfig.icns in Resources */ = {isa = PBXBuildFile; fileRef = AB75226D14C7BB51009B97B3 /* AppIcon_FirmwareConfig.icns */; };
AB796C9C15CDCB0F00C59155 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB796C9B15CDCB0F00C59155 /* arm_jit.cpp */; };
AB796C9F15CDCB0F00C59155 /* arm_jit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB796C9B15CDCB0F00C59155 /* arm_jit.cpp */; };
@ -796,6 +798,7 @@
AB64987B13ECC73800EE7DD2 /* FileTypeInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = FileTypeInfo.plist; sourceTree = "<group>"; };
AB68A0DA16B139BC00DE0546 /* OGLRender_3_2.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OGLRender_3_2.cpp; path = ../OGLRender_3_2.cpp; sourceTree = "<group>"; };
AB6FBEF5139B6258007BB045 /* slot1_retail_nand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = slot1_retail_nand.cpp; sourceTree = "<group>"; };
AB74EC891738499C0026C41E /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; };
AB75226D14C7BB51009B97B3 /* AppIcon_FirmwareConfig.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_FirmwareConfig.icns; sourceTree = "<group>"; };
AB796C9B15CDCB0F00C59155 /* arm_jit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = arm_jit.cpp; path = ../arm_jit.cpp; sourceTree = "<group>"; };
AB796CA115CDCB4600C59155 /* arm_jit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = arm_jit.h; path = ../arm_jit.h; sourceTree = "<group>"; };
@ -1090,6 +1093,7 @@
AB350BA51478AC96007165AC /* IOKit.framework in Frameworks */,
ABC570D5134431DA00E7B0B1 /* OpenGL.framework in Frameworks */,
AB4676F314AB12D60002FF94 /* libz.dylib in Frameworks */,
AB3701E5173A3FBF006E573E /* Carbon.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1101,6 +1105,7 @@
AB796D6615CDCBA200C59155 /* AppKit.framework in Frameworks */,
ABACB8DC1710B621003B845D /* AudioToolbox.framework in Frameworks */,
AB796D6715CDCBA200C59155 /* AudioUnit.framework in Frameworks */,
AB74EC8A1738499C0026C41E /* Carbon.framework in Frameworks */,
AB796D6815CDCBA200C59155 /* Cocoa.framework in Frameworks */,
AB796D6915CDCBA200C59155 /* Foundation.framework in Frameworks */,
AB796D6A15CDCBA200C59155 /* IOKit.framework in Frameworks */,
@ -1178,6 +1183,7 @@
29B97324FDCFA39411CA2CEA /* AppKit.framework */,
ABACB8DB1710B621003B845D /* AudioToolbox.framework */,
ABC570D0134431CE00E7B0B1 /* AudioUnit.framework */,
AB74EC891738499C0026C41E /* Carbon.framework */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
29B97325FDCFA39411CA2CEA /* Foundation.framework */,
AB350BA41478AC96007165AC /* IOKit.framework */,

View File

@ -46,6 +46,8 @@
#define NSSTRING_TITLE_ENABLE_CHEATS NSLocalizedString(@"Enable Cheats", nil)
#define NSSTRING_TITLE_DISABLE_HUD NSLocalizedString(@"Disable HUD", nil)
#define NSSTRING_TITLE_ENABLE_HUD NSLocalizedString(@"Enable HUD", nil)
#define NSSTRING_TITLE_EXIT_FULL_SCREEN NSLocalizedString(@"Exit Full Screen", nil)
#define NSSTRING_TITLE_ENTER_FULL_SCREEN NSLocalizedString(@"Enter Full Screen", nil)
#define NSSTRING_TITLE_HIDE_STATUS_BAR NSLocalizedString(@"Hide Status Bar", nil)
#define NSSTRING_TITLE_SHOW_STATUS_BAR NSLocalizedString(@"Show Status Bar", nil)
#define NSSTRING_TITLE_HIDE_TOOLBAR NSLocalizedString(@"Hide Toolbar", nil)

View File

@ -314,7 +314,6 @@
<int key="NSvFlags">5156</int>
<string key="NSFrame">{{2, 3}, {16, 16}}</string>
<reference key="NSSuperview" ref="1027645320"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="731708450"/>
<int key="NSpiFlags">28938</int>
<double key="NSMaxValue">100</double>
@ -336,7 +335,6 @@
</object>
<string key="NSFrame">{{160, 1}, {20, 20}}</string>
<reference key="NSSuperview" ref="1027645320"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="710507134"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="1028721215">
@ -359,7 +357,6 @@
<int key="NSvFlags">294</int>
<string key="NSFrame">{{17, 5}, {137, 14}}</string>
<reference key="NSSuperview" ref="1027645320"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="323138602"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="644649254">
@ -399,7 +396,6 @@
<int key="NSvFlags">45</int>
<string key="NSFrame">{{0, 24}, {256, 384}}</string>
<reference key="NSSuperview" ref="1027645320"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="963885183"/>
<bool key="NSViewCanDrawConcurrently">YES</bool>
<string key="NSClassName">DisplayView</string>
@ -409,7 +405,6 @@
<int key="NSvFlags">289</int>
<string key="NSFrame">{{180, 3}, {56, 15}}</string>
<reference key="NSSuperview" ref="1027645320"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="62495840">
<int key="NSCellFlags">-2080112384</int>
@ -430,7 +425,6 @@
</object>
<string key="NSFrameSize">{256, 408}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="740908585"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
@ -1177,217 +1171,7 @@
<nil key="sourceID"/>
<int key="maxID">109</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
<string key="className">DisplayView</string>
<string key="superclassName">NSView</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/DisplayView.h</string>
</object>
</object>
<object class="IBPartialClassDescription">
<string key="className">DisplayWindowController</string>
<string key="superclassName">NSWindowController</string>
<object class="NSMutableDictionary" key="actions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>changeCoreSpeed:</string>
<string>changeDisplayGap:</string>
<string>changeDisplayMode:</string>
<string>changeDisplayOrder:</string>
<string>changeDisplayOrientation:</string>
<string>changeRotation:</string>
<string>changeRotationRelative:</string>
<string>changeScale:</string>
<string>changeVolume:</string>
<string>copy:</string>
<string>openRom:</string>
<string>reset:</string>
<string>saveScreenshotAs:</string>
<string>toggleExecutePause:</string>
<string>toggleKeepMinDisplaySizeAtNormal:</string>
<string>toggleStatusBar:</string>
<string>writeDefaultsDisplayGap:</string>
<string>writeDefaultsDisplayRotation:</string>
<string>writeDefaultsDisplayVideoSettings:</string>
<string>writeDefaultsHUDSettings:</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
<string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="actionInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>changeCoreSpeed:</string>
<string>changeDisplayGap:</string>
<string>changeDisplayMode:</string>
<string>changeDisplayOrder:</string>
<string>changeDisplayOrientation:</string>
<string>changeRotation:</string>
<string>changeRotationRelative:</string>
<string>changeScale:</string>
<string>changeVolume:</string>
<string>copy:</string>
<string>openRom:</string>
<string>reset:</string>
<string>saveScreenshotAs:</string>
<string>toggleExecutePause:</string>
<string>toggleKeepMinDisplaySizeAtNormal:</string>
<string>toggleStatusBar:</string>
<string>writeDefaultsDisplayGap:</string>
<string>writeDefaultsDisplayRotation:</string>
<string>writeDefaultsDisplayVideoSettings:</string>
<string>writeDefaultsHUDSettings:</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">changeCoreSpeed:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeDisplayGap:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeDisplayMode:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeDisplayOrder:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeDisplayOrientation:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeRotation:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeRotationRelative:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeScale:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeVolume:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">copy:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">openRom:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">reset:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">saveScreenshotAs:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">toggleExecutePause:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">toggleKeepMinDisplaySizeAtNormal:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">toggleStatusBar:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">writeDefaultsDisplayGap:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">writeDefaultsDisplayRotation:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">writeDefaultsDisplayVideoSettings:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">writeDefaultsHUDSettings:</string>
<string key="candidateClassName">id</string>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>saveScreenshotPanelAccessoryView</string>
<string>view</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSView</string>
<string>DisplayView</string>
</object>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>saveScreenshotPanelAccessoryView</string>
<string>view</string>
</object>
<object class="NSArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBToOneOutletInfo">
<string key="name">saveScreenshotPanelAccessoryView</string>
<string key="candidateClassName">NSView</string>
</object>
<object class="IBToOneOutletInfo">
<string key="name">view</string>
<string key="candidateClassName">DisplayView</string>
</object>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/DisplayWindowController.h</string>
</object>
</object>
</object>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes"/>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencies">

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,11 @@
@class EmuControllerDelegate;
// Subclass NSWindow for full screen windows so that we can override some methods.
@interface DisplayFullScreenWindow : NSWindow
{ }
@end
@interface DisplayView : NSView <CocoaDSDisplayVideoDelegate, InputHIDManagerTarget>
{
InputManager *inputManager;
@ -38,9 +43,11 @@
NSOpenGLContext *context;
CGLContextObj cglDisplayContext;
NSInteger lastDisplayMode;
NSInteger currentDisplayOrientation;
GLfloat currentGapScalar;
NSSize _currentNormalSize;
NSInteger _currentDisplayMode;
NSInteger _currentDisplayOrientation;
GLfloat _currentGapScalar;
GLfloat _currentRotation;
GLenum glTexPixelFormat;
GLvoid *glTexBack;
NSSize glTexBackSize;
@ -90,13 +97,19 @@
@end
#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
@interface DisplayWindowController : NSWindowController <NSWindowDelegate>
#else
@interface DisplayWindowController : NSWindowController
#endif
{
DisplayView *view;
NSView *saveScreenshotPanelAccessoryView;
EmuControllerDelegate *emuControl;
CocoaDSDisplayVideo *cdsVideoOutput;
NSScreen *assignedScreen;
NSWindow *masterWindow;
NSSize _normalSize;
double _displayScale;
@ -113,6 +126,7 @@
NSSize _minDisplayViewSize;
BOOL _isMinSizeNormal;
NSUInteger _statusBarHeight;
BOOL _isWindowResizing;
OSSpinLock spinlockNormalSize;
OSSpinLock spinlockScale;
@ -131,6 +145,8 @@
@property (retain) EmuControllerDelegate *emuControl;
@property (assign) CocoaDSDisplayVideo *cdsVideoOutput;
@property (assign) NSScreen *assignedScreen;
@property (retain) NSWindow *masterWindow;
@property (readonly) NSSize normalSize;
@property (assign) double displayScale;
@ -151,11 +167,14 @@
- (void) setupUserDefaults;
- (double) resizeWithTransform:(NSSize)normalBounds scalar:(double)scalar rotation:(double)angleDegrees;
- (double) maxScalarForContentBoundsWidth:(double)contentBoundsWidth height:(double)contentBoundsHeight;
- (void) enterFullScreen;
- (void) exitFullScreen;
- (IBAction) copy:(id)sender;
- (IBAction) changeVolume:(id)sender;
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender;
- (IBAction) toggleStatusBar:(id)sender;
- (IBAction) toggleFullScreenDisplay:(id)sender;
- (IBAction) toggleExecutePause:(id)sender;
- (IBAction) reset:(id)sender;
@ -171,6 +190,9 @@
- (IBAction) changeDisplayOrientation:(id)sender;
- (IBAction) changeDisplayOrder:(id)sender;
- (IBAction) changeDisplayGap:(id)sender;
- (IBAction) toggleBilinearFilteredOutput:(id)sender;
- (IBAction) toggleVerticalSync:(id)sender;
- (IBAction) changeVideoFilter:(id)sender;
- (IBAction) writeDefaultsDisplayRotation:(id)sender;
- (IBAction) writeDefaultsDisplayGap:(id)sender;

View File

@ -25,10 +25,17 @@
#import "cocoa_videofilter.h"
#import "cocoa_util.h"
#include <Carbon/Carbon.h>
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <OpenGL/glu.h>
#if defined(__ppc__) || defined(__ppc64__)
#include <map>
#else
#include <tr1/unordered_map>
#endif
// VERTEX SHADER FOR DISPLAY OUTPUT
static const char *vertexProgram_100 = {"\
attribute vec2 inPosition; \n\
@ -80,6 +87,8 @@ enum OGLVertexAttributeID
@synthesize emuControl;
@synthesize cdsVideoOutput;
@synthesize assignedScreen;
@synthesize masterWindow;
@synthesize view;
@synthesize saveScreenshotPanelAccessoryView;
@ -97,6 +106,11 @@ enum OGLVertexAttributeID
@dynamic isMinSizeNormal;
@dynamic isShowingStatusBar;
#if defined(__ppc__) || defined(__ppc64__)
static std::map<NSScreen *, DisplayWindowController *> _screenMap; // Key = NSScreen object pointer, Value = DisplayWindowController object pointer
#else
static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap; // Key = NSScreen object pointer, Value = DisplayWindowController object pointer
#endif
- (id)initWithWindowNibName:(NSString *)windowNibName emuControlDelegate:(EmuControllerDelegate *)theEmuController
{
@ -108,6 +122,8 @@ enum OGLVertexAttributeID
emuControl = [theEmuController retain];
cdsVideoOutput = nil;
assignedScreen = nil;
masterWindow = nil;
spinlockNormalSize = OS_SPINLOCK_INIT;
spinlockScale = OS_SPINLOCK_INIT;
@ -130,14 +146,18 @@ enum OGLVertexAttributeID
_minDisplayViewSize = NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*_displayGap));
_isMinSizeNormal = YES;
_statusBarHeight = WINDOW_STATUS_BAR_HEIGHT;
[[self window] setTitle:(NSString *)[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]];
_isWindowResizing = NO;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(saveScreenshotAsFinish:)
name:@"org.desmume.DeSmuME.requestScreenshotDidFinish"
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(respondToScreenChange:)
name:@"NSApplicationDidChangeScreenParametersNotification"
object:NSApp];
return self;
}
@ -145,6 +165,8 @@ enum OGLVertexAttributeID
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self setEmuControl:nil];
[self setAssignedScreen:nil];
[self setMasterWindow:nil];
[super dealloc];
}
@ -161,24 +183,22 @@ enum OGLVertexAttributeID
}
- (void) setDisplayScale:(double)s
{
if (_isWindowResizing)
{
// Resize the window when displayScale changes.
// No need to set the view's scale here since window resizing will implicitly change it.
OSSpinLockLock(&spinlockScale);
_displayScale = s;
OSSpinLockUnlock(&spinlockScale);
}
else
{
const double constrainedScale = [self resizeWithTransform:[self normalSize] scalar:s rotation:[self displayRotation]];
OSSpinLockLock(&spinlockScale);
_displayScale = constrainedScale;
OSSpinLockUnlock(&spinlockScale);
DisplayOutputTransformData transformData = { constrainedScale,
[self displayRotation],
0.0,
0.0,
0.0 };
[CocoaDSUtil messageSendOneWayWithData:[[self cdsVideoOutput] receivePort]
msgID:MESSAGE_TRANSFORM_VIEW
data:[NSData dataWithBytes:&transformData length:sizeof(DisplayOutputTransformData)]];
}
}
- (double) displayScale
@ -324,7 +344,6 @@ enum OGLVertexAttributeID
}
OSSpinLockLock(&spinlockDisplayMode);
const NSInteger oldMode = _displayMode;
_displayMode = displayModeID;
OSSpinLockUnlock(&spinlockDisplayMode);
@ -336,14 +355,6 @@ enum OGLVertexAttributeID
[self resizeWithTransform:[self normalSize] scalar:[self displayScale] rotation:[self displayRotation]];
[CocoaDSUtil messageSendOneWayWithInteger:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_DISPLAY_TYPE integerValue:displayModeID];
// If the display mode swaps between Main Only and Touch Only, the view will not resize to implicitly
// redraw the view. So when swapping between these two display modes, explicitly tell the view to redraw.
if ( (oldMode == DS_DISPLAY_TYPE_MAIN && displayModeID == DS_DISPLAY_TYPE_TOUCH) ||
(oldMode == DS_DISPLAY_TYPE_TOUCH && displayModeID == DS_DISPLAY_TYPE_MAIN) )
{
[CocoaDSUtil messageSendOneWay:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_REDRAW_VIEW];
}
}
- (NSInteger) displayMode
@ -516,17 +527,17 @@ enum OGLVertexAttributeID
- (void) setIsShowingStatusBar:(BOOL)showStatusBar
{
NSRect frameRect = [[self window] frame];
NSRect frameRect = [masterWindow frame];
if (showStatusBar)
{
_statusBarHeight = WINDOW_STATUS_BAR_HEIGHT;
frameRect.size.height += WINDOW_STATUS_BAR_HEIGHT;
NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
NSRect screenFrame = [[masterWindow screen] visibleFrame];
if (frameRect.size.height > screenFrame.size.height)
{
NSRect windowContentRect = [[[self window] contentView] bounds];
NSRect windowContentRect = [[masterWindow contentView] bounds];
double widthToHeightRatio = windowContentRect.size.width / windowContentRect.size.height;
windowContentRect.size.height -= frameRect.size.height - screenFrame.size.height;
windowContentRect.size.width = windowContentRect.size.height * widthToHeightRatio;
@ -547,7 +558,7 @@ enum OGLVertexAttributeID
}
[[NSUserDefaults standardUserDefaults] setBool:showStatusBar forKey:@"DisplayView_ShowStatusBar"];
[[self window] setFrame:frameRect display:YES animate:NO];
[masterWindow setFrame:frameRect display:YES animate:NO];
}
- (BOOL) isShowingStatusBar
@ -576,7 +587,10 @@ enum OGLVertexAttributeID
- (double) resizeWithTransform:(NSSize)normalBounds scalar:(double)scalar rotation:(double)angleDegrees
{
NSWindow *theWindow = [self window];
if ([self assignedScreen] != nil)
{
return scalar;
}
// Convert angle to clockwise-direction degrees.
angleDegrees = CLOCKWISE_DEGREES(angleDegrees);
@ -593,14 +607,14 @@ enum OGLVertexAttributeID
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];
const NSRect windowContentRect = [[masterWindow contentView] bounds];
const double translationX = (windowContentRect.size.width - transformedBounds.width) / 2.0;
const double translationY = ((windowContentRect.size.height - _statusBarHeight) - transformedBounds.height) / 2.0;
// Resize the window.
const NSRect windowFrame = [theWindow frame];
const NSRect newFrame = [theWindow frameRectForContentRect:NSMakeRect(windowFrame.origin.x + translationX, windowFrame.origin.y + translationY, transformedBounds.width, transformedBounds.height + _statusBarHeight)];
[theWindow setFrame:newFrame display:YES animate:NO];
const NSRect windowFrame = [masterWindow frame];
const NSRect newFrame = [masterWindow frameRectForContentRect:NSMakeRect(windowFrame.origin.x + translationX, windowFrame.origin.y + translationY, transformedBounds.width, transformedBounds.height + _statusBarHeight)];
[masterWindow setFrame:newFrame display:YES animate:NO];
// Return the actual scale used for the view (may be constrained).
return scalar;
@ -632,6 +646,108 @@ enum OGLVertexAttributeID
[emuControl restoreCoreState];
}
- (void) enterFullScreen
{
NSScreen *targetScreen = [masterWindow screen];
// If there is a window that is already assigned to the target screen, then force the
// current window to exit full screen first.
if (_screenMap.find(targetScreen) != _screenMap.end())
{
DisplayWindowController *currentFullScreenWindow = _screenMap[targetScreen];
[currentFullScreenWindow exitFullScreen];
}
[[self window] orderOut:nil];
// Since we'll be using the screen rect to position the window, we need to set the origin
// to (0,0) since creating the new full screen window requires the screen rect to be in
// screen coordinates.
NSRect screenRect = [targetScreen frame];
screenRect.origin.x = 0.0;
screenRect.origin.y = 0.0;
DisplayFullScreenWindow *newFullScreenWindow = [[[DisplayFullScreenWindow alloc] initWithContentRect:screenRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO
screen:targetScreen] autorelease];
[newFullScreenWindow setHasShadow:NO];
[newFullScreenWindow setInitialFirstResponder:view];
[view setFrame:screenRect];
[[newFullScreenWindow contentView] addSubview:view];
[newFullScreenWindow setDelegate:self];
// If the target screen is the main screen (index 0), then autohide the menu bar and dock.
if (targetScreen == [[NSScreen screens] objectAtIndex:0])
{
SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
}
// Show the full screen window.
[self setWindow:newFullScreenWindow];
[newFullScreenWindow makeKeyAndOrderFront:self];
[newFullScreenWindow display];
[self setAssignedScreen:targetScreen];
_screenMap[targetScreen] = self;
}
- (void) exitFullScreen
{
_screenMap.erase([self assignedScreen]);
[self setAssignedScreen:nil];
[[self window] orderOut:nil];
// If the window is using the main screen (index 0), then restore the menu bar and dock.
if ([masterWindow screen] == [[NSScreen screens] objectAtIndex:0])
{
SetSystemUIMode(kUIModeNormal, 0);
}
[self setWindow:masterWindow];
[self resizeWithTransform:[self normalSize] scalar:[self displayScale] rotation:[self displayRotation]];
NSRect viewFrame = [[masterWindow contentView] frame];
viewFrame.size.height -= _statusBarHeight;
viewFrame.origin.y = _statusBarHeight;
[view setFrame:viewFrame];
[[masterWindow contentView] addSubview:view];
[masterWindow makeKeyAndOrderFront:self];
[masterWindow display];
}
- (void) respondToScreenChange:(NSNotification *)aNotification
{
// This method only applies for displays in full screen mode. For displays in
// windowed mode, we don't need to do anything.
if ([self assignedScreen] == nil)
{
return;
}
NSArray *screenList = [NSScreen screens];
// If the assigned screen was disconnected, exit full screen mode. Hopefully, the
// window will automatically move onto an available screen.
if (![screenList containsObject:[self assignedScreen]])
{
[self exitFullScreen];
}
else
{
// There are many other reasons that a screen change would occur, but the only
// other one we care about is a resolution change. Let's just assume that a
// resolution change occurred and resize the full screen window.
NSRect screenRect = [assignedScreen frame];
[[self window] setFrame:screenRect display:NO];
screenRect.origin.x = 0.0;
screenRect.origin.y = 0.0;
[view setFrame:screenRect];
}
}
#pragma mark IBActions
- (IBAction) copy:(id)sender
@ -646,8 +762,6 @@ enum OGLVertexAttributeID
- (IBAction) toggleKeepMinDisplaySizeAtNormal:(id)sender
{
NSWindow *theWindow = [self window];
if ([self isMinSizeNormal])
{
[self setIsMinSizeNormal:NO];
@ -661,20 +775,20 @@ enum OGLVertexAttributeID
transformedMinSize.height += _statusBarHeight;
// Resize the window if it's smaller than the minimum content size.
NSRect windowContentRect = [theWindow contentRectForFrameRect:[theWindow frame]];
NSRect windowContentRect = [masterWindow contentRectForFrameRect:[masterWindow frame]];
if (windowContentRect.size.width < transformedMinSize.width || windowContentRect.size.height < transformedMinSize.height)
{
// Prepare to resize.
NSRect oldFrameRect = [theWindow frame];
NSRect oldFrameRect = [masterWindow frame];
windowContentRect.size = NSMakeSize(transformedMinSize.width, transformedMinSize.height);
NSRect newFrameRect = [theWindow frameRectForContentRect:windowContentRect];
NSRect newFrameRect = [masterWindow frameRectForContentRect:windowContentRect];
// Keep the window centered when expanding the size.
newFrameRect.origin.x = oldFrameRect.origin.x - ((newFrameRect.size.width - oldFrameRect.size.width) / 2);
newFrameRect.origin.y = oldFrameRect.origin.y - ((newFrameRect.size.height - oldFrameRect.size.height) / 2);
// Set the window size.
[theWindow setFrame:newFrameRect display:YES animate:NO];
[masterWindow setFrame:newFrameRect display:YES animate:NO];
}
}
}
@ -684,6 +798,18 @@ enum OGLVertexAttributeID
[self setIsShowingStatusBar:([self isShowingStatusBar]) ? NO : YES];
}
- (IBAction) toggleFullScreenDisplay:(id)sender
{
if ([self assignedScreen] == nil)
{
[self enterFullScreen];
}
else
{
[self exitFullScreen];
}
}
- (IBAction) toggleExecutePause:(id)sender
{
[emuControl toggleExecutePause:sender];
@ -782,6 +908,21 @@ enum OGLVertexAttributeID
[self setDisplayGap:(double)[CocoaDSUtil getIBActionSenderTag:sender] / 100.0];
}
- (IBAction) toggleBilinearFilteredOutput:(id)sender
{
[self setUseBilinearOutput:([self useBilinearOutput]) ? NO : YES];
}
- (IBAction) toggleVerticalSync:(id)sender
{
[self setUseVerticalSync:([self useVerticalSync]) ? NO : YES];
}
- (IBAction) changeVideoFilter:(id)sender
{
[self setVideoFilterType:[CocoaDSUtil getIBActionSenderTag:sender]];
}
- (IBAction) writeDefaultsDisplayRotation:(id)sender
{
[[NSUserDefaults standardUserDefaults] setDouble:[self displayRotation] forKey:@"DisplayView_Rotation"];
@ -897,6 +1038,27 @@ enum OGLVertexAttributeID
}
}
}
else if (theAction == @selector(toggleBilinearFilteredOutput:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setState:([self useBilinearOutput]) ? NSOnState : NSOffState];
}
}
else if (theAction == @selector(toggleVerticalSync:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setState:([self useVerticalSync]) ? NSOnState : NSOffState];
}
}
else if (theAction == @selector(changeVideoFilter:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setState:([self videoFilterType] == [theItem tag]) ? NSOnState : NSOffState];
}
}
else if (theAction == @selector(hudDisable:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
@ -910,6 +1072,18 @@ enum OGLVertexAttributeID
{
[(NSMenuItem *)theItem setTitle:([self isShowingStatusBar]) ? NSSTRING_TITLE_HIDE_STATUS_BAR : NSSTRING_TITLE_SHOW_STATUS_BAR];
}
if ([self assignedScreen] != nil)
{
enable = NO;
}
}
else if (theAction == @selector(toggleFullScreenDisplay:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setTitle:([self assignedScreen] != nil) ? NSSTRING_TITLE_EXIT_FULL_SCREEN : NSSTRING_TITLE_ENTER_FULL_SCREEN];
}
}
else if (theAction == @selector(toggleKeepMinDisplaySizeAtNormal:))
{
@ -917,6 +1091,11 @@ enum OGLVertexAttributeID
{
[(NSMenuItem *)theItem setState:([self isMinSizeNormal]) ? NSOnState : NSOffState];
}
if ([self assignedScreen] != nil)
{
enable = NO;
}
}
else if (theAction == @selector(toggleToolbarShown:))
{
@ -933,6 +1112,14 @@ enum OGLVertexAttributeID
- (void)windowDidLoad
{
// Set up the master window that is associated with this window controller.
[self setMasterWindow:[self window]];
[masterWindow setTitle:(NSString *)[[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"]];
[masterWindow setInitialFirstResponder:view];
[view setInputManager:[emuControl inputManager]];
[[emuControl windowList] addObject:self];
[emuControl updateAllWindowTitles];
// Set up the video output thread.
cdsVideoOutput = [[CocoaDSDisplayVideo alloc] init];
[cdsVideoOutput setDelegate:view];
@ -965,6 +1152,13 @@ enum OGLVertexAttributeID
- (NSSize)windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
if ([self assignedScreen] != nil)
{
return frameSize;
}
_isWindowResizing = YES;
// Get a content Rect so that we can make our comparison.
// This will be based on the proposed frameSize.
const NSRect frameRect = NSMakeRect(0.0f, 0.0f, frameSize.width, frameSize.height);
@ -987,6 +1181,13 @@ enum OGLVertexAttributeID
- (void)windowDidResize:(NSNotification *)notification
{
if ([self assignedScreen] != nil)
{
return;
}
_isWindowResizing = YES;
// Get the max scalar within the window's current content bounds.
const NSSize normalBounds = [self normalSize];
const CGSize checkSize = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, [self displayRotation]);
@ -1002,6 +1203,8 @@ enum OGLVertexAttributeID
newContentFrame.origin.y = _statusBarHeight;
newContentFrame.size.height -= _statusBarHeight;
[view setFrame:newContentFrame];
_isWindowResizing = NO;
}
- (BOOL)windowShouldClose:(id)sender
@ -1132,13 +1335,14 @@ enum OGLVertexAttributeID
[self startupOpenGL];
CGLSetCurrentContext(prevContext);
lastDisplayMode = DS_DISPLAY_TYPE_COMBO;
currentDisplayOrientation = DS_DISPLAY_ORIENTATION_VERTICAL;
currentGapScalar = 0.0f;
_currentDisplayMode = DS_DISPLAY_TYPE_COMBO;
_currentDisplayOrientation = DS_DISPLAY_ORIENTATION_VERTICAL;
_currentGapScalar = 0.0f;
_currentNormalSize = NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*_currentGapScalar));
glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
UInt32 w = GetNearestPositivePOT((UInt32)GPU_DISPLAY_WIDTH);
UInt32 h = GetNearestPositivePOT((UInt32)(GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*currentGapScalar)));
const UInt32 w = GetNearestPositivePOT((UInt32)_currentNormalSize.width);
const UInt32 h = GetNearestPositivePOT((UInt32)_currentNormalSize.height);
glTexBack = (GLvoid *)calloc(w * h, sizeof(UInt16));
glTexBackSize = NSMakeSize(w, h);
vtxBufferOffset = 0;
@ -1169,7 +1373,7 @@ enum OGLVertexAttributeID
- (void) startupOpenGL
{
[self updateDisplayVerticesUsingDisplayMode:lastDisplayMode orientation:currentDisplayOrientation gap:currentGapScalar];
[self updateDisplayVerticesUsingDisplayMode:_currentDisplayMode orientation:_currentDisplayOrientation gap:_currentGapScalar];
[self updateTexCoordS:1.0f T:2.0f];
// Set up initial vertex elements
@ -1213,7 +1417,7 @@ enum OGLVertexAttributeID
glUniform1f(uniformAngleDegrees, 0.0f);
glUniform1f(uniformScalar, 1.0f);
glUniform2f(uniformViewSize, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*currentGapScalar));
glUniform2f(uniformViewSize, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*_currentGapScalar));
}
else
{
@ -1424,10 +1628,10 @@ enum OGLVertexAttributeID
glBindVertexArrayAPPLE(vaoMainStatesID);
// Perform the render
if (lastDisplayMode != displayModeID)
if (_currentDisplayMode != displayModeID)
{
lastDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:currentDisplayOrientation gap:currentGapScalar];
_currentDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:_currentDisplayOrientation gap:_currentGapScalar];
[self uploadVertices];
}
@ -1528,11 +1732,14 @@ enum OGLVertexAttributeID
}
const NSSize normalBounds = [windowController normalSize];
const NSSize transformBounds = [self bounds].size;
const NSSize viewSize = [self bounds].size;
const CGSize transformBounds = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, _currentRotation);
const double s = GetMaxScalarInBounds(transformBounds.width, transformBounds.height, viewSize.width, viewSize.height);
CGPoint touchLoc = GetNormalPointFromTransformedPoint(clickLoc.x, clickLoc.y,
normalBounds.width, normalBounds.height,
transformBounds.width, transformBounds.height,
[windowController displayScale],
viewSize.width, viewSize.height,
s,
viewAngle);
// Normalize the touch location to the DS.
@ -1865,6 +2072,10 @@ enum OGLVertexAttributeID
- (void)doResizeView:(NSRect)rect
{
const NSSize viewSize = [self frame].size;
const CGSize checkSize = GetTransformedBounds(_currentNormalSize.width, _currentNormalSize.height, 1.0, _currentRotation);
const double s = GetMaxScalarInBounds(checkSize.width, checkSize.height, viewSize.width, viewSize.height);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
@ -1873,38 +2084,50 @@ enum OGLVertexAttributeID
if (isShaderSupported)
{
glUniform2f(uniformViewSize, rect.size.width, rect.size.height);
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-rect.size.width/2, -rect.size.width/2 + rect.size.width, -rect.size.height/2, -rect.size.height/2 + rect.size.height, -1.0, 1.0);
glRotatef(CLOCKWISE_DEGREES(_currentRotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doTransformView:(const DisplayOutputTransformData *)transformData
{
const GLfloat angleDegrees = (GLfloat)transformData->rotation;
const GLfloat s = (GLfloat)transformData->scale;
_currentRotation = (GLfloat)transformData->rotation;
const NSSize viewSize = [self bounds].size;
const CGSize checkSize = GetTransformedBounds(_currentNormalSize.width, _currentNormalSize.height, 1.0, _currentRotation);
const double s = GetMaxScalarInBounds(checkSize.width, checkSize.height, viewSize.width, viewSize.height);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
if (isShaderSupported)
{
glUniform1f(uniformAngleDegrees, angleDegrees);
glUniform1f(uniformAngleDegrees, _currentRotation);
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(angleDegrees), 0.0f, 0.0f, 1.0f);
glRotatef(CLOCKWISE_DEGREES(_currentRotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
@ -1913,7 +2136,7 @@ enum OGLVertexAttributeID
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self renderDisplayUsingDisplayMode:lastDisplayMode];
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
@ -1921,20 +2144,41 @@ enum OGLVertexAttributeID
- (void)doDisplayModeChanged:(NSInteger)displayModeID
{
lastDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:currentDisplayOrientation gap:currentGapScalar];
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
_currentNormalSize = [windowController normalSize];
const NSSize viewSize = [self bounds].size;
const CGSize checkSize = GetTransformedBounds(_currentNormalSize.width, _currentNormalSize.height, 1.0, _currentRotation);
const double s = GetMaxScalarInBounds(checkSize.width, checkSize.height, viewSize.width, viewSize.height);
_currentDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:_currentDisplayOrientation gap:_currentGapScalar];
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
if (isShaderSupported)
{
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(_currentRotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
[self uploadVertices];
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doBilinearOutputChanged:(BOOL)useBilinear
{
const GLint textureFilter = useBilinear ? GL_LINEAR : GL_NEAREST;
const GLint textureFilter = (useBilinear) ? GL_LINEAR : GL_NEAREST;
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
@ -1949,14 +2193,39 @@ enum OGLVertexAttributeID
- (void)doDisplayOrientationChanged:(NSInteger)displayOrientationID
{
currentDisplayOrientation = displayOrientationID;
[self updateDisplayVerticesUsingDisplayMode:lastDisplayMode orientation:displayOrientationID gap:currentGapScalar];
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
_currentNormalSize = [windowController normalSize];
_currentDisplayOrientation = displayOrientationID;
[self updateDisplayVerticesUsingDisplayMode:_currentDisplayMode orientation:displayOrientationID gap:_currentGapScalar];
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadVertices];
if (_currentDisplayMode == DS_DISPLAY_TYPE_COMBO)
{
const NSSize viewSize = [self bounds].size;
const CGSize checkSize = GetTransformedBounds(_currentNormalSize.width, _currentNormalSize.height, 1.0, _currentRotation);
const double s = GetMaxScalarInBounds(checkSize.width, checkSize.height, viewSize.width, viewSize.height);
if (isShaderSupported)
{
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(_currentRotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
}
CGLUnlockContext(cglDisplayContext);
}
@ -1976,9 +2245,9 @@ enum OGLVertexAttributeID
[self uploadVertices];
if (lastDisplayMode == DS_DISPLAY_TYPE_COMBO)
if (_currentDisplayMode == DS_DISPLAY_TYPE_COMBO)
{
[self renderDisplayUsingDisplayMode:lastDisplayMode];
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
}
@ -1987,14 +2256,39 @@ enum OGLVertexAttributeID
- (void)doDisplayGapChanged:(float)displayGapScalar
{
currentGapScalar = (GLfloat)displayGapScalar;
[self updateDisplayVerticesUsingDisplayMode:lastDisplayMode orientation:currentDisplayOrientation gap:(GLfloat)displayGapScalar];
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
_currentNormalSize = [windowController normalSize];
_currentGapScalar = (GLfloat)displayGapScalar;
[self updateDisplayVerticesUsingDisplayMode:_currentDisplayMode orientation:_currentDisplayOrientation gap:(GLfloat)displayGapScalar];
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadVertices];
if (_currentDisplayMode == DS_DISPLAY_TYPE_COMBO)
{
const NSSize viewSize = [self bounds].size;
const CGSize checkSize = GetTransformedBounds(_currentNormalSize.width, _currentNormalSize.height, 1.0, _currentRotation);
const double s = GetMaxScalarInBounds(checkSize.width, checkSize.height, viewSize.width, viewSize.height);
if (isShaderSupported)
{
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(_currentRotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
}
CGLUnlockContext(cglDisplayContext);
}
@ -2015,7 +2309,7 @@ enum OGLVertexAttributeID
glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
}
if ([(DisplayWindowController *)[[self window] delegate] displayMode] != DS_DISPLAY_TYPE_COMBO)
if (_currentDisplayMode != DS_DISPLAY_TYPE_COMBO)
{
videoFilterDestSize.height = (uint32_t)videoFilterDestSize.height * 2;
}
@ -2055,3 +2349,19 @@ enum OGLVertexAttributeID
}
@end
#pragma mark -
@implementation DisplayFullScreenWindow
#pragma mark NSWindow Methods
- (BOOL)canBecomeKeyWindow
{
return YES;
}
- (BOOL)canBecomeMainWindow
{
return YES;
}
@end

View File

@ -430,11 +430,6 @@
- (IBAction) newDisplayWindow:(id)sender
{
DisplayWindowController *newWindowController = [[DisplayWindowController alloc] initWithWindowNibName:@"DisplayWindow" emuControlDelegate:self];
[windowList addObject:newWindowController];
[[newWindowController view] setInputManager:[self inputManager]];
[self updateAllWindowTitles];
[newWindowController showWindow:self];
[[newWindowController window] makeKeyAndOrderFront:self];
[[newWindowController window] makeMainWindow];
@ -1796,14 +1791,14 @@
{
NSString *newWindowTitle = [romName stringByAppendingFormat:@":%ld", (unsigned long)([windowList indexOfObject:windowController] + 1)];
[[windowController window] setTitle:newWindowTitle];
[[windowController window] setRepresentedURL:repURL];
[[[windowController window] standardWindowButton:NSWindowDocumentIconButton] setImage:titleIcon];
[[windowController masterWindow] setTitle:newWindowTitle];
[[windowController masterWindow] setRepresentedURL:repURL];
[[[windowController masterWindow] standardWindowButton:NSWindowDocumentIconButton] setImage:titleIcon];
}
}
else
{
NSWindow *theWindow = [[windowList objectAtIndex:0] window];
NSWindow *theWindow = [[windowList objectAtIndex:0] masterWindow];
[theWindow setTitle:romName];
[theWindow setRepresentedURL:repURL];
[[theWindow standardWindowButton:NSWindowDocumentIconButton] setImage:titleIcon];