Video Filters:

- Add new xBRZ family of filters.

Cocoa Port:
- Refactor all display code. OpenGL code is pushed to a lower level and filter code is pushed towards the UI level.
- Add support for the new xBRZ filters.
- The Execution Control panel no longer always appears on app startup.
This commit is contained in:
rogerman 2014-02-07 04:34:32 +00:00
parent 2c3db349c3
commit 875ae2cc4b
17 changed files with 2602 additions and 975 deletions

View File

@ -1168,6 +1168,16 @@
ABD59849187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; };
ABD5984A187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; };
ABD5984B187D4A6C00069403 /* Icon_PaddleKnob_256x256.png in Resources */ = {isa = PBXBuildFile; fileRef = ABD59846187D4A6C00069403 /* Icon_PaddleKnob_256x256.png */; };
ABECB50918A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB50A18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB50B18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB50C18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB50D18A460710052D52A /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB50818A460710052D52A /* xbrz.cpp */; };
ABECB51418A460910052D52A /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */; };
ABECB51518A460910052D52A /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */; };
ABECB51618A460910052D52A /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */; };
ABECB51718A460910052D52A /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */; };
ABECB51818A460910052D52A /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */; };
ABEF84721873576300E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; };
ABEF84831873578F00E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; };
ABEF84841873579400E99ADC /* ForceFeedback.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB8C6E56186CD07E00E3EC64 /* ForceFeedback.framework */; };
@ -1624,6 +1634,10 @@
ABE6702A1415DE6C00E8E4C9 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = "<group>"; };
ABE7F53C13EE1C7900FD3A71 /* cocoa_firmware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_firmware.h; sourceTree = "<group>"; };
ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_firmware.mm; sourceTree = "<group>"; };
ABECB50718A460710052D52A /* xbrz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbrz.h; sourceTree = "<group>"; };
ABECB50818A460710052D52A /* xbrz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbrz.cpp; sourceTree = "<group>"; };
ABECB51218A460910052D52A /* OGLDisplayOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; };
ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLDisplayOutput.cpp; sourceTree = "<group>"; };
ABEFCF5D141AB82A000CC0CD /* AppIcon_ROMSave.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_ROMSave.icns; sourceTree = "<group>"; };
ABEFCF5E141AB82A000CC0CD /* AppIcon_DeSmuME.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_DeSmuME.icns; sourceTree = "<group>"; };
ABEFCF5F141AB82A000CC0CD /* AppIcon_NintendoDS_ROM.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_NintendoDS_ROM.icns; sourceTree = "<group>"; };
@ -1812,6 +1826,7 @@
AB2145221714DFF4006DDB0F /* audiosamplegenerator.cpp */,
ABD0A5341501AA5A0074A094 /* coreaudiosound.cpp */,
ABD9A46413DB99B300777194 /* mic_ext.cpp */,
ABECB51318A460910052D52A /* OGLDisplayOutput.cpp */,
ABD0A5351501AA5A0074A094 /* ringbuffer.cpp */,
ABD104141346652500AF11D1 /* sndOSX.cpp */,
AB2145211714DFF4006DDB0F /* audiosamplegenerator.h */,
@ -1829,6 +1844,7 @@
ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */,
ABD0A5361501AA5A0074A094 /* coreaudiosound.h */,
ABD9A46313DB99B300777194 /* mic_ext.h */,
ABECB51218A460910052D52A /* OGLDisplayOutput.h */,
ABD0A5371501AA5A0074A094 /* ringbuffer.h */,
ABD104011346652500AF11D1 /* sndOSX.h */,
AB2F56EE1704C86900E28885 /* utilities.h */,
@ -2451,12 +2467,14 @@
ABFE150414C92FF5005D6699 /* lq2x.cpp */,
ABFE150614C92FF5005D6699 /* scanline.cpp */,
AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */,
ABECB50818A460710052D52A /* xbrz.cpp */,
ABFE14FD14C92FF5005D6699 /* filter.h */,
ABFE14FF14C92FF5005D6699 /* hq2x.h */,
ABFE150214C92FF5005D6699 /* hq4x.h */,
ABFE150314C92FF5005D6699 /* interp.h */,
ABFE150514C92FF5005D6699 /* lq2x.h */,
AB817A34143EE2DB00A7DFE9 /* videofilter.h */,
ABECB50718A460710052D52A /* xbrz.h */,
);
name = filter;
path = ../filter;
@ -3366,6 +3384,8 @@
AB53518A18313E4E00CCD532 /* slot2.cpp in Sources */,
ABAE2F7F18682B6C00C92F4F /* Slot2WindowDelegate.mm in Sources */,
ABAE2F8818682B8F00C92F4F /* cocoa_slot2.mm in Sources */,
ABECB50D18A460710052D52A /* xbrz.cpp in Sources */,
ABECB51818A460910052D52A /* OGLDisplayOutput.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3508,6 +3528,8 @@
AB53518718313E4E00CCD532 /* slot2.cpp in Sources */,
ABAE2F7B18682B6C00C92F4F /* Slot2WindowDelegate.mm in Sources */,
ABAE2F8418682B8F00C92F4F /* cocoa_slot2.mm in Sources */,
ABECB50A18A460710052D52A /* xbrz.cpp in Sources */,
ABECB51518A460910052D52A /* OGLDisplayOutput.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3680,6 +3702,8 @@
ABAE2F7C18682B6C00C92F4F /* Slot2WindowDelegate.mm in Sources */,
ABAE2F8518682B8F00C92F4F /* cocoa_slot2.mm in Sources */,
AB8FFCB4186F8E5400C10085 /* slot2_mpcf.cpp in Sources */,
ABECB50918A460710052D52A /* xbrz.cpp in Sources */,
ABECB51418A460910052D52A /* OGLDisplayOutput.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3852,6 +3876,8 @@
AB53518918313E4E00CCD532 /* slot2.cpp in Sources */,
ABAE2F7E18682B6C00C92F4F /* Slot2WindowDelegate.mm in Sources */,
ABAE2F8718682B8F00C92F4F /* cocoa_slot2.mm in Sources */,
ABECB50C18A460710052D52A /* xbrz.cpp in Sources */,
ABECB51718A460910052D52A /* OGLDisplayOutput.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3994,6 +4020,8 @@
AB53518818313E4E00CCD532 /* slot2.cpp in Sources */,
ABAE2F7D18682B6C00C92F4F /* Slot2WindowDelegate.mm in Sources */,
ABAE2F8618682B8F00C92F4F /* cocoa_slot2.mm in Sources */,
ABECB50B18A460710052D52A /* xbrz.cpp in Sources */,
ABECB51618A460910052D52A /* OGLDisplayOutput.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -533,6 +533,10 @@
ABB3C6D51501C04F00E0C22E /* thumb_instructions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FECD1345AC8400AF11D1 /* thumb_instructions.cpp */; };
ABB3C6D61501C04F00E0C22E /* version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FECE1345AC8400AF11D1 /* version.cpp */; };
ABB3C6D71501C04F00E0C22E /* wifi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FECF1345AC8400AF11D1 /* wifi.cpp */; };
ABB72D4218A493A900EB9AA7 /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB72D4118A493A900EB9AA7 /* OGLDisplayOutput.cpp */; };
ABB72D4318A493A900EB9AA7 /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB72D4118A493A900EB9AA7 /* OGLDisplayOutput.cpp */; };
ABB72D4618A493C000EB9AA7 /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB72D4518A493C000EB9AA7 /* xbrz.cpp */; };
ABB72D4718A493C000EB9AA7 /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB72D4518A493C000EB9AA7 /* xbrz.cpp */; };
ABB97876144E89CC00793FA3 /* Icon_ActionReplay_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = ABB97873144E89CC00793FA3 /* Icon_ActionReplay_32x32.png */; };
ABB97877144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = ABB97874144E89CC00793FA3 /* Icon_CodeBreaker_32x32.png */; };
ABB97878144E89CC00793FA3 /* Icon_DeSmuME_32x32.png in Resources */ = {isa = PBXBuildFile; fileRef = ABB97875144E89CC00793FA3 /* Icon_DeSmuME_32x32.png */; };
@ -931,6 +935,10 @@
ABB3C6401501BB8300E0C22E /* OESoundInterface.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = OESoundInterface.mm; sourceTree = "<group>"; };
ABB3C6411501BB8300E0C22E /* OESoundInterface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OESoundInterface.h; sourceTree = "<group>"; };
ABB3C6471501BC6D00E0C22E /* DeSmuME.oecoreplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DeSmuME.oecoreplugin; sourceTree = BUILT_PRODUCTS_DIR; };
ABB72D4018A493A900EB9AA7 /* OGLDisplayOutput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; };
ABB72D4118A493A900EB9AA7 /* OGLDisplayOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLDisplayOutput.cpp; sourceTree = "<group>"; };
ABB72D4418A493C000EB9AA7 /* xbrz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbrz.h; sourceTree = "<group>"; };
ABB72D4518A493C000EB9AA7 /* xbrz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbrz.cpp; sourceTree = "<group>"; };
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>"; };
@ -1248,6 +1256,7 @@
AB1B9E5F1501A78000464647 /* coreaudiosound.cpp */,
AB23567216C2F6F400DA782E /* macosx_10_5_compat.cpp */,
ABD10AE61715FCDD00B5729D /* mic_ext.cpp */,
ABB72D4118A493A900EB9AA7 /* OGLDisplayOutput.cpp */,
AB1B9E601501A78000464647 /* ringbuffer.cpp */,
ABD104141346652500AF11D1 /* sndOSX.cpp */,
ABD10AE31715FCDD00B5729D /* audiosamplegenerator.h */,
@ -1265,6 +1274,7 @@
ABE5DFE3143FB1DA00835AD8 /* cocoa_videofilter.h */,
AB1B9E611501A78000464647 /* coreaudiosound.h */,
ABD10AE41715FCDD00B5729D /* mic_ext.h */,
ABB72D4018A493A900EB9AA7 /* OGLDisplayOutput.h */,
AB1B9E621501A78000464647 /* ringbuffer.h */,
ABD104011346652500AF11D1 /* sndOSX.h */,
AB82445E1704AEC400B8EE20 /* utilities.h */,
@ -1902,12 +1912,14 @@
ABFE150414C92FF5005D6699 /* lq2x.cpp */,
ABFE150614C92FF5005D6699 /* scanline.cpp */,
AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */,
ABB72D4518A493C000EB9AA7 /* xbrz.cpp */,
ABFE14FD14C92FF5005D6699 /* filter.h */,
ABFE14FF14C92FF5005D6699 /* hq2x.h */,
ABFE150214C92FF5005D6699 /* hq4x.h */,
ABFE150314C92FF5005D6699 /* interp.h */,
ABFE150514C92FF5005D6699 /* lq2x.h */,
AB817A34143EE2DB00A7DFE9 /* videofilter.h */,
ABB72D4418A493C000EB9AA7 /* xbrz.h */,
);
name = filter;
path = ../filter;
@ -2311,6 +2323,7 @@
ABD1FED31345AC8400AF11D1 /* armcpu.cpp in Sources */,
ABD1FED41345AC8400AF11D1 /* bios.cpp in Sources */,
ABD1FF5B1345ACBF00AF11D1 /* cache.cpp in Sources */,
ABB72D4318A493A900EB9AA7 /* OGLDisplayOutput.cpp in Sources */,
ABD1FED51345AC8400AF11D1 /* cheatSystem.cpp in Sources */,
ABD1FED71345AC8400AF11D1 /* common.cpp in Sources */,
ABD1FED81345AC8400AF11D1 /* cp15.cpp in Sources */,
@ -2424,6 +2437,7 @@
AB405634169F5DBB0016AC3E /* compiler.cpp in Sources */,
AB405637169F5DBB0016AC3E /* compilercontext.cpp in Sources */,
AB40563A169F5DBB0016AC3E /* compilerfunc.cpp in Sources */,
ABB72D4718A493C000EB9AA7 /* xbrz.cpp in Sources */,
AB40563D169F5DBB0016AC3E /* compileritem.cpp in Sources */,
AB405640169F5DBB0016AC3E /* context.cpp in Sources */,
AB405643169F5DBB0016AC3E /* cpuinfo.cpp in Sources */,
@ -2550,6 +2564,7 @@
AB796D3515CDCBA200C59155 /* sndOSX.cpp in Sources */,
AB796D3615CDCBA200C59155 /* SndOut.cpp in Sources */,
AB796D3715CDCBA200C59155 /* SoundTouch.cpp in Sources */,
ABB72D4618A493C000EB9AA7 /* xbrz.cpp in Sources */,
AB796D3815CDCBA200C59155 /* SPU.cpp in Sources */,
AB796D3915CDCBA200C59155 /* sse_optimized.cpp in Sources */,
AB796D3A15CDCBA200C59155 /* task.cpp in Sources */,
@ -2583,6 +2598,7 @@
AB796D5A15CDCBA200C59155 /* preferencesWindowDelegate.mm in Sources */,
AB796D5B15CDCBA200C59155 /* 2xsai.cpp in Sources */,
AB796D5C15CDCBA200C59155 /* bilinear.cpp in Sources */,
ABB72D4218A493A900EB9AA7 /* OGLDisplayOutput.cpp in Sources */,
AB796D5D15CDCBA200C59155 /* epx.cpp in Sources */,
AB796D5E15CDCBA200C59155 /* hq2x.cpp in Sources */,
AB796D5F15CDCBA200C59155 /* hq4x.cpp in Sources */,

View File

@ -195,6 +195,8 @@
AB405694169F5DCC0016AC3E /* x86util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB405676169F5DCC0016AC3E /* x86util.cpp */; };
AB405695169F5DCC0016AC3E /* x86util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB405676169F5DCC0016AC3E /* x86util.cpp */; };
AB4676F314AB12D60002FF94 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = AB0A0D1914AACA9600E83E91 /* libz.dylib */; };
AB47B52E18A3F722009A42AF /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB47B52C18A3F722009A42AF /* xbrz.cpp */; };
AB47B52F18A45C35009A42AF /* xbrz.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AB47B52C18A3F722009A42AF /* xbrz.cpp */; };
AB4FCEBD1692AB82000F498F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB4FCEBC1692AB82000F498F /* Accelerate.framework */; };
AB4FCEBE1692AB82000F498F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB4FCEBC1692AB82000F498F /* Accelerate.framework */; };
AB4FCEBF1692AB82000F498F /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB4FCEBC1692AB82000F498F /* Accelerate.framework */; };
@ -683,6 +685,8 @@
ABE6702C1415DE6C00E8E4C9 /* tinyxml.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE670271415DE6C00E8E4C9 /* tinyxml.cpp */; };
ABE6702D1415DE6C00E8E4C9 /* tinyxmlerror.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE670291415DE6C00E8E4C9 /* tinyxmlerror.cpp */; };
ABE6702E1415DE6C00E8E4C9 /* tinyxmlparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE6702A1415DE6C00E8E4C9 /* tinyxmlparser.cpp */; };
ABE6840C189E33BC007FD69C /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE6840B189E33BC007FD69C /* OGLDisplayOutput.cpp */; };
ABE6840D189E33BC007FD69C /* OGLDisplayOutput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABE6840B189E33BC007FD69C /* OGLDisplayOutput.cpp */; };
ABE7F53E13EE1C7900FD3A71 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; };
ABE9EEEA1501C6EB00D3FB19 /* cocoa_firmware.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */; };
ABE9EEEB1501C78700D3FB19 /* fs-linux.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FEB21345AC8400AF11D1 /* fs-linux.cpp */; };
@ -864,6 +868,8 @@
AB405675169F5DCC0016AC3E /* x86operand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x86operand.h; sourceTree = "<group>"; };
AB405676169F5DCC0016AC3E /* x86util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = x86util.cpp; sourceTree = "<group>"; };
AB405677169F5DCC0016AC3E /* x86util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = x86util.h; sourceTree = "<group>"; };
AB47B52B18A3F722009A42AF /* xbrz.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xbrz.h; sourceTree = "<group>"; };
AB47B52C18A3F722009A42AF /* xbrz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xbrz.cpp; sourceTree = "<group>"; };
AB4FCEBC1692AB82000F498F /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
AB5648FD186E6EA8002740F4 /* cocoa_slot2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_slot2.h; sourceTree = "<group>"; };
AB5648FE186E6EA8002740F4 /* cocoa_slot2.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_slot2.mm; sourceTree = "<group>"; };
@ -1159,6 +1165,8 @@
ABE670281415DE6C00E8E4C9 /* tinyxml.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml.h; sourceTree = "<group>"; };
ABE670291415DE6C00E8E4C9 /* tinyxmlerror.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlerror.cpp; sourceTree = "<group>"; };
ABE6702A1415DE6C00E8E4C9 /* tinyxmlparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyxmlparser.cpp; sourceTree = "<group>"; };
ABE6840B189E33BC007FD69C /* OGLDisplayOutput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGLDisplayOutput.cpp; sourceTree = "<group>"; };
ABE6840E189E33D5007FD69C /* OGLDisplayOutput.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OGLDisplayOutput.h; sourceTree = "<group>"; };
ABE7F53C13EE1C7900FD3A71 /* cocoa_firmware.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cocoa_firmware.h; sourceTree = "<group>"; };
ABE7F53D13EE1C7900FD3A71 /* cocoa_firmware.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = cocoa_firmware.mm; sourceTree = "<group>"; };
ABEFCF5D141AB82A000CC0CD /* AppIcon_ROMSave.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = AppIcon_ROMSave.icns; sourceTree = "<group>"; };
@ -1247,6 +1255,7 @@
AB1B9E5F1501A78000464647 /* coreaudiosound.cpp */,
AB23567216C2F6F400DA782E /* macosx_10_5_compat.cpp */,
ABD10AE61715FCDD00B5729D /* mic_ext.cpp */,
ABE6840B189E33BC007FD69C /* OGLDisplayOutput.cpp */,
AB1B9E601501A78000464647 /* ringbuffer.cpp */,
ABD104141346652500AF11D1 /* sndOSX.cpp */,
ABD10AE31715FCDD00B5729D /* audiosamplegenerator.h */,
@ -1265,6 +1274,7 @@
AB1B9E611501A78000464647 /* coreaudiosound.h */,
ABD10AE41715FCDD00B5729D /* mic_ext.h */,
AB1B9E621501A78000464647 /* ringbuffer.h */,
ABE6840E189E33D5007FD69C /* OGLDisplayOutput.h */,
ABD104011346652500AF11D1 /* sndOSX.h */,
AB82445E1704AEC400B8EE20 /* utilities.h */,
ABA6574A14511EC90077E5E9 /* cocoa_cheat.mm */,
@ -1901,12 +1911,14 @@
ABFE150414C92FF5005D6699 /* lq2x.cpp */,
ABFE150614C92FF5005D6699 /* scanline.cpp */,
AB817A35143EE2DB00A7DFE9 /* videofilter.cpp */,
AB47B52C18A3F722009A42AF /* xbrz.cpp */,
ABFE14FD14C92FF5005D6699 /* filter.h */,
ABFE14FF14C92FF5005D6699 /* hq2x.h */,
ABFE150214C92FF5005D6699 /* hq4x.h */,
ABFE150314C92FF5005D6699 /* interp.h */,
ABFE150514C92FF5005D6699 /* lq2x.h */,
AB817A34143EE2DB00A7DFE9 /* videofilter.h */,
AB47B52B18A3F722009A42AF /* xbrz.h */,
);
name = filter;
path = ../filter;
@ -2371,6 +2383,7 @@
ABD1FF0F1345AC9C00AF11D1 /* slot2_gbagame.cpp in Sources */,
ABD1FF101345AC9C00AF11D1 /* slot2_guitarGrip.cpp in Sources */,
ABD1FF111345AC9C00AF11D1 /* slot2_mpcf.cpp in Sources */,
ABE6840D189E33BC007FD69C /* OGLDisplayOutput.cpp in Sources */,
ABD1FF121345AC9C00AF11D1 /* slot2_none.cpp in Sources */,
ABD1FF131345AC9C00AF11D1 /* slot2_paddle.cpp in Sources */,
ABD1FF141345AC9C00AF11D1 /* slot2_piano.cpp in Sources */,
@ -2423,6 +2436,7 @@
ABFE150B14C92FF5005D6699 /* hq4x.cpp in Sources */,
AB9038A717C5ECFD00F410BD /* advanscene.cpp in Sources */,
ABFE150D14C92FF5005D6699 /* lq2x.cpp in Sources */,
AB47B52E18A3F722009A42AF /* xbrz.cpp in Sources */,
ABFE150E14C92FF5005D6699 /* scanline.cpp in Sources */,
AB1B9E631501A78000464647 /* coreaudiosound.cpp in Sources */,
AB1B9E661501A78000464647 /* ringbuffer.cpp in Sources */,
@ -2547,7 +2561,9 @@
AB5648FF186E6EA8002740F4 /* cocoa_slot2.mm in Sources */,
AB796D2A15CDCBA200C59155 /* slot1_r4.cpp in Sources */,
AB796D2C15CDCBA200C59155 /* slot1_retail_nand.cpp in Sources */,
ABE6840C189E33BC007FD69C /* OGLDisplayOutput.cpp in Sources */,
AB796D2D15CDCBA200C59155 /* slot2_expMemory.cpp in Sources */,
AB47B52F18A45C35009A42AF /* xbrz.cpp in Sources */,
AB796D2E15CDCBA200C59155 /* slot2_gbagame.cpp in Sources */,
AB796D2F15CDCBA200C59155 /* slot2_guitarGrip.cpp in Sources */,
AB796D3015CDCBA200C59155 /* slot2_mpcf.cpp in Sources */,

View File

@ -0,0 +1,668 @@
/*
Copyright (C) 2014 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 "OGLDisplayOutput.h"
#include "cocoa_globals.h"
#include "utilities.h"
#include "../filter/videofilter.h"
// VERTEX SHADER FOR DISPLAY OUTPUT
static const char *vertexProgram_100 = {"\
attribute vec2 inPosition; \n\
attribute vec2 inTexCoord0; \n\
\n\
uniform vec2 viewSize; \n\
uniform float scalar; \n\
uniform float angleDegrees; \n\
\n\
varying vec2 vtxTexCoord; \n\
\n\
void main() \n\
{ \n\
float angleRadians = radians(angleDegrees); \n\
\n\
mat2 projection = mat2( vec2(2.0/viewSize.x, 0.0), \n\
vec2( 0.0, 2.0/viewSize.y)); \n\
\n\
mat2 rotation = mat2( vec2(cos(angleRadians), -sin(angleRadians)), \n\
vec2(sin(angleRadians), cos(angleRadians))); \n\
\n\
mat2 scale = mat2( vec2(scalar, 0.0), \n\
vec2( 0.0, scalar)); \n\
\n\
vtxTexCoord = inTexCoord0; \n\
gl_Position = vec4(projection * rotation * scale * inPosition, 1.0, 1.0); \n\
} \n\
"};
// FRAGMENT SHADER FOR DISPLAY OUTPUT
static const char *fragmentProgram_100 = {"\
varying vec2 vtxTexCoord; \n\
uniform sampler2D tex; \n\
\n\
void main() \n\
{ \n\
gl_FragColor = texture2D(tex, vtxTexCoord); \n\
} \n\
"};
enum OGLVertexAttributeID
{
OGLVertexAttributeID_Position = 0,
OGLVertexAttributeID_TexCoord0 = 8
};
OGLVideoOutput::OGLVideoOutput()
{
_gapScalar = 0.0f;
_normalWidth = GPU_DISPLAY_WIDTH;
_normalHeight = GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*_gapScalar);
_displayMode = DS_DISPLAY_TYPE_DUAL;
_displayOrder = DS_DISPLAY_ORDER_MAIN_FIRST;
_displayOrientation = DS_DISPLAY_ORIENTATION_VERTICAL;
_rotation = 0.0f;
_displayTexFilter = GL_NEAREST;
_glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
_glTexBackWidth = GetNearestPositivePOT((uint32_t)_normalWidth);
_glTexBackHeight = GetNearestPositivePOT((uint32_t)_normalHeight);
_glTexBack = (GLvoid *)calloc(_glTexBackWidth * _glTexBackHeight, sizeof(uint16_t));
_vfSingle = new VideoFilter(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT, VideoFilterTypeID_None, 0);
_vfDual = new VideoFilter(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2, VideoFilterTypeID_None, 2);
_vf = _vfDual;
UpdateVertices();
UpdateTexCoords(1.0f, 2.0f);
_vtxBufferOffset = 0;
// Set up initial vertex elements
vtxIndexBuffer[0] = 0; vtxIndexBuffer[1] = 1; vtxIndexBuffer[2] = 2;
vtxIndexBuffer[3] = 2; vtxIndexBuffer[4] = 3; vtxIndexBuffer[5] = 0;
vtxIndexBuffer[6] = 4; vtxIndexBuffer[7] = 5; vtxIndexBuffer[8] = 6;
vtxIndexBuffer[9] = 6; vtxIndexBuffer[10] = 7; vtxIndexBuffer[11] = 4;
}
OGLVideoOutput::~OGLVideoOutput()
{
free(_glTexBack);
delete _vfSingle;
delete _vfDual;
_vf = NULL;
}
void OGLVideoOutput::InitializeOGL()
{
// Check the OpenGL capabilities for this renderer
std::set<std::string> oglExtensionSet;
GetExtensionSetOGL(&oglExtensionSet);
// Set up textures
glGenTextures(1, &this->_displayTexID);
glBindTexture(GL_TEXTURE_2D, this->_displayTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
// Set up shaders (but disable on PowerPC, since it doesn't seem to work there)
#if defined(__i386__) || defined(__x86_64__)
_isShaderSupported = IsExtensionPresent(oglExtensionSet, "GL_ARB_shader_objects") &&
IsExtensionPresent(oglExtensionSet, "GL_ARB_vertex_shader") &&
IsExtensionPresent(oglExtensionSet, "GL_ARB_fragment_shader") &&
IsExtensionPresent(oglExtensionSet, "GL_ARB_vertex_program");
#else
this->_isShaderSupported = false;
#endif
if (this->_isShaderSupported)
{
bool isShaderSetUp = SetupShadersOGL(vertexProgram_100, fragmentProgram_100);
if (isShaderSetUp)
{
glUseProgram(this->_shaderProgram);
this->_uniformAngleDegrees = glGetUniformLocation(this->_shaderProgram, "angleDegrees");
this->_uniformScalar = glGetUniformLocation(this->_shaderProgram, "scalar");
this->_uniformViewSize = glGetUniformLocation(this->_shaderProgram, "viewSize");
glUniform1f(this->_uniformAngleDegrees, 0.0f);
glUniform1f(this->_uniformScalar, 1.0f);
glUniform2f(this->_uniformViewSize, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*this->_gapScalar));
}
else
{
this->_isShaderSupported = false;
}
}
// Set up VBOs
glGenBuffersARB(1, &this->_vboVertexID);
glGenBuffersARB(1, &this->_vboTexCoordID);
glGenBuffersARB(1, &this->_vboElementID);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboVertexID);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLint) * (2 * 8), this->vtxBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLfloat) * (2 * 8), this->texCoordBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->_vboElementID);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLubyte) * 12, this->vtxIndexBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
// Set up VAO
glGenVertexArraysAPPLE(1, &this->_vaoMainStatesID);
glBindVertexArrayAPPLE(this->_vaoMainStatesID);
if (this->_isShaderSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboVertexID);
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_INT, GL_FALSE, 0, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->_vboElementID);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
else
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboVertexID);
glVertexPointer(2, GL_INT, 0, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->_vboElementID);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glBindVertexArrayAPPLE(0);
// Render State Setup (common to both shaders and fixed-function pipeline)
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_DITHER);
glDisable(GL_STENCIL_TEST);
// Set up fixed-function pipeline render states.
if (!_isShaderSupported)
{
glDisable(GL_ALPHA_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glEnable(GL_TEXTURE_2D);
}
// Set up clear attributes
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void OGLVideoOutput::TerminateOGL()
{
glDeleteTextures(1, &this->_displayTexID);
glDeleteVertexArraysAPPLE(1, &this->_vaoMainStatesID);
glDeleteBuffersARB(1, &this->_vboVertexID);
glDeleteBuffersARB(1, &this->_vboTexCoordID);
glDeleteBuffersARB(1, &this->_vboElementID);
if (this->_isShaderSupported)
{
glUseProgram(0);
glDetachShader(this->_shaderProgram, this->_vertexShaderID);
glDetachShader(this->_shaderProgram, this->_fragmentShaderID);
glDeleteProgram(this->_shaderProgram);
glDeleteShader(this->_vertexShaderID);
glDeleteShader(this->_fragmentShaderID);
}
}
int OGLVideoOutput::GetDisplayMode()
{
return this->_displayMode;
}
void OGLVideoOutput::SetDisplayMode(int dispMode)
{
this->_displayMode = dispMode;
this->_vf = (dispMode == DS_DISPLAY_TYPE_DUAL) ? this->_vfDual : this->_vfSingle;
this->CalculateDisplayNormalSize(&this->_normalWidth, &this->_normalHeight);
this->UpdateVertices();
}
int OGLVideoOutput::GetDisplayOrientation()
{
return this->_displayOrientation;
}
void OGLVideoOutput::SetDisplayOrientation(int dispOrientation)
{
this->_displayOrientation = dispOrientation;
this->CalculateDisplayNormalSize(&this->_normalWidth, &this->_normalHeight);
this->UpdateVertices();
}
GLfloat OGLVideoOutput::GetGapScalar()
{
return this->_gapScalar;
}
void OGLVideoOutput::SetGapScalar(GLfloat theScalar)
{
this->_gapScalar = theScalar;
this->CalculateDisplayNormalSize(&this->_normalWidth, &this->_normalHeight);
this->UpdateVertices();
}
GLfloat OGLVideoOutput::GetRotation()
{
return this->_rotation;
}
void OGLVideoOutput::SetRotation(GLfloat theRotation)
{
this->_rotation = theRotation;
}
bool OGLVideoOutput::GetDisplayBilinear()
{
return (this->_displayTexFilter == GL_LINEAR);
}
void OGLVideoOutput::SetDisplayBilinearOGL(bool useBilinear)
{
this->_displayTexFilter = (useBilinear) ? GL_LINEAR : GL_NEAREST;
glBindTexture(GL_TEXTURE_2D, this->_displayTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, this->_displayTexFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, this->_displayTexFilter);
glBindTexture(GL_TEXTURE_2D, 0);
}
int OGLVideoOutput::GetDisplayOrder()
{
return this->_displayOrder;
}
void OGLVideoOutput::SetDisplayOrder(int dispOrder)
{
this->_displayOrder = dispOrder;
if (this->_displayOrder == DS_DISPLAY_ORDER_MAIN_FIRST)
{
this->_vtxBufferOffset = 0;
}
else // dispOrder == DS_DISPLAY_ORDER_TOUCH_FIRST
{
this->_vtxBufferOffset = (2 * 8);
}
}
void OGLVideoOutput::SetViewportSizeOGL(GLsizei w, GLsizei h)
{
this->_viewportWidth = w;
this->_viewportHeight = h;
const CGSize checkSize = GetTransformedBounds(this->_normalWidth, this->_normalHeight, 1.0, this->_rotation);
const GLdouble s = GetMaxScalarInBounds(checkSize.width, checkSize.height, w, h);
glViewport(0, 0, w, h);
if (this->_isShaderSupported)
{
glUniform2f(this->_uniformViewSize, w, h);
glUniform1f(this->_uniformScalar, s);
}
else
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-w/2, -w/2 + w, -h/2, -h/2 + h, -1.0, 1.0);
glRotatef(CLOCKWISE_DEGREES(this->_rotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
}
void OGLVideoOutput::UpdateDisplayTransformationOGL()
{
const CGSize checkSize = GetTransformedBounds(this->_normalWidth, this->_normalHeight, 1.0, this->_rotation);
const GLdouble s = GetMaxScalarInBounds(checkSize.width, checkSize.height, this->_viewportWidth, this->_viewportHeight);
if (this->_isShaderSupported)
{
glUniform1f(this->_uniformAngleDegrees, this->_rotation);
glUniform1f(this->_uniformScalar, s);
}
else
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(this->_rotation), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
}
void OGLVideoOutput::RespondToVideoFilterChangeOGL(const VideoFilterTypeID videoFilterTypeID)
{
this->_vfSingle->ChangeFilterByID(videoFilterTypeID);
this->_vfDual->ChangeFilterByID(videoFilterTypeID);
const GLsizei vfDstWidth = this->_vf->GetDstWidth();
const GLsizei vfDstHeight = (this->_displayMode == DS_DISPLAY_TYPE_DUAL) ? this->_vf->GetDstHeight() : this->_vf->GetDstHeight() * 2;
size_t colorDepth = sizeof(uint32_t);
this->_glTexPixelFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
if (videoFilterTypeID == VideoFilterTypeID_None)
{
colorDepth = sizeof(uint16_t);
this->_glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
}
// Convert textures to Power-of-Two to support older GPUs
// Example: Radeon X1600M on the 2006 MacBook Pro
const GLsizei potW = GetNearestPositivePOT((uint32_t)vfDstWidth);
const GLsizei potH = GetNearestPositivePOT((uint32_t)vfDstHeight);
if (this->_glTexBackWidth != potW || this->_glTexBackHeight != potH)
{
this->_glTexBackWidth = potW;
this->_glTexBackHeight = potH;
free(this->_glTexBack);
this->_glTexBack = (GLvoid *)calloc((size_t)potW * (size_t)potH, colorDepth);
if (this->_glTexBack == NULL)
{
return;
}
}
const GLfloat s = (GLfloat)vfDstWidth / (GLfloat)potW;
const GLfloat t = (GLfloat)vfDstHeight / (GLfloat)potH;
this->UpdateTexCoords(s, t);
glBindTexture(GL_TEXTURE_2D, this->_displayTexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)potW, (GLsizei)potH, 0, GL_BGRA, this->_glTexPixelFormat, this->_glTexBack);
glBindTexture(GL_TEXTURE_2D, 0);
this->UploadTexCoordsOGL();
}
void OGLVideoOutput::CalculateDisplayNormalSize(double *w, double *h)
{
if (w == NULL || h == NULL)
{
return;
}
if (this->_displayMode != DS_DISPLAY_TYPE_DUAL)
{
*w = GPU_DISPLAY_WIDTH;
*h = GPU_DISPLAY_HEIGHT;
return;
}
if (this->_displayOrientation == DS_DISPLAY_ORIENTATION_VERTICAL)
{
*w = GPU_DISPLAY_WIDTH;
*h = GPU_DISPLAY_HEIGHT * 2.0 + (DS_DISPLAY_GAP * this->_gapScalar);
}
else
{
*w = GPU_DISPLAY_WIDTH * 2.0 + (DS_DISPLAY_GAP * this->_gapScalar);
*h = GPU_DISPLAY_HEIGHT;
}
}
void OGLVideoOutput::GetExtensionSetOGL(std::set<std::string> *oglExtensionSet)
{
std::string oglExtensionString = std::string((const char *)glGetString(GL_EXTENSIONS));
size_t extStringStartLoc = 0;
size_t delimiterLoc = oglExtensionString.find_first_of(' ', extStringStartLoc);
while (delimiterLoc != std::string::npos)
{
std::string extensionName = oglExtensionString.substr(extStringStartLoc, delimiterLoc - extStringStartLoc);
oglExtensionSet->insert(extensionName);
extStringStartLoc = delimiterLoc + 1;
delimiterLoc = oglExtensionString.find_first_of(' ', extStringStartLoc);
}
if (extStringStartLoc - oglExtensionString.length() > 0)
{
std::string extensionName = oglExtensionString.substr(extStringStartLoc, oglExtensionString.length() - extStringStartLoc);
oglExtensionSet->insert(extensionName);
}
}
bool OGLVideoOutput::IsExtensionPresent(const std::set<std::string> &oglExtensionSet, const std::string &extensionName) const
{
if (oglExtensionSet.size() == 0)
{
return false;
}
return (oglExtensionSet.find(extensionName) != oglExtensionSet.end());
}
bool OGLVideoOutput::SetupShadersOGL(const char *vertexProgram, const char *fragmentProgram)
{
bool result = false;
GLint shaderStatus = GL_TRUE;
this->_vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if (this->_vertexShaderID == 0)
{
printf("OpenGL Error - Failed to create vertex shader.");
return result;
}
glShaderSource(this->_vertexShaderID, 1, (const GLchar **)&vertexProgram, NULL);
glCompileShader(this->_vertexShaderID);
glGetShaderiv(this->_vertexShaderID, GL_COMPILE_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE)
{
glDeleteShader(this->_vertexShaderID);
printf("OpenGL Error - Failed to compile vertex shader.");
return result;
}
this->_fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (this->_fragmentShaderID == 0)
{
glDeleteShader(this->_vertexShaderID);
printf("OpenGL Error - Failed to create fragment shader.");
return result;
}
glShaderSource(this->_fragmentShaderID, 1, (const GLchar **)&fragmentProgram, NULL);
glCompileShader(this->_fragmentShaderID);
glGetShaderiv(this->_fragmentShaderID, GL_COMPILE_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE)
{
glDeleteShader(this->_vertexShaderID);
glDeleteShader(this->_fragmentShaderID);
printf("OpenGL Error - Failed to compile fragment shader.");
return result;
}
this->_shaderProgram = glCreateProgram();
if (this->_shaderProgram == 0)
{
glDeleteShader(this->_vertexShaderID);
glDeleteShader(this->_fragmentShaderID);
printf("OpenGL Error - Failed to create shader program.");
return result;
}
glAttachShader(this->_shaderProgram, this->_vertexShaderID);
glAttachShader(this->_shaderProgram, this->_fragmentShaderID);
this->SetupShaderIO_OGL();
glLinkProgram(this->_shaderProgram);
glGetProgramiv(this->_shaderProgram, GL_LINK_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE)
{
glDeleteProgram(this->_shaderProgram);
glDeleteShader(this->_vertexShaderID);
glDeleteShader(this->_fragmentShaderID);
printf("OpenGL Error - Failed to link shader program.");
return result;
}
glValidateProgram(this->_shaderProgram);
result = true;
return result;
}
void OGLVideoOutput::SetupShaderIO_OGL()
{
glBindAttribLocation(this->_shaderProgram, OGLVertexAttributeID_Position, "inPosition");
glBindAttribLocation(this->_shaderProgram, OGLVertexAttributeID_TexCoord0, "inTexCoord0");
}
void OGLVideoOutput::UploadVerticesOGL()
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboVertexID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(GLint) * (2 * 8), this->vtxBuffer + this->_vtxBufferOffset);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
void OGLVideoOutput::UploadTexCoordsOGL()
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->_vboTexCoordID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(GLfloat) * (2 * 8), this->texCoordBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
void OGLVideoOutput::UploadDisplayTextureOGL(const GLvoid *textureData, GLsizei texWidth, GLsizei texHeight)
{
if (textureData == NULL)
{
return;
}
const GLint lineOffset = (this->_displayMode == DS_DISPLAY_TYPE_TOUCH) ? texHeight : 0;
glBindTexture(GL_TEXTURE_2D, this->_displayTexID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lineOffset, texWidth, texHeight, GL_RGBA, this->_glTexPixelFormat, textureData);
glBindTexture(GL_TEXTURE_2D, 0);
}
void OGLVideoOutput::UpdateVertices()
{
const GLfloat w = GPU_DISPLAY_WIDTH;
const GLfloat h = GPU_DISPLAY_HEIGHT;
const GLfloat gap = DS_DISPLAY_GAP * this->_gapScalar / 2.0;
if (this->_displayMode == DS_DISPLAY_TYPE_DUAL)
{
// displayOrder == DS_DISPLAY_ORDER_MAIN_FIRST
if (this->_displayOrientation == DS_DISPLAY_ORIENTATION_VERTICAL)
{
vtxBuffer[0] = -w/2; vtxBuffer[1] = h+gap; // Top display, top left
vtxBuffer[2] = w/2; vtxBuffer[3] = h+gap; // Top display, top right
vtxBuffer[4] = w/2; vtxBuffer[5] = gap; // Top display, bottom right
vtxBuffer[6] = -w/2; vtxBuffer[7] = gap; // Top display, bottom left
vtxBuffer[8] = -w/2; vtxBuffer[9] = -gap; // Bottom display, top left
vtxBuffer[10] = w/2; vtxBuffer[11] = -gap; // Bottom display, top right
vtxBuffer[12] = w/2; vtxBuffer[13] = -(h+gap); // Bottom display, bottom right
vtxBuffer[14] = -w/2; vtxBuffer[15] = -(h+gap); // Bottom display, bottom left
}
else // displayOrientationID == DS_DISPLAY_ORIENTATION_HORIZONTAL
{
vtxBuffer[0] = -(w+gap); vtxBuffer[1] = h/2; // Left display, top left
vtxBuffer[2] = -gap; vtxBuffer[3] = h/2; // Left display, top right
vtxBuffer[4] = -gap; vtxBuffer[5] = -h/2; // Left display, bottom right
vtxBuffer[6] = -(w+gap); vtxBuffer[7] = -h/2; // Left display, bottom left
vtxBuffer[8] = gap; vtxBuffer[9] = h/2; // Right display, top left
vtxBuffer[10] = w+gap; vtxBuffer[11] = h/2; // Right display, top right
vtxBuffer[12] = w+gap; vtxBuffer[13] = -h/2; // Right display, bottom right
vtxBuffer[14] = gap; vtxBuffer[15] = -h/2; // Right display, bottom left
}
// displayOrder == DS_DISPLAY_ORDER_TOUCH_FIRST
memcpy(vtxBuffer + (2 * 8), vtxBuffer + (1 * 8), sizeof(GLint) * (1 * 8));
memcpy(vtxBuffer + (3 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (1 * 8));
}
else // displayModeID == DS_DISPLAY_TYPE_MAIN || displayModeID == DS_DISPLAY_TYPE_TOUCH
{
vtxBuffer[0] = -w/2; vtxBuffer[1] = h/2; // First display, top left
vtxBuffer[2] = w/2; vtxBuffer[3] = h/2; // First display, top right
vtxBuffer[4] = w/2; vtxBuffer[5] = -h/2; // First display, bottom right
vtxBuffer[6] = -w/2; vtxBuffer[7] = -h/2; // First display, bottom left
memcpy(vtxBuffer + (1 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (1 * 8)); // Second display
memcpy(vtxBuffer + (2 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (2 * 8)); // Second display
}
}
void OGLVideoOutput::UpdateTexCoords(GLfloat s, GLfloat t)
{
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t/2.0f;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t/2.0f;
texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = t/2.0f;
texCoordBuffer[10] = s; texCoordBuffer[11] = t/2.0f;
texCoordBuffer[12] = s; texCoordBuffer[13] = t;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = t;
}
void OGLVideoOutput::PrerenderOGL(const GLvoid *textureData, GLsizei texWidth, GLsizei texHeight)
{
uint32_t *vfTextureData = (uint32_t *)textureData;
if (this->_vf->GetTypeID() != VideoFilterTypeID_None)
{
RGB555ToRGBA8888Buffer((const uint16_t *)textureData, (uint32_t *)this->_vf->GetSrcBufferPtr(), texWidth * texHeight);
texWidth = this->_vf->GetDstWidth();
texHeight = this->_vf->GetDstHeight();
vfTextureData = this->_vf->RunFilter();
}
this->UploadDisplayTextureOGL(vfTextureData, texWidth, texHeight);
}
void OGLVideoOutput::RenderOGL()
{
// Enable vertex attributes
glBindVertexArrayAPPLE(this->_vaoMainStatesID);
const GLsizei vtxElementCount = (this->_displayMode == DS_DISPLAY_TYPE_DUAL) ? 12 : 6;
const GLubyte *elementPointer = !(this->_displayMode == DS_DISPLAY_TYPE_TOUCH) ? 0 : (GLubyte *)(vtxElementCount * sizeof(GLubyte));
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, this->_displayTexID);
glDrawElements(GL_TRIANGLES, vtxElementCount, GL_UNSIGNED_BYTE, elementPointer);
glBindTexture(GL_TEXTURE_2D, 0);
// Disable vertex attributes
glBindVertexArrayAPPLE(0);
}

View File

@ -0,0 +1,113 @@
/*
Copyright (C) 2014 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 _OGLDISPLAYOUTPUT_H_
#define _OGLDISPLAYOUTPUT_H_
#if defined(__APPLE__)
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#endif
#include <set>
#include <string>
#include "../filter/videofilter.h"
class OGLVideoOutput
{
protected:
VideoFilter *_vfSingle;
VideoFilter *_vfDual;
VideoFilter *_vf;
bool _isShaderSupported;
double _normalWidth;
double _normalHeight;
int _displayMode;
int _displayOrder;
int _displayOrientation;
GLint _displayTexFilter;
GLsizei _viewportWidth;
GLsizei _viewportHeight;
GLfloat _gapScalar;
GLfloat _rotation;
GLenum _glTexPixelFormat;
GLvoid *_glTexBack;
GLsizei _glTexBackWidth;
GLsizei _glTexBackHeight;
GLuint _displayTexID;
GLuint _vboVertexID;
GLuint _vboTexCoordID;
GLuint _vboElementID;
GLuint _vaoMainStatesID;
GLuint _vertexShaderID;
GLuint _fragmentShaderID;
GLuint _shaderProgram;
GLint _uniformAngleDegrees;
GLint _uniformScalar;
GLint _uniformViewSize;
GLint vtxBuffer[4 * 8];
GLfloat texCoordBuffer[2 * 8];
GLubyte vtxIndexBuffer[12];
size_t _vtxBufferOffset;
void GetExtensionSetOGL(std::set<std::string> *oglExtensionSet);
bool IsExtensionPresent(const std::set<std::string> &oglExtensionSet, const std::string &extensionName) const;
bool SetupShadersOGL(const char *vertexProgram, const char *fragmentProgram);
void SetupShaderIO_OGL();
public:
OGLVideoOutput();
~OGLVideoOutput();
virtual void InitializeOGL();
virtual void TerminateOGL();
virtual void UploadVerticesOGL();
virtual void UploadTexCoordsOGL();
virtual void UploadDisplayTextureOGL(const GLvoid *textureData, GLsizei texWidth, GLsizei texHeight);
virtual void PrerenderOGL(const GLvoid *textureData, GLsizei texWidth, GLsizei texHeight);
virtual void RenderOGL();
virtual void SetViewportSizeOGL(GLsizei w, GLsizei h);
virtual void UpdateDisplayTransformationOGL();
virtual void RespondToVideoFilterChangeOGL(const VideoFilterTypeID videoFilterTypeID);
void CalculateDisplayNormalSize(double *w, double *h);
void UpdateVertices();
void UpdateTexCoords(GLfloat s, GLfloat t);
int GetDisplayMode();
void SetDisplayMode(int dispMode);
int GetDisplayOrientation();
void SetDisplayOrientation(int dispOrientation);
GLfloat GetGapScalar();
void SetGapScalar(GLfloat theScalar);
GLfloat GetRotation();
void SetRotation(GLfloat theRotation);
bool GetDisplayBilinear();
void SetDisplayBilinearOGL(bool useBilinear);
int GetDisplayOrder();
void SetDisplayOrder(int dispOrder);
};
#endif // _OGLDISPLAYOUTPUT_H_

View File

@ -428,8 +428,6 @@ enum
MESSAGE_CHANGE_DISPLAY_ORIENTATION,
MESSAGE_CHANGE_DISPLAY_ORDER,
MESSAGE_CHANGE_DISPLAY_GAP,
MESSAGE_CHANGE_BILINEAR_OUTPUT,
MESSAGE_CHANGE_VERTICAL_SYNC,
MESSAGE_CHANGE_VIDEO_FILTER,
MESSAGE_SET_RENDER3D_METHOD,
MESSAGE_SET_RENDER3D_HIGH_PRECISION_COLOR_INTERPOLATION,

View File

@ -120,16 +120,13 @@ typedef struct
@required
- (void) doDisplayModeChanged:(NSInteger)displayModeID;
@property (assign) BOOL isHudEnabled;
@property (assign) BOOL isHudEditingModeEnabled;
@end
@protocol CocoaDSDisplayVideoDelegate <CocoaDSDisplayDelegate>
@required
- (void) doInitVideoOutput:(NSDictionary *)properties;
- (void) doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight;
- (void) doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)frameDisplayMode width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight;
@optional
- (void) doResizeView:(NSRect)rect;
@ -140,7 +137,7 @@ typedef struct
- (void) doDisplayGapChanged:(float)displayGapScalar;
- (void) doBilinearOutputChanged:(BOOL)useBilinear;
- (void) doVerticalSyncChanged:(BOOL)useVerticalSync;
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize;
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID;
@end
@ -151,7 +148,6 @@ typedef struct
NSInteger displayMode;
NSSize frameSize;
OSSpinLock spinlockDelegate;
OSSpinLock spinlockDisplayType;
}
@ -174,25 +170,15 @@ typedef struct
@interface CocoaDSDisplayVideo : CocoaDSDisplay
{
CocoaVideoFilter *vf;
id <CocoaDSDisplayVideoDelegate> videoDelegate;
NSInteger lastDisplayMode;
OSSpinLock spinlockVideoFilterType;
OSSpinLock spinlockVFBuffers;
}
@property (retain) id <CocoaDSDisplayVideoDelegate> delegate;
@property (assign) CocoaVideoFilter *vf;
- (void) handleResizeView:(NSData *)rectData;
- (void) handleTransformView:(NSData *)transformData;
- (void) handleRedrawView;
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData;
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData;
- (void) handleChangeDisplayGap:(NSData *)displayGapScalarData;
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData;
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData;
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData;
@end

View File

@ -513,7 +513,7 @@
@implementation CocoaDSDisplay
@dynamic delegate;
@synthesize delegate;
@dynamic displayMode;
@dynamic frameSize;
@ -525,8 +525,7 @@
{
return self;
}
spinlockDelegate = OS_SPINLOCK_INIT;
spinlockDisplayType = OS_SPINLOCK_INIT;
delegate = nil;
@ -541,41 +540,11 @@
- (void)dealloc
{
self.delegate = nil;
[self setDelegate:nil];
[super dealloc];
}
- (void) setDelegate:(id <CocoaDSDisplayDelegate>)theDelegate
{
OSSpinLockLock(&spinlockDelegate);
if (theDelegate == delegate)
{
OSSpinLockUnlock(&spinlockDelegate);
return;
}
if (theDelegate != nil)
{
[theDelegate retain];
}
[delegate release];
delegate = theDelegate;
OSSpinLockUnlock(&spinlockDelegate);
}
- (id <CocoaDSDisplayDelegate>) delegate
{
OSSpinLockLock(&spinlockDelegate);
id <CocoaDSDisplayDelegate> theDelegate = delegate;
OSSpinLockUnlock(&spinlockDelegate);
return theDelegate;
}
- (void) setDisplayMode:(NSInteger)displayModeID
{
NSString *newDispString = nil;
@ -712,7 +681,7 @@
}
const NSInteger displayModeID = *(NSInteger *)[displayModeData bytes];
self.displayMode = displayModeID;
[self setDisplayMode:displayModeID];
[delegate doDisplayModeChanged:displayModeID];
}
@ -850,8 +819,6 @@
@implementation CocoaDSDisplayVideo
@synthesize vf;
- (id)init
{
self = [super init];
@ -860,21 +827,6 @@
return self;
}
videoDelegate = nil;
lastDisplayMode = DS_DISPLAY_TYPE_DUAL;
spinlockVideoFilterType = OS_SPINLOCK_INIT;
spinlockVFBuffers = OS_SPINLOCK_INIT;
if ([[NSProcessInfo processInfo] activeProcessorCount] >= 2)
{
vf = [[CocoaVideoFilter alloc] initWithSize:frameSize typeID:VideoFilterTypeID_None numberThreads:2];
}
else
{
vf = [[CocoaVideoFilter alloc] initWithSize:frameSize typeID:VideoFilterTypeID_None numberThreads:0];
}
[property setValue:[NSNumber numberWithInteger:(NSInteger)VideoFilterTypeID_None] forKey:@"videoFilterType"];
[property setValue:[CocoaVideoFilter typeStringByID:VideoFilterTypeID_None] forKey:@"videoFilterTypeString"];
@ -883,68 +835,13 @@
- (void)dealloc
{
[vf release];
[super dealloc];
}
- (void) setDelegate:(id <CocoaDSDisplayVideoDelegate>)theDelegate
{
OSSpinLockLock(&spinlockDelegate);
if (theDelegate == videoDelegate)
{
OSSpinLockUnlock(&spinlockDelegate);
return;
}
if (theDelegate != nil)
{
[theDelegate retain];
}
[videoDelegate release];
videoDelegate = theDelegate;
OSSpinLockUnlock(&spinlockDelegate);
[super setDelegate:theDelegate];
}
- (id <CocoaDSDisplayVideoDelegate>) delegate
{
OSSpinLockLock(&spinlockDelegate);
id <CocoaDSDisplayVideoDelegate> theDelegate = videoDelegate;
OSSpinLockUnlock(&spinlockDelegate);
return theDelegate;
}
- (void) setVfType:(NSInteger)videoFilterTypeID
{
OSSpinLockLock(&spinlockVFBuffers);
[vf changeFilter:(VideoFilterTypeID)videoFilterTypeID];
OSSpinLockUnlock(&spinlockVFBuffers);
OSSpinLockLock(&spinlockVideoFilterType);
[property setValue:[NSNumber numberWithInteger:videoFilterTypeID] forKey:@"videoFilterType"];
[property setValue:NSLocalizedString([vf typeString], nil) forKey:@"videoFilterTypeString"];
OSSpinLockUnlock(&spinlockVideoFilterType);
}
- (NSInteger) vfType
{
OSSpinLockLock(&spinlockVideoFilterType);
NSInteger theType = [(NSNumber *)[property valueForKey:@"videoFilterType"] integerValue];
OSSpinLockUnlock(&spinlockVideoFilterType);
return theType;
}
- (void) runThread:(id)object
{
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
[videoDelegate doInitVideoOutput:self.property];
[(id<CocoaDSDisplayVideoDelegate>)delegate doInitVideoOutput:self.property];
[tempPool release];
[super runThread:object];
@ -985,14 +882,6 @@
[self handleChangeDisplayGap:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_CHANGE_BILINEAR_OUTPUT:
[self handleChangeBilinearOutput:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_CHANGE_VERTICAL_SYNC:
[self handleChangeVerticalSync:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_CHANGE_VIDEO_FILTER:
[self handleChangeVideoFilter:[messageComponents objectAtIndex:0]];
break;
@ -1011,134 +900,110 @@
}
const DisplaySrcPixelAttributes attr = *(DisplaySrcPixelAttributes *)[attributesData bytes];
const NSInteger displayModeID = attr.displayModeID;
const NSInteger frameDisplayMode = attr.displayModeID;
const NSInteger frameWidth = attr.width;
const NSInteger frameHeight = attr.height;
// Tell the video delegate to process the video frame with our copied GPU data.
OSSpinLockLock(&spinlockVFBuffers);
if (lastDisplayMode != displayModeID)
{
const NSSize newSrcSize = NSMakeSize((CGFloat)attr.width, (CGFloat)attr.height);
[vf setSourceSize:newSrcSize];
lastDisplayMode = displayModeID;
}
const NSInteger destWidth = (NSInteger)[vf destSize].width;
const NSInteger destHeight = (NSInteger)[vf destSize].height;
if ([vf typeID] == VideoFilterTypeID_None)
{
[videoDelegate doProcessVideoFrame:[mainData bytes] displayMode:displayModeID width:destWidth height:destHeight];
}
else
{
RGB555ToRGBA8888Buffer((const uint16_t *)[mainData bytes], (uint32_t *)[vf srcBufferPtr], [mainData length] / sizeof(UInt16));
const UInt32 *vfDestBuffer = [vf runFilter];
[videoDelegate doProcessVideoFrame:vfDestBuffer displayMode:displayModeID width:destWidth height:destHeight];
}
OSSpinLockUnlock(&spinlockVFBuffers);
[(id<CocoaDSDisplayVideoDelegate>)delegate doProcessVideoFrame:[mainData bytes] displayMode:frameDisplayMode width:frameWidth height:frameHeight];
[super handleEmuFrameProcessed:mainData attributes:attributesData];
}
- (void) handleResizeView:(NSData *)rectData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doResizeView:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doResizeView:)])
{
return;
}
const NSRect resizeRect = *(NSRect *)[rectData bytes];
[videoDelegate doResizeView:resizeRect];
[(id<CocoaDSDisplayVideoDelegate>)delegate doResizeView:resizeRect];
}
- (void) handleTransformView:(NSData *)transformData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doTransformView:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doTransformView:)])
{
return;
}
[videoDelegate doTransformView:(DisplayOutputTransformData *)[transformData bytes]];
[(id<CocoaDSDisplayVideoDelegate>)delegate doTransformView:(DisplayOutputTransformData *)[transformData bytes]];
}
- (void) handleRedrawView
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doRedraw)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doRedraw)])
{
return;
}
[videoDelegate doRedraw];
[(id<CocoaDSDisplayVideoDelegate>)delegate doRedraw];
}
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayOrientationChanged:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrientationChanged:)])
{
return;
}
const NSInteger theOrientation = *(NSInteger *)[displayOrientationIdData bytes];
[videoDelegate doDisplayOrientationChanged:theOrientation];
[(id<CocoaDSDisplayVideoDelegate>)delegate doDisplayOrientationChanged:theOrientation];
}
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayOrderChanged:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrderChanged:)])
{
return;
}
const NSInteger theOrder = *(NSInteger *)[displayOrderIdData bytes];
[videoDelegate doDisplayOrderChanged:theOrder];
[(id<CocoaDSDisplayVideoDelegate>)delegate doDisplayOrderChanged:theOrder];
}
- (void) handleChangeDisplayGap:(NSData *)displayGapScalarData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayGapChanged:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayGapChanged:)])
{
return;
}
const float gapScalar = *(float *)[displayGapScalarData bytes];
[videoDelegate doDisplayGapChanged:gapScalar];
[(id<CocoaDSDisplayVideoDelegate>)delegate doDisplayGapChanged:gapScalar];
}
/*
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doBilinearOutputChanged:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doBilinearOutputChanged:)])
{
return;
}
const BOOL theState = *(BOOL *)[bilinearStateData bytes];
[videoDelegate doBilinearOutputChanged:theState];
[(id<CocoaDSDisplayVideoDelegate>)delegate doBilinearOutputChanged:theState];
[self handleEmuFrameProcessed:self.frameData attributes:self.frameAttributesData];
}
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doVerticalSyncChanged:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doVerticalSyncChanged:)])
{
return;
}
const BOOL theState = *(BOOL *)[verticalSyncStateData bytes];
[videoDelegate doVerticalSyncChanged:theState];
[(id<CocoaDSDisplayVideoDelegate>)delegate doVerticalSyncChanged:theState];
}
*/
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doVideoFilterChanged:frameSize:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doVideoFilterChanged:)])
{
return;
}
const NSInteger theType = *(NSInteger *)[videoFilterTypeIdData bytes];
[self setVfType:theType];
[videoDelegate doVideoFilterChanged:theType frameSize:[vf destSize]];
[(id<CocoaDSDisplayVideoDelegate>)delegate doVideoFilterChanged:theType];
[self handleEmuFrameProcessed:self.frameData attributes:self.frameAttributesData];
}

View File

@ -12,7 +12,6 @@
</object>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
<integer value="9104"/>
<integer value="29"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
@ -1343,6 +1342,42 @@
<reference key="NSMixedImage" ref="678976864"/>
<int key="NSTag">18</int>
</object>
<object class="NSMenuItem" id="776018739">
<reference key="NSMenu" ref="1003123887"/>
<string key="NSTitle">2xBRZ</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="396634170"/>
<reference key="NSMixedImage" ref="678976864"/>
<int key="NSTag">19</int>
</object>
<object class="NSMenuItem" id="83119602">
<reference key="NSMenu" ref="1003123887"/>
<string key="NSTitle">3xBRZ</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="396634170"/>
<reference key="NSMixedImage" ref="678976864"/>
<int key="NSTag">20</int>
</object>
<object class="NSMenuItem" id="145998027">
<reference key="NSMenu" ref="1003123887"/>
<string key="NSTitle">4xBRZ</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="396634170"/>
<reference key="NSMixedImage" ref="678976864"/>
<int key="NSTag">21</int>
</object>
<object class="NSMenuItem" id="863067735">
<reference key="NSMenu" ref="1003123887"/>
<string key="NSTitle">5xBRZ</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
<reference key="NSOnImage" ref="396634170"/>
<reference key="NSMixedImage" ref="678976864"/>
<int key="NSTag">22</int>
</object>
<object class="NSMenuItem" id="472615298">
<reference key="NSMenu" ref="1003123887"/>
<string key="NSTitle">2xSaI</string>
@ -8487,8 +8522,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string key="NSWindowClass">NSWindow</string>
<nil key="NSViewClass"/>
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMaxSize">{1.7976931348623157e+308, 1.7976931348623157e+308}</string>
<object class="NSView" key="NSWindowView" id="663395288">
<reference key="NSNextResponder"/>
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -8581,7 +8617,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
</object>
<string key="NSFrameSize">{300, 108}</string>
<reference key="NSSuperview"/>
<string key="NSReuseIdentifierKey">_NS:122</string>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
@ -8599,7 +8634,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMaxSize">{1.7976931348623157e+308, 1.7976931348623157e+308}</string>
<object class="NSView" key="NSWindowView" id="705283056">
<reference key="NSNextResponder"/>
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -8618,7 +8653,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 14}, {190, 126}}</string>
<reference key="NSSuperview" ref="620417532"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSNumRows">4</int>
@ -8892,7 +8926,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{130, 18}, {224, 21}}</string>
<reference key="NSSuperview" ref="620417532"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="565031755">
<int key="NSCellFlags">612368448</int>
@ -8913,7 +8946,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{476, 11}, {96, 32}}</string>
<reference key="NSSuperview" ref="620417532"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="189809655">
<int key="NSCellFlags">67108864</int>
@ -8935,7 +8967,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{128, 47}, {348, 26}}</string>
<reference key="NSSuperview" ref="620417532"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSliderCell" key="NSCell" id="792766777">
<int key="NSCellFlags">-2080112384</int>
@ -8958,7 +8989,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{479, 56}, {90, 17}}</string>
<reference key="NSSuperview" ref="620417532"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="18475068">
<int key="NSCellFlags">68157504</int>
@ -9037,7 +9067,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{356, 11}, {124, 32}}</string>
<reference key="NSSuperview" ref="620417532"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="1009914712">
<int key="NSCellFlags">67108864</int>
@ -9057,12 +9086,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{1, 1}, {584, 150}}</string>
<reference key="NSSuperview" ref="531436272"/>
<reference key="NSWindow"/>
</object>
</object>
<string key="NSFrame">{{17, 56}, {586, 166}}</string>
<reference key="NSSuperview" ref="705283056"/>
<reference key="NSWindow"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67108864</int>
@ -9086,7 +9113,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{510, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="705283056"/>
<reference key="NSWindow"/>
<int key="NSTag">1</int>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="23472213">
@ -9109,7 +9135,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{414, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="705283056"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="565213794">
<int key="NSCellFlags">67108864</int>
@ -9131,7 +9156,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 230}, {586, 17}}</string>
<reference key="NSSuperview" ref="705283056"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="702563390">
<int key="NSCellFlags">70254657</int>
@ -9148,8 +9172,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
</object>
<string key="NSFrameSize">{620, 267}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMaxSize">{1.7976931348623157e+308, 1.7976931348623157e+308}</string>
@ -15005,7 +15027,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMaxSize">{1.7976931348623157e+308, 1.7976931348623157e+308}</string>
<object class="NSView" key="NSWindowView" id="961953439">
<reference key="NSNextResponder"/>
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -15014,7 +15036,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{14, 12}, {168, 32}}</string>
<reference key="NSSuperview" ref="961953439"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="440705577">
<int key="NSCellFlags">67108864</int>
@ -15036,7 +15057,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{181, 22}, {105, 17}}</string>
<reference key="NSSuperview" ref="961953439"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="930972867">
<int key="NSCellFlags">68157504</int>
@ -15055,7 +15075,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">12</int>
<string key="NSFrame">{{12, 51}, {616, 5}}</string>
<reference key="NSSuperview" ref="961953439"/>
<reference key="NSWindow"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67108864</int>
@ -15078,7 +15097,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{288, 22}, {330, 17}}</string>
<reference key="NSSuperview" ref="961953439"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="712282542">
<int key="NSCellFlags">70254657</int>
@ -15108,7 +15126,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 14}, {260, 128}}</string>
<reference key="NSSuperview" ref="996955280"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSNumRows">5</int>
@ -15394,7 +15411,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{85, 15}, {409, 21}}</string>
<reference key="NSSuperview" ref="996955280"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="284244966">
<int key="NSCellFlags">78643265</int>
@ -15415,7 +15431,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{496, 8}, {96, 32}}</string>
<reference key="NSSuperview" ref="996955280"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="1061428768">
<int key="NSCellFlags">67108864</int>
@ -15437,7 +15452,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{15, 150}, {482, 28}}</string>
<reference key="NSSuperview" ref="996955280"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="535412247">
<int key="NSCellFlags">67108864</int>
@ -15459,7 +15473,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{496, 146}, {96, 32}}</string>
<reference key="NSSuperview" ref="996955280"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="944157190">
<int key="NSCellFlags">67108864</int>
@ -15479,12 +15492,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{1, 1}, {604, 188}}</string>
<reference key="NSSuperview" ref="16720907"/>
<reference key="NSWindow"/>
</object>
</object>
<string key="NSFrame">{{17, 140}, {606, 204}}</string>
<reference key="NSSuperview" ref="961953439"/>
<reference key="NSWindow"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67108864</int>
@ -15530,7 +15541,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{18, 16}, {30, 30}}</string>
<reference key="NSSuperview" ref="952926539"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSImageCell" key="NSCell" id="248957291">
<int key="NSCellFlags">134217728</int>
@ -15549,7 +15559,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">265</int>
<string key="NSFrame">{{50, 18}, {168, 28}}</string>
<reference key="NSSuperview" ref="952926539"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="409285173">
<int key="NSCellFlags">69206017</int>
@ -15568,7 +15577,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">1292</int>
<string key="NSFrame">{{18, 14}, {32, 32}}</string>
<reference key="NSSuperview" ref="952926539"/>
<reference key="NSWindow"/>
<int key="NSpiFlags">28682</int>
<double key="NSMaxValue">100</double>
</object>
@ -15577,7 +15585,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{220, 17}, {201, 26}}</string>
<reference key="NSSuperview" ref="952926539"/>
<reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="224228792">
<int key="NSCellFlags">-2076180416</int>
@ -15685,12 +15692,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{1, 1}, {604, 56}}</string>
<reference key="NSSuperview" ref="219608642"/>
<reference key="NSWindow"/>
</object>
</object>
<string key="NSFrame">{{17, 64}, {606, 72}}</string>
<reference key="NSSuperview" ref="961953439"/>
<reference key="NSWindow"/>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
<int key="NSCellFlags">67108864</int>
@ -15711,8 +15716,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
</object>
<string key="NSFrameSize">{640, 355}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMaxSize">{1.7976931348623157e+308, 1.7976931348623157e+308}</string>
@ -15730,7 +15733,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<nil key="NSUserInterfaceItemIdentifier"/>
<string key="NSWindowContentMaxSize">{1.7976931348623157e+308, 1.7976931348623157e+308}</string>
<object class="NSView" key="NSWindowView" id="894973118">
<reference key="NSNextResponder"/>
<nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -15749,7 +15752,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{188, 304}</string>
<reference key="NSSuperview" ref="25555796"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:1843</string>
<bool key="NSEnabled">YES</bool>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
@ -15759,7 +15761,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">256</int>
<string key="NSFrameSize">{188, 17}</string>
<reference key="NSSuperview" ref="262029771"/>
<reference key="NSWindow"/>
<reference key="NSTableView" ref="566119693"/>
</object>
<object class="_NSCornerView" key="NSCornerView">
@ -15817,7 +15818,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{1, 17}, {188, 304}}</string>
<reference key="NSSuperview" ref="425688478"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="566119693"/>
<string key="NSReuseIdentifierKey">_NS:1841</string>
<reference key="NSDocView" ref="566119693"/>
@ -15829,7 +15829,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{224, 17}, {15, 102}}</string>
<reference key="NSSuperview" ref="425688478"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:1860</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<reference key="NSTarget" ref="425688478"/>
@ -15841,7 +15840,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">-2147483392</int>
<string key="NSFrame">{{1, 306}, {188.95703125, 15}}</string>
<reference key="NSSuperview" ref="425688478"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:1862</string>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSsFlags">1</int>
@ -15858,7 +15856,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{1, 0}, {188, 17}}</string>
<reference key="NSSuperview" ref="425688478"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="887977263"/>
<reference key="NSDocView" ref="887977263"/>
<reference key="NSBGColor" ref="856317944"/>
@ -15867,7 +15864,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{20, 106}, {190, 322}}</string>
<reference key="NSSuperview" ref="894973118"/>
<reference key="NSWindow"/>
<reference key="NSNextKeyView" ref="25555796"/>
<string key="NSReuseIdentifierKey">_NS:1839</string>
<int key="NSsFlags">133682</int>
@ -15895,20 +15891,17 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{3, 4}, {400, 320}}</string>
<reference key="NSSuperview" ref="354392661"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:1109</string>
<string key="NSClassName">NSView</string>
</object>
</object>
<string key="NSFrame">{{1, 1}, {406, 326}}</string>
<reference key="NSSuperview" ref="186085671"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:21</string>
</object>
</object>
<string key="NSFrame">{{215, 102}, {408, 328}}</string>
<reference key="NSSuperview" ref="894973118"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:18</string>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
@ -15933,7 +15926,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{530, 12}, {96, 32}}</string>
<reference key="NSSuperview" ref="894973118"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:610</string>
<bool key="NSEnabled">YES</bool>
<object class="NSButtonCell" key="NSCell" id="915735608">
@ -15967,7 +15959,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<int key="NSvFlags">268</int>
<string key="NSFrame">{{15, 14}, {482, 42}}</string>
<reference key="NSSuperview" ref="200748973"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:3939</string>
<bool key="NSEnabled">YES</bool>
<object class="NSTextFieldCell" key="NSCell" id="662435237">
@ -15987,13 +15978,11 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<string key="NSFrame">{{1, 1}, {512, 66}}</string>
<reference key="NSSuperview" ref="83748336"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:21</string>
</object>
</object>
<string key="NSFrame">{{17, 16}, {514, 82}}</string>
<reference key="NSSuperview" ref="894973118"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:18</string>
<string key="NSOffsets">{0, 0}</string>
<object class="NSTextFieldCell" key="NSTitleCell">
@ -16015,8 +16004,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
</object>
<string key="NSFrameSize">{640, 448}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:122</string>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
@ -19884,7 +19871,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<object class="NSWindowTemplate" id="1037714331">
<int key="NSWindowStyleMask">279</int>
<int key="NSWindowBacking">2</int>
<string key="NSWindowRect">{{1004, 215}, {204, 521}}</string>
<string key="NSWindowRect">{{1004, 135}, {204, 601}}</string>
<int key="NSWTFlags">-461896704</int>
<string key="NSWindowTitle">Set Video Output</string>
<string key="NSWindowClass">NSPanel</string>
@ -19930,12 +19917,12 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<object class="NSMatrix" id="807791156">
<reference key="NSNextResponder" ref="36717965"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{18, 14}, {129, 378}}</string>
<string key="NSFrame">{{18, 14}, {132, 458}}</string>
<reference key="NSSuperview" ref="36717965"/>
<reference key="NSNextKeyView" ref="670018968"/>
<bool key="NSEnabled">YES</bool>
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
<int key="NSNumRows">19</int>
<int key="NSNumRows">23</int>
<int key="NSNumCols">1</int>
<object class="NSMutableArray" key="NSCells">
<bool key="EncodedWithXMLCoder">YES</bool>
@ -20169,6 +20156,62 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<object class="NSButtonCell" id="989723426">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">2xBRZ</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">19</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="31989988">
<int key="NSCellFlags">1140850688</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">3xBRZ</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">20</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="809818802">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">4xBRZ</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">21</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="863635465">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">5xBRZ</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">22</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="1004225907">
<int key="NSCellFlags">1140850688</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">2xSaI</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
@ -20180,8 +20223,8 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="31989988">
<int key="NSCellFlags">1140850688</int>
<object class="NSButtonCell" id="338954373">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Super 2xSaI</string>
<reference key="NSSupport" ref="26"/>
@ -20194,7 +20237,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="809818802">
<object class="NSButtonCell" id="188640664">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Super Eagle</string>
@ -20208,7 +20251,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="863635465">
<object class="NSButtonCell" id="134108895">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Scanline</string>
@ -20222,8 +20265,8 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="1004225907">
<int key="NSCellFlags">1140850688</int>
<object class="NSButtonCell" id="1009745071">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Bilinear</string>
<reference key="NSSupport" ref="26"/>
@ -20236,7 +20279,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="338954373">
<object class="NSButtonCell" id="385829730">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Nearest 2x</string>
@ -20250,7 +20293,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="188640664">
<object class="NSButtonCell" id="454811629">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Nearest 1.5x</string>
@ -20259,62 +20302,6 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSTag">12</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="134108895">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Nearest+ 1.5x</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">13</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="1009745071">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">14</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="385829730">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX+</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">15</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSNormalImage" ref="62036590"/>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="454811629">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX 1.5x</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">16</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<object class="NSImage" key="NSNormalImage">
<int key="NSImageFlags">12779520</int>
<object class="NSMutableArray" key="NSReps">
@ -20354,6 +20341,58 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="94235884">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">Nearest+ 1.5x</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">13</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="357679618">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">14</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="689486251">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX+</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">15</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="944146258">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX 1.5x</string>
<reference key="NSSupport" ref="26"/>
<reference key="NSControlView" ref="807791156"/>
<int key="NSTag">16</int>
<int key="NSButtonFlags">1211912448</int>
<int key="NSButtonFlags2">0</int>
<reference key="NSAlternateImage" ref="491083016"/>
<int key="NSPeriodicDelay">400</int>
<int key="NSPeriodicInterval">75</int>
</object>
<object class="NSButtonCell" id="828488894">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">131072</int>
<string key="NSContents">EPX+ 1.5x</string>
@ -20367,7 +20406,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA</bytes>
<int key="NSPeriodicInterval">75</int>
</object>
</object>
<string key="NSCellSize">{129, 18}</string>
<string key="NSCellSize">{132, 18}</string>
<string key="NSIntercellSpacing">{4, 2}</string>
<int key="NSMatrixFlags">1151868928</int>
<string key="NSCellClass">NSActionCell</string>
@ -20482,12 +20521,12 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<reference key="NSFont" ref="462791774"/>
</object>
</object>
<string key="NSFrame">{{1, 1}, {168, 402}}</string>
<string key="NSFrame">{{1, 1}, {168, 482}}</string>
<reference key="NSSuperview" ref="197231888"/>
<reference key="NSNextKeyView" ref="807791156"/>
</object>
</object>
<string key="NSFrame">{{17, 41}, {170, 418}}</string>
<string key="NSFrame">{{17, 41}, {170, 498}}</string>
<reference key="NSSuperview" ref="440584564"/>
<reference key="NSNextKeyView" ref="36717965"/>
<string key="NSOffsets">{0, 0}</string>
@ -20511,7 +20550,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<object class="NSButton" id="309436516">
<reference key="NSNextResponder" ref="440584564"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 485}, {169, 18}}</string>
<string key="NSFrame">{{17, 565}, {169, 18}}</string>
<reference key="NSSuperview" ref="440584564"/>
<reference key="NSNextKeyView" ref="824878810"/>
<bool key="NSEnabled">YES</bool>
@ -20535,7 +20574,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<object class="NSButton" id="824878810">
<reference key="NSNextResponder" ref="440584564"/>
<int key="NSvFlags">268</int>
<string key="NSFrame">{{17, 465}, {135, 18}}</string>
<string key="NSFrame">{{17, 545}, {135, 18}}</string>
<reference key="NSSuperview" ref="440584564"/>
<reference key="NSNextKeyView" ref="197231888"/>
<bool key="NSEnabled">YES</bool>
@ -20557,7 +20596,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<bool key="NSAllowsLogicalLayoutDirection">NO</bool>
</object>
</object>
<string key="NSFrameSize">{204, 521}</string>
<string key="NSFrameSize">{204, 601}</string>
<reference key="NSNextKeyView" ref="309436516"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1440, 878}}</string>
@ -38037,6 +38076,38 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<int key="connectionID">9119</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">changeVideoFilter:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="776018739"/>
</object>
<int key="connectionID">9130</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">changeVideoFilter:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="83119602"/>
</object>
<int key="connectionID">9132</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">changeVideoFilter:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="145998027"/>
</object>
<int key="connectionID">9134</int>
</object>
<object class="IBConnectionRecord">
<object class="IBActionConnection" key="connection">
<string key="label">changeVideoFilter:</string>
<reference key="source" ref="1014"/>
<reference key="destination" ref="863067735"/>
</object>
<int key="connectionID">9136</int>
</object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@ -41397,7 +41468,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<bool key="EncodedWithXMLCoder">YES</bool>
<reference ref="406038934"/>
<reference ref="266817043"/>
<reference ref="307101671"/>
<reference ref="1020424148"/>
<reference ref="617951998"/>
<reference ref="976048887"/>
@ -41415,6 +41485,11 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<reference ref="385829730"/>
<reference ref="454811629"/>
<reference ref="94235884"/>
<reference ref="357679618"/>
<reference ref="689486251"/>
<reference ref="944146258"/>
<reference ref="828488894"/>
<reference ref="307101671"/>
</object>
<reference key="parent" ref="197231888"/>
</object>
@ -41428,11 +41503,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<reference key="object" ref="266817043"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3665</int>
<reference key="object" ref="307101671"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3664</int>
<reference key="object" ref="1020424148"/>
@ -49382,6 +49452,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<reference ref="597449564"/>
<reference ref="83352345"/>
<reference ref="670198780"/>
<reference ref="776018739"/>
<reference ref="83119602"/>
<reference ref="145998027"/>
<reference ref="863067735"/>
</object>
<reference key="parent" ref="920883390"/>
</object>
@ -51284,6 +51358,51 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<reference key="object" ref="567261011"/>
<reference key="parent" ref="361536114"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9124</int>
<reference key="object" ref="357679618"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9125</int>
<reference key="object" ref="689486251"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9126</int>
<reference key="object" ref="944146258"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9127</int>
<reference key="object" ref="828488894"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">3665</int>
<reference key="object" ref="307101671"/>
<reference key="parent" ref="807791156"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9129</int>
<reference key="object" ref="776018739"/>
<reference key="parent" ref="1003123887"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9131</int>
<reference key="object" ref="83119602"/>
<reference key="parent" ref="1003123887"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9133</int>
<reference key="object" ref="145998027"/>
<reference key="parent" ref="1003123887"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">9135</int>
<reference key="object" ref="863067735"/>
<reference key="parent" ref="1003123887"/>
</object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@ -51704,6 +51823,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>3523.IBPluginDependency</string>
<string>3644.IBPluginDependency</string>
<string>3648.IBPluginDependency</string>
<string>3648.IBViewBoundsToFrameTransform</string>
<string>3649.IBPluginDependency</string>
<string>3650.IBPluginDependency</string>
<string>3651.IBPluginDependency</string>
@ -53183,6 +53303,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>8448.IBPluginDependency</string>
<string>8448.IBViewBoundsToFrameTransform</string>
<string>845.IBPluginDependency</string>
<string>845.IBViewBoundsToFrameTransform</string>
<string>8451.IBEditorWindowLastContentRect</string>
<string>8451.IBPluginDependency</string>
<string>8451.IBViewBoundsToFrameTransform</string>
@ -53490,7 +53611,11 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>9114.IBPluginDependency</string>
<string>9115.IBPluginDependency</string>
<string>912.IBPluginDependency</string>
<string>9129.IBPluginDependency</string>
<string>913.IBPluginDependency</string>
<string>9131.IBPluginDependency</string>
<string>9133.IBPluginDependency</string>
<string>9135.IBPluginDependency</string>
<string>914.IBPluginDependency</string>
<string>92.IBPluginDependency</string>
<string>924.IBPluginDependency</string>
@ -54158,6 +54283,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBkAAAxCKAAA</bytes>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@ -56122,9 +56250,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
</object>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{343, 181}, {204, 521}}</string>
<string>{{861, 261}, {204, 601}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{343, 181}, {204, 521}}</string>
<string>{{861, 261}, {204, 601}}</string>
<boolean value="NO"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@ -56264,7 +56392,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{884, 253}, {239, 463}}</string>
<string>{{920, 173}, {239, 543}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@ -56464,6 +56592,9 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform">
<bytes key="NSTransformStruct">P4AAAL+AAABBoAAAwgwAAA</bytes>
</object>
<string>{{1184, 327}, {400, 320}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSAffineTransform"/>
@ -56746,7 +56877,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>{{307, 552}, {254, 262}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>{{307, 552}, {254, 262}}</string>
<boolean value="YES"/>
<boolean value="NO"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<object class="NSMutableDictionary">
<string key="NS.key.0">ToolTip</string>
@ -57007,6 +57138,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@ -57025,7 +57160,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
</object>
<nil key="sourceID"/>
<int key="maxID">9119</int>
<int key="maxID">9136</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -57776,6 +57911,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="NSArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>autoholdSet:</string>
<string>changeAudioEngine:</string>
<string>changeCoreEmuFlags:</string>
<string>changeCoreSpeed:</string>
@ -57863,12 +57999,14 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
<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>autoholdSet:</string>
<string>changeAudioEngine:</string>
<string>changeCoreEmuFlags:</string>
<string>changeCoreSpeed:</string>
@ -57914,6 +58052,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBActionInfo">
<string key="name">autoholdSet:</string>
<string key="candidateClassName">id</string>
</object>
<object class="IBActionInfo">
<string key="name">changeAudioEngine:</string>
<string key="candidateClassName">id</string>

View File

@ -16,7 +16,7 @@
*/
#import <Cocoa/Cocoa.h>
#include <OpenGL/OpenGL.h>
#import <OpenGL/OpenGL.h>
#include <libkern/OSAtomic.h>
#import "InputManager.h"
@ -24,6 +24,7 @@
@class CocoaDSController;
@class EmuControllerDelegate;
class OGLVideoOutput;
// Subclass NSWindow for full screen windows so that we can override some methods.
@ -34,59 +35,17 @@
@interface DisplayView : NSView <CocoaDSDisplayVideoDelegate, InputHIDManagerTarget>
{
InputManager *inputManager;
// Display thread
BOOL isHudEnabled;
BOOL isHudEditingModeEnabled;
OGLVideoOutput *oglv;
CGFloat _displayRotation;
// OpenGL context
NSOpenGLContext *context;
CGLContextObj cglDisplayContext;
NSSize _currentNormalSize;
NSInteger _currentDisplayMode;
NSInteger _currentDisplayOrientation;
GLfloat _currentGapScalar;
GLfloat _currentRotation;
GLenum glTexPixelFormat;
GLvoid *glTexBack;
NSSize glTexBackSize;
GLuint displayTexID;
GLuint vboVertexID;
GLuint vboTexCoordID;
GLuint vboElementID;
GLuint vaoMainStatesID;
GLuint vertexShaderID;
GLuint fragmentShaderID;
GLuint shaderProgram;
GLint uniformAngleDegrees;
GLint uniformScalar;
GLint uniformViewSize;
GLint vtxBuffer[4 * 8];
GLfloat texCoordBuffer[2 * 8];
GLubyte vtxIndexBuffer[12];
BOOL isShaderSupported;
size_t vtxBufferOffset;
}
@property (retain) InputManager *inputManager;
- (void) startupOpenGL;
- (void) shutdownOpenGL;
- (void) setupShaderIO;
- (BOOL) setupShadersWithVertexProgram:(const char *)vertShaderProgram fragmentProgram:(const char *)fragShaderProgram;
- (void) drawVideoFrame;
- (void) uploadVertices;
- (void) uploadTexCoords;
- (void) uploadDisplayTextures:(const GLvoid *)textureData displayMode:(const NSInteger)displayModeID width:(const GLsizei)texWidth height:(const GLsizei)texHeight;
- (void) renderDisplayUsingDisplayMode:(const NSInteger)displayModeID;
- (void) updateDisplayVerticesUsingDisplayMode:(const NSInteger)displayModeID orientation:(const NSInteger)displayOrientationID gap:(const GLfloat)gapScalar;
- (void) updateTexCoordS:(GLfloat)s T:(GLfloat)t;
- (NSPoint) dsPointFromEvent:(NSEvent *)theEvent;
- (NSPoint) convertPointToDS:(NSPoint)clickLoc;
- (BOOL) handleKeyPress:(NSEvent *)theEvent keyPressed:(BOOL)keyPressed;

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2013 DeSmuME team
Copyright (C) 2013-2014 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
@ -25,10 +25,8 @@
#import "cocoa_videofilter.h"
#import "cocoa_util.h"
#include "OGLDisplayOutput.h"
#include <Carbon/Carbon.h>
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <OpenGL/glu.h>
#if defined(__ppc__) || defined(__ppc64__)
#include <map>
@ -36,52 +34,6 @@
#include <tr1/unordered_map>
#endif
// VERTEX SHADER FOR DISPLAY OUTPUT
static const char *vertexProgram_100 = {"\
attribute vec2 inPosition; \n\
attribute vec2 inTexCoord0; \n\
\n\
uniform vec2 viewSize; \n\
uniform float scalar; \n\
uniform float angleDegrees; \n\
\n\
varying vec2 vtxTexCoord; \n\
\n\
void main() \n\
{ \n\
float angleRadians = radians(angleDegrees); \n\
\n\
mat2 projection = mat2( vec2(2.0/viewSize.x, 0.0), \n\
vec2( 0.0, 2.0/viewSize.y)); \n\
\n\
mat2 rotation = mat2( vec2(cos(angleRadians), -sin(angleRadians)), \n\
vec2(sin(angleRadians), cos(angleRadians))); \n\
\n\
mat2 scale = mat2( vec2(scalar, 0.0), \n\
vec2( 0.0, scalar)); \n\
\n\
vtxTexCoord = inTexCoord0; \n\
gl_Position = vec4(projection * rotation * scale * inPosition, 1.0, 1.0); \n\
} \n\
"};
// FRAGMENT SHADER FOR DISPLAY OUTPUT
static const char *fragmentProgram_100 = {"\
varying vec2 vtxTexCoord; \n\
uniform sampler2D tex; \n\
\n\
void main() \n\
{ \n\
gl_FragColor = texture2D(tex, vtxTexCoord); \n\
} \n\
"};
enum OGLVertexAttributeID
{
OGLVertexAttributeID_Position = 0,
OGLVertexAttributeID_TexCoord0 = 8
};
@implementation DisplayWindowController
@ -278,7 +230,7 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
_useBilinearOutput = theState;
OSSpinLockUnlock(&spinlockUseBilinearOutput);
[CocoaDSUtil messageSendOneWayWithBool:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_BILINEAR_OUTPUT boolValue:theState];
[[self view] doBilinearOutputChanged:theState];
}
- (BOOL) useBilinearOutput
@ -296,7 +248,7 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
_useVerticalSync = theState;
OSSpinLockUnlock(&spinlockUseVerticalSync);
[CocoaDSUtil messageSendOneWayWithBool:[[self cdsVideoOutput] receivePort] msgID:MESSAGE_CHANGE_VERTICAL_SYNC boolValue:theState];
[[self view] doVerticalSyncChanged:theState];
}
- (BOOL) useVerticalSync
@ -1060,13 +1012,6 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
[(NSMenuItem *)theItem setState:([self videoFilterType] == [theItem tag]) ? NSOnState : NSOffState];
}
}
else if (theAction == @selector(hudDisable:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
[(NSMenuItem *)theItem setTitle:([[self view] isHudEnabled]) ? NSSTRING_TITLE_DISABLE_HUD : NSSTRING_TITLE_ENABLE_HUD];
}
}
else if (theAction == @selector(toggleStatusBar:))
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
@ -1136,8 +1081,8 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
// Set the video filter source size now since the proper size is needed on initialization.
// If we don't do this, new windows could draw incorrectly.
const NSSize vfSrcSize = NSMakeSize(GPU_DISPLAY_WIDTH, ([self displayMode] == DS_DISPLAY_TYPE_DUAL) ? GPU_DISPLAY_HEIGHT * 2 : GPU_DISPLAY_HEIGHT);
[[cdsVideoOutput vf] setSourceSize:vfSrcSize];
//const NSSize vfSrcSize = NSMakeSize(GPU_DISPLAY_WIDTH, ([self displayMode] == DS_DISPLAY_TYPE_DUAL) ? GPU_DISPLAY_HEIGHT * 2 : GPU_DISPLAY_HEIGHT);
//[[cdsVideoOutput vf] setSourceSize:vfSrcSize];
[CocoaDSUtil messageSendOneWayWithInteger:[cdsVideoOutput receivePort] msgID:MESSAGE_CHANGE_VIDEO_FILTER integerValue:[self videoFilterType]];
// Add the video thread to the output list.
@ -1314,8 +1259,6 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
@implementation DisplayView
@synthesize inputManager;
@synthesize isHudEnabled;
@synthesize isHudEditingModeEnabled;
- (id)initWithFrame:(NSRect)frameRect
{
@ -1326,6 +1269,7 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
}
inputManager = nil;
oglv = new OGLVideoOutput();
// Initialize the OpenGL context
NSOpenGLPixelFormatAttribute attributes[] = {
@ -1341,31 +1285,9 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
[format release];
cglDisplayContext = (CGLContextObj)[context CGLContextObj];
_currentDisplayMode = DS_DISPLAY_TYPE_DUAL;
_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;
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;
[self updateDisplayVerticesUsingDisplayMode:_currentDisplayMode orientation:_currentDisplayOrientation gap:_currentGapScalar];
[self updateTexCoordS:1.0f T:2.0f];
// Set up initial vertex elements
vtxIndexBuffer[0] = 0; vtxIndexBuffer[1] = 1; vtxIndexBuffer[2] = 2;
vtxIndexBuffer[3] = 2; vtxIndexBuffer[4] = 3; vtxIndexBuffer[5] = 0;
vtxIndexBuffer[6] = 4; vtxIndexBuffer[7] = 5; vtxIndexBuffer[8] = 6;
vtxIndexBuffer[9] = 6; vtxIndexBuffer[10] = 7; vtxIndexBuffer[11] = 4;
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglDisplayContext);
[self startupOpenGL];
oglv->InitializeOGL();
CGLSetCurrentContext(prevContext);
return self;
@ -1375,350 +1297,26 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
{
CGLContextObj prevContext = CGLGetCurrentContext();
CGLSetCurrentContext(cglDisplayContext);
[self shutdownOpenGL];
oglv->TerminateOGL();
CGLSetCurrentContext(prevContext);
free(glTexBack);
glTexBack = NULL;
[self setInputManager:nil];
[context clearDrawable];
[context release];
delete oglv;
[super dealloc];
}
#pragma mark Class Methods
- (void) startupOpenGL
{
// Check the OpenGL capabilities for this renderer
const GLubyte *glExtString = glGetString(GL_EXTENSIONS);
// Set up textures
glGenTextures(1, &displayTexID);
glBindTexture(GL_TEXTURE_2D, displayTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
// Set up shaders (but disable on PowerPC, since it doesn't seem to work there)
#if defined(__i386__) || defined(__x86_64__)
isShaderSupported = (gluCheckExtension((const GLubyte *)"GL_ARB_shader_objects", glExtString) &&
gluCheckExtension((const GLubyte *)"GL_ARB_vertex_shader", glExtString) &&
gluCheckExtension((const GLubyte *)"GL_ARB_fragment_shader", glExtString) &&
gluCheckExtension((const GLubyte *)"GL_ARB_vertex_program", glExtString) );
#else
isShaderSupported = false;
#endif
if (isShaderSupported)
{
BOOL isShaderSetUp = [self setupShadersWithVertexProgram:vertexProgram_100 fragmentProgram:fragmentProgram_100];
if (isShaderSetUp)
{
glUseProgram(shaderProgram);
uniformAngleDegrees = glGetUniformLocation(shaderProgram, "angleDegrees");
uniformScalar = glGetUniformLocation(shaderProgram, "scalar");
uniformViewSize = glGetUniformLocation(shaderProgram, "viewSize");
glUniform1f(uniformAngleDegrees, 0.0f);
glUniform1f(uniformScalar, 1.0f);
glUniform2f(uniformViewSize, GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT*2.0 + (DS_DISPLAY_GAP*_currentGapScalar));
}
else
{
isShaderSupported = false;
}
}
// Set up VBOs
glGenBuffersARB(1, &vboVertexID);
glGenBuffersARB(1, &vboTexCoordID);
glGenBuffersARB(1, &vboElementID);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLint) * (2 * 8), vtxBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboTexCoordID);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLfloat) * (2 * 8), texCoordBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboElementID);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(GLubyte) * 12, vtxIndexBuffer, GL_STATIC_DRAW_ARB);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
// Set up VAO
glGenVertexArraysAPPLE(1, &vaoMainStatesID);
glBindVertexArrayAPPLE(vaoMainStatesID);
if (isShaderSupported)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID);
glVertexAttribPointer(OGLVertexAttributeID_Position, 2, GL_INT, GL_FALSE, 0, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboTexCoordID);
glVertexAttribPointer(OGLVertexAttributeID_TexCoord0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboElementID);
glEnableVertexAttribArray(OGLVertexAttributeID_Position);
glEnableVertexAttribArray(OGLVertexAttributeID_TexCoord0);
}
else
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID);
glVertexPointer(2, GL_INT, 0, 0);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboTexCoordID);
glTexCoordPointer(2, GL_FLOAT, 0, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vboElementID);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
}
glBindVertexArrayAPPLE(0);
// Render State Setup (common to both shaders and fixed-function pipeline)
glDisable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_DITHER);
glDisable(GL_STENCIL_TEST);
// Set up fixed-function pipeline render states.
if (!isShaderSupported)
{
glDisable(GL_ALPHA_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glEnable(GL_TEXTURE_2D);
}
// Set up clear attributes
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
- (void) shutdownOpenGL
{
glDeleteTextures(1, &displayTexID);
glDeleteVertexArraysAPPLE(1, &vaoMainStatesID);
glDeleteBuffersARB(1, &vboVertexID);
glDeleteBuffersARB(1, &vboTexCoordID);
glDeleteBuffersARB(1, &vboElementID);
if (isShaderSupported)
{
glUseProgram(0);
glDetachShader(shaderProgram, vertexShaderID);
glDetachShader(shaderProgram, fragmentShaderID);
glDeleteProgram(shaderProgram);
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
}
}
- (void) setupShaderIO
{
glBindAttribLocation(shaderProgram, OGLVertexAttributeID_Position, "inPosition");
glBindAttribLocation(shaderProgram, OGLVertexAttributeID_TexCoord0, "inTexCoord0");
}
- (BOOL) setupShadersWithVertexProgram:(const char *)vertShaderProgram fragmentProgram:(const char *)fragShaderProgram
{
BOOL result = NO;
GLint shaderStatus = GL_TRUE;
vertexShaderID = glCreateShader(GL_VERTEX_SHADER);
if (vertexShaderID == 0)
{
NSLog(@"OpenGL Error - Failed to create vertex shader.");
return result;
}
glShaderSource(vertexShaderID, 1, (const GLchar **)&vertShaderProgram, NULL);
glCompileShader(vertexShaderID);
glGetShaderiv(vertexShaderID, GL_COMPILE_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE)
{
glDeleteShader(vertexShaderID);
NSLog(@"OpenGL Error - Failed to compile vertex shader.");
return result;
}
fragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
if (fragmentShaderID == 0)
{
glDeleteShader(vertexShaderID);
NSLog(@"OpenGL Error - Failed to create fragment shader.");
return result;
}
glShaderSource(fragmentShaderID, 1, (const GLchar **)&fragShaderProgram, NULL);
glCompileShader(fragmentShaderID);
glGetShaderiv(fragmentShaderID, GL_COMPILE_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE)
{
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
NSLog(@"OpenGL Error - Failed to compile fragment shader.");
return result;
}
shaderProgram = glCreateProgram();
if (shaderProgram == 0)
{
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
NSLog(@"OpenGL Error - Failed to create shader program.");
return result;
}
glAttachShader(shaderProgram, vertexShaderID);
glAttachShader(shaderProgram, fragmentShaderID);
[self setupShaderIO];
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &shaderStatus);
if (shaderStatus == GL_FALSE)
{
glDeleteProgram(shaderProgram);
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
NSLog(@"OpenGL Error - Failed to link shader program.");
return result;
}
glValidateProgram(shaderProgram);
result = YES;
return result;
}
- (void) drawVideoFrame
{
oglv->RenderOGL();
CGLFlushDrawable(cglDisplayContext);
}
- (void) uploadVertices
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboVertexID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(GLint) * (2 * 8), vtxBuffer + vtxBufferOffset);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
- (void) uploadTexCoords
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vboTexCoordID);
glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(GLfloat) * (2 * 8), texCoordBuffer);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
}
- (void) uploadDisplayTextures:(const GLvoid *)textureData displayMode:(const NSInteger)displayModeID width:(const GLsizei)texWidth height:(const GLsizei)texHeight
{
if (textureData == NULL)
{
return;
}
const GLint lineOffset = (displayModeID == DS_DISPLAY_TYPE_TOUCH) ? texHeight : 0;
glBindTexture(GL_TEXTURE_2D, displayTexID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, lineOffset, texWidth, texHeight, GL_RGBA, glTexPixelFormat, textureData);
glBindTexture(GL_TEXTURE_2D, 0);
}
- (void) renderDisplayUsingDisplayMode:(const NSInteger)displayModeID
{
// Enable vertex attributes
glBindVertexArrayAPPLE(vaoMainStatesID);
// Perform the render
if (_currentDisplayMode != displayModeID)
{
_currentDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:_currentDisplayOrientation gap:_currentGapScalar];
[self uploadVertices];
}
const GLsizei vtxElementCount = (displayModeID == DS_DISPLAY_TYPE_DUAL) ? 12 : 6;
const GLubyte *elementPointer = !(displayModeID == DS_DISPLAY_TYPE_TOUCH) ? 0 : (GLubyte *)(vtxElementCount * sizeof(GLubyte));
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, displayTexID);
glDrawElements(GL_TRIANGLES, vtxElementCount, GL_UNSIGNED_BYTE, elementPointer);
glBindTexture(GL_TEXTURE_2D, 0);
// Disable vertex attributes
glBindVertexArrayAPPLE(0);
}
- (void) updateDisplayVerticesUsingDisplayMode:(const NSInteger)displayModeID orientation:(const NSInteger)displayOrientationID gap:(const GLfloat)gapScalar
{
const GLfloat w = GPU_DISPLAY_WIDTH;
const GLfloat h = GPU_DISPLAY_HEIGHT;
const GLfloat gap = DS_DISPLAY_GAP * gapScalar / 2.0;
if (displayModeID == DS_DISPLAY_TYPE_DUAL)
{
// displayOrder == DS_DISPLAY_ORDER_MAIN_FIRST
if (displayOrientationID == DS_DISPLAY_ORIENTATION_VERTICAL)
{
vtxBuffer[0] = -w/2; vtxBuffer[1] = h+gap; // Top display, top left
vtxBuffer[2] = w/2; vtxBuffer[3] = h+gap; // Top display, top right
vtxBuffer[4] = w/2; vtxBuffer[5] = gap; // Top display, bottom right
vtxBuffer[6] = -w/2; vtxBuffer[7] = gap; // Top display, bottom left
vtxBuffer[8] = -w/2; vtxBuffer[9] = -gap; // Bottom display, top left
vtxBuffer[10] = w/2; vtxBuffer[11] = -gap; // Bottom display, top right
vtxBuffer[12] = w/2; vtxBuffer[13] = -(h+gap); // Bottom display, bottom right
vtxBuffer[14] = -w/2; vtxBuffer[15] = -(h+gap); // Bottom display, bottom left
}
else // displayOrientationID == DS_DISPLAY_ORIENTATION_HORIZONTAL
{
vtxBuffer[0] = -(w+gap); vtxBuffer[1] = h/2; // Left display, top left
vtxBuffer[2] = -gap; vtxBuffer[3] = h/2; // Left display, top right
vtxBuffer[4] = -gap; vtxBuffer[5] = -h/2; // Left display, bottom right
vtxBuffer[6] = -(w+gap); vtxBuffer[7] = -h/2; // Left display, bottom left
vtxBuffer[8] = gap; vtxBuffer[9] = h/2; // Right display, top left
vtxBuffer[10] = w+gap; vtxBuffer[11] = h/2; // Right display, top right
vtxBuffer[12] = w+gap; vtxBuffer[13] = -h/2; // Right display, bottom right
vtxBuffer[14] = gap; vtxBuffer[15] = -h/2; // Right display, bottom left
}
// displayOrder == DS_DISPLAY_ORDER_TOUCH_FIRST
memcpy(vtxBuffer + (2 * 8), vtxBuffer + (1 * 8), sizeof(GLint) * (1 * 8));
memcpy(vtxBuffer + (3 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (1 * 8));
}
else // displayModeID == DS_DISPLAY_TYPE_MAIN || displayModeID == DS_DISPLAY_TYPE_TOUCH
{
vtxBuffer[0] = -w/2; vtxBuffer[1] = h/2; // First display, top left
vtxBuffer[2] = w/2; vtxBuffer[3] = h/2; // First display, top right
vtxBuffer[4] = w/2; vtxBuffer[5] = -h/2; // First display, bottom right
vtxBuffer[6] = -w/2; vtxBuffer[7] = -h/2; // First display, bottom left
memcpy(vtxBuffer + (1 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (1 * 8)); // Second display
memcpy(vtxBuffer + (2 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (2 * 8)); // Second display
}
}
- (void) updateTexCoordS:(GLfloat)s T:(GLfloat)t
{
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t/2.0f;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t/2.0f;
texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = t/2.0f;
texCoordBuffer[10] = s; texCoordBuffer[11] = t/2.0f;
texCoordBuffer[12] = s; texCoordBuffer[13] = t;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = t;
}
- (NSPoint) dsPointFromEvent:(NSEvent *)theEvent
{
// Convert the clicked location from window coordinates, to view coordinates,
@ -1742,7 +1340,7 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
const NSSize normalBounds = [windowController normalSize];
const NSSize viewSize = [self bounds].size;
const CGSize transformBounds = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, _currentRotation);
const CGSize transformBounds = GetTransformedBounds(normalBounds.width, normalBounds.height, 1.0, _displayRotation);
const double s = GetMaxScalarInBounds(transformBounds.width, transformBounds.height, viewSize.width, viewSize.height);
CGPoint touchLoc = GetNormalPointFromTransformedPoint(clickLoc.x, clickLoc.y,
@ -2047,13 +1645,23 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
// No init needed, so do nothing.
}
- (void)doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight
- (void)doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)frameDisplayMode width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight
{
const bool didDisplayModeChange = (oglv->GetDisplayMode() != frameDisplayMode);
if (didDisplayModeChange)
{
oglv->SetDisplayMode(frameDisplayMode);
}
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadDisplayTextures:videoFrameData displayMode:displayModeID width:frameWidth height:frameHeight];
[self renderDisplayUsingDisplayMode:displayModeID];
if (didDisplayModeChange)
{
oglv->UploadVerticesOGL();
}
oglv->PrerenderOGL(videoFrameData, frameWidth, frameHeight);
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
@ -2061,62 +1669,22 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
- (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);
glViewport(0, 0, rect.size.width, rect.size.height);
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];
oglv->SetViewportSizeOGL(rect.size.width, rect.size.height);
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doTransformView:(const DisplayOutputTransformData *)transformData
{
_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);
_displayRotation = (GLfloat)transformData->rotation;
oglv->SetRotation((GLfloat)transformData->rotation);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
if (isShaderSupported)
{
glUniform1f(uniformAngleDegrees, _currentRotation);
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];
oglv->UpdateDisplayTransformationOGL();
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
@ -2124,94 +1692,45 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
{
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doDisplayModeChanged:(NSInteger)displayModeID
{
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];
oglv->SetDisplayMode(displayModeID);
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];
oglv->UpdateDisplayTransformationOGL();
oglv->UploadVerticesOGL();
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doBilinearOutputChanged:(BOOL)useBilinear
{
const GLint textureFilter = (useBilinear) ? GL_LINEAR : GL_NEAREST;
const bool c99_useBilinear = (useBilinear) ? true : false;
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
glBindTexture(GL_TEXTURE_2D, displayTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, textureFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, textureFilter);
glBindTexture(GL_TEXTURE_2D, 0);
oglv->SetDisplayBilinearOGL(c99_useBilinear);
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doDisplayOrientationChanged:(NSInteger)displayOrientationID
{
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
_currentNormalSize = [windowController normalSize];
_currentDisplayOrientation = displayOrientationID;
[self updateDisplayVerticesUsingDisplayMode:_currentDisplayMode orientation:displayOrientationID gap:_currentGapScalar];
oglv->SetDisplayOrientation(displayOrientationID);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadVertices];
oglv->UploadVerticesOGL();
if (_currentDisplayMode == DS_DISPLAY_TYPE_DUAL)
if (oglv->GetDisplayMode() == DS_DISPLAY_TYPE_DUAL)
{
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];
oglv->UpdateDisplayTransformationOGL();
[self drawVideoFrame];
}
@ -2220,23 +1739,14 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
- (void)doDisplayOrderChanged:(NSInteger)displayOrderID
{
if (displayOrderID == DS_DISPLAY_ORDER_MAIN_FIRST)
{
vtxBufferOffset = 0;
}
else // displayOrder == DS_DISPLAY_ORDER_TOUCH_FIRST
{
vtxBufferOffset = (2 * 8);
}
oglv->SetDisplayOrder(displayOrderID);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadVertices];
if (_currentDisplayMode == DS_DISPLAY_TYPE_DUAL)
oglv->UploadVerticesOGL();
if (oglv->GetDisplayMode() == DS_DISPLAY_TYPE_DUAL)
{
[self renderDisplayUsingDisplayMode:_currentDisplayMode];
[self drawVideoFrame];
}
@ -2245,36 +1755,16 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
- (void)doDisplayGapChanged:(float)displayGapScalar
{
DisplayWindowController *windowController = (DisplayWindowController *)[[self window] delegate];
_currentNormalSize = [windowController normalSize];
_currentGapScalar = (GLfloat)displayGapScalar;
[self updateDisplayVerticesUsingDisplayMode:_currentDisplayMode orientation:_currentDisplayOrientation gap:(GLfloat)displayGapScalar];
oglv->SetGapScalar((GLfloat)displayGapScalar);
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadVertices];
oglv->UploadVerticesOGL();
if (_currentDisplayMode == DS_DISPLAY_TYPE_DUAL)
if (oglv->GetDisplayMode() == DS_DISPLAY_TYPE_DUAL)
{
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];
oglv->UpdateDisplayTransformationOGL();
[self drawVideoFrame];
}
@ -2283,57 +1773,19 @@ static std::tr1::unordered_map<NSScreen *, DisplayWindowController *> _screenMap
- (void)doVerticalSyncChanged:(BOOL)useVerticalSync
{
const GLint swapInt = useVerticalSync ? 1 : 0;
CGLSetParameter(cglDisplayContext, kCGLCPSwapInterval, &swapInt);
}
- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize
{
size_t colorDepth = sizeof(uint32_t);
glTexPixelFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
if (videoFilterTypeID == VideoFilterTypeID_None)
{
colorDepth = sizeof(uint16_t);
glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
}
if (_currentDisplayMode != DS_DISPLAY_TYPE_DUAL)
{
videoFilterDestSize.height = (uint32_t)videoFilterDestSize.height * 2;
}
// Convert textures to Power-of-Two to support older GPUs
// Example: Radeon X1600M on the 2006 MacBook Pro
const uint32_t potW = GetNearestPositivePOT((uint32_t)videoFilterDestSize.width);
const uint32_t potH = GetNearestPositivePOT((uint32_t)videoFilterDestSize.height);
if (glTexBackSize.width != potW || glTexBackSize.height != potH)
{
glTexBackSize.width = potW;
glTexBackSize.height = potH;
free(glTexBack);
glTexBack = (GLvoid *)calloc((size_t)potW * (size_t)potH, colorDepth);
if (glTexBack == NULL)
{
return;
}
}
const GLfloat s = (GLfloat)videoFilterDestSize.width / (GLfloat)potW;
const GLfloat t = (GLfloat)videoFilterDestSize.height / (GLfloat)potH;
[self updateTexCoordS:s T:t];
const GLint swapInt = (useVerticalSync) ? 1 : 0;
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
glBindTexture(GL_TEXTURE_2D, displayTexID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)potW, (GLsizei)potH, 0, GL_BGRA, glTexPixelFormat, glTexBack);
glBindTexture(GL_TEXTURE_2D, 0);
[self uploadTexCoords];
CGLSetParameter(cglDisplayContext, kCGLCPSwapInterval, &swapInt);
CGLUnlockContext(cglDisplayContext);
}
- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID
{
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
oglv->RespondToVideoFilterChangeOGL((const VideoFilterTypeID)videoFilterTypeID);
CGLUnlockContext(cglDisplayContext);
}

View File

@ -1,5 +1,5 @@
/*
Copyright (C) 2009-2012 DeSmuME team
Copyright (C) 2009-2014 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
@ -41,3 +41,7 @@ void RenderEPX_1Point5x( SSurface Src, SSurface Dst);
void RenderEPXPlus_1Point5x( SSurface Src, SSurface Dst);
void RenderNearest_1Point5x( SSurface Src, SSurface Dst);
void RenderNearestPlus_1Point5x( SSurface Src, SSurface Dst);
void Render2xBRZ(SSurface Src, SSurface Dst);
void Render3xBRZ(SSurface Src, SSurface Dst);
void Render4xBRZ(SSurface Src, SSurface Dst);
void Render5xBRZ(SSurface Src, SSurface Dst);

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011-2012 Roger Manuel
Copyright (C) 2013 DeSmuME team
Copyright (C) 2013-2014 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

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011-2012 Roger Manuel
Copyright (C) 2013 DeSmuME team
Copyright (C) 2013-2014 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
@ -64,6 +64,10 @@ enum VideoFilterTypeID
VideoFilterTypeID_EPX1_5X,
VideoFilterTypeID_EPXPlus1_5X,
VideoFilterTypeID_HQ4XS,
VideoFilterTypeID_2xBRZ,
VideoFilterTypeID_3xBRZ,
VideoFilterTypeID_4xBRZ,
VideoFilterTypeID_5xBRZ,
VideoFilterTypeIDCount // Make sure this one is always last
};
@ -97,7 +101,11 @@ const VideoFilterAttributes VideoFilterAttributesList[] = {
{VideoFilterTypeID_EPXPlus, "EPX+", &RenderEPXPlus, 2, 1},
{VideoFilterTypeID_EPX1_5X, "EPX 1.5x", &RenderEPX_1Point5x, 3, 2},
{VideoFilterTypeID_EPXPlus1_5X, "EPX+ 1.5x", &RenderEPXPlus_1Point5x, 3, 2},
{VideoFilterTypeID_HQ4XS, "HQ4xS", &RenderHQ4XS, 4, 1} };
{VideoFilterTypeID_HQ4XS, "HQ4xS", &RenderHQ4XS, 4, 1},
{VideoFilterTypeID_2xBRZ, "2xBRZ", &Render2xBRZ, 2, 1},
{VideoFilterTypeID_3xBRZ, "3xBRZ", &Render3xBRZ, 3, 1},
{VideoFilterTypeID_4xBRZ, "4xBRZ", &Render4xBRZ, 4, 1},
{VideoFilterTypeID_5xBRZ, "5xBRZ", &Render5xBRZ, 5, 1} };
// VIDEO FILTER PARAMETER DATA TYPES
enum VideoFilterParamType

1267
desmume/src/filter/xbrz.cpp Normal file

File diff suppressed because it is too large Load Diff

105
desmume/src/filter/xbrz.h Normal file
View File

@ -0,0 +1,105 @@
// ****************************************************************************
// * This file is part of the HqMAME project. It is distributed under *
// * GNU General Public License: http://www.gnu.org/licenses/gpl.html *
// * Copyright (C) Zenju (zenju AT gmx DOT de) - All Rights Reserved *
// * *
// * Additionally and as a special exception, the author gives permission *
// * to link the code of this program with the MAME library (or with modified *
// * versions of MAME that use the same license as MAME), and distribute *
// * linked combinations including the two. You must obey the GNU General *
// * Public License in all respects for all of the code used other than MAME. *
// * If you modify this file, you may extend this exception to your version *
// * of the file, but you are not obligated to do so. If you do not wish to *
// * do so, delete this exception statement from your version. *
// ****************************************************************************
// 2014-02-06 (rogerman): Modified for use in DeSmuME by removing C++11 code.
// Also integrate xbrz's config.h file into this one.
#ifndef XBRZ_HEADER_3847894708239054
#define XBRZ_HEADER_3847894708239054
#include <cstddef> //size_t
#include <stdint.h> //uint32_t
#include <limits>
namespace xbrz
{
/*
-------------------------------------------------------------------------
| xBRZ: "Scale by rules" - high quality image upscaling filter by Zenju |
-------------------------------------------------------------------------
using a modified approach of xBR:
http://board.byuu.org/viewtopic.php?f=10&t=2248
- new rule set preserving small image features
- support multithreading
- support 64 bit architectures
- support processing image slices
*/
/*
-> map source (srcWidth * srcHeight) to target (scale * width x scale * height) image, optionally processing a half-open slice of rows [yFirst, yLast) only
-> color format: ARGB (BGRA byte order), alpha channel unused
-> support for source/target pitch in bytes!
-> if your emulator changes only a few image slices during each cycle (e.g. Dosbox) then there's no need to run xBRZ on the complete image:
Just make sure you enlarge the source image slice by 2 rows on top and 2 on bottom (this is the additional range the xBRZ algorithm is using during analysis)
Caveat: If there are multiple changed slices, make sure they do not overlap after adding these additional rows in order to avoid a memory race condition
if you are using multiple threads for processing each enlarged slice!
THREAD-SAFETY: - parts of the same image may be scaled by multiple threads as long as the [yFirst, yLast) ranges do not overlap!
- there is a minor inefficiency for the first row of a slice, so avoid processing single rows only
*/
struct ScalerCfg
{
ScalerCfg() :
luminanceWeight_(1),
equalColorTolerance_(30),
dominantDirectionThreshold(3.6),
steepDirectionThreshold(2.2),
newTestAttribute_(0) {}
double luminanceWeight_;
double equalColorTolerance_;
double dominantDirectionThreshold;
double steepDirectionThreshold;
double newTestAttribute_; //unused; test new parameters
};
void scale(size_t factor, //valid range: 2 - 5
const uint32_t* src, uint32_t* trg, int srcWidth, int srcHeight,
const ScalerCfg& cfg = ScalerCfg(),
int yFirst = 0, int yLast = std::numeric_limits<int>::max()); //slice of source image
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
uint32_t* trg, int trgWidth, int trgHeight);
enum SliceType
{
NN_SCALE_SLICE_SOURCE,
NN_SCALE_SLICE_TARGET,
};
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight, int srcPitch, //pitch in bytes!
uint32_t* trg, int trgWidth, int trgHeight, int trgPitch,
SliceType st, int yFirst, int yLast);
//parameter tuning
bool equalColor(uint32_t col1, uint32_t col2, double luminanceWeight, double equalColorTolerance);
//########################### implementation ###########################
inline
void nearestNeighborScale(const uint32_t* src, int srcWidth, int srcHeight,
uint32_t* trg, int trgWidth, int trgHeight)
{
nearestNeighborScale(src, srcWidth, srcHeight, srcWidth * sizeof(uint32_t),
trg, trgWidth, trgHeight, trgWidth * sizeof(uint32_t),
NN_SCALE_SLICE_TARGET, 0, trgHeight);
}
}
#endif