From: <gec...@us...> - 2008-09-20 20:25:15
|
Revision: 977 http://desmume.svn.sourceforge.net/desmume/?rev=977&view=rev Author: gecko_reverse Date: 2008-09-20 20:25:02 +0000 (Sat, 20 Sep 2008) Log Message: ----------- cocoa port: compile fixes, ScreenState cleaned up a bit and moved to it's own file, opengl now optional with HAVE_OPENGL macro (VideoOutputView now uses NSImageView to display if opengl is not available), VideoOuputView rotation uses boundsRotation from NSView rather than managing it's own Modified Paths: -------------- trunk/desmume/src/OGLRender.cpp trunk/desmume/src/cocoa/DeSmuME.cbp trunk/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj trunk/desmume/src/cocoa/Rakefile trunk/desmume/src/cocoa/main_window.h trunk/desmume/src/cocoa/main_window.m trunk/desmume/src/cocoa/nds_control.h trunk/desmume/src/cocoa/nds_control.mm trunk/desmume/src/cocoa/video_output_view.h trunk/desmume/src/cocoa/video_output_view.m trunk/desmume/src/saves.cpp trunk/desmume/src/types.h Added Paths: ----------- trunk/desmume/src/cocoa/screen_state.h trunk/desmume/src/cocoa/screen_state.m Modified: trunk/desmume/src/OGLRender.cpp =================================================================== --- trunk/desmume/src/OGLRender.cpp 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/OGLRender.cpp 2008-09-20 20:25:02 UTC (rev 977) @@ -508,7 +508,7 @@ { //TODO - we need to compare the palette also. //TODO - this doesnt correctly span bank boundaries. in fact, it seems quite dangerous. - if (!texcache[i].suspectedInvalid || !memcmp(adr,texcache[i].texture,std::min(imageSize,sizeof(texcache[i].texture)))) + if (!texcache[i].suspectedInvalid || !memcmp(adr,texcache[i].texture,std::min((size_t)imageSize,sizeof(texcache[i].texture)))) { texcache[i].suspectedInvalid = false; texcache_count=i; @@ -550,7 +550,7 @@ texcache[i].invSizeX=1.0f/((float)sizeX*(1<<4)); texcache[i].invSizeY=1.0f/((float)sizeY*(1<<4)); //memcpy(texcache[i].texture,adr,imageSize); //======================= copy - memcpy_fast(texcache[i].texture,adr,std::min(imageSize,sizeof(texcache[i].texture))); //======================= copy + memcpy_fast(texcache[i].texture,adr,std::min((size_t)imageSize,sizeof(texcache[i].texture))); //======================= copy texcache[i].numcolors=palSize[texcache[i].mode]; texcache[i].frm=format; Modified: trunk/desmume/src/cocoa/DeSmuME.cbp =================================================================== --- trunk/desmume/src/cocoa/DeSmuME.cbp 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/DeSmuME.cbp 2008-09-20 20:25:02 UTC (rev 977) @@ -43,6 +43,7 @@ <Add option="-msse2" /> <Add option="-DDESMUME_COCOA" /> <Add option="-DHAVE_LIBZ" /> + <Add option="-DHAVE_OPENGL" /> </Compiler> <ExtraCommands> <Add after="cp DeSmuME.app/Contents/MacOS/DeSmuME DeSmuME.app/Contents/MacOS/DeSmuME_x86" /> @@ -59,6 +60,8 @@ <Add option="-arch ppc" /> <Add option="-DDESMUME_COCOA" /> <Add option="-DHAVE_LIBZ" /> + <Add option="-DWORDS_BIGENDIAN" /> + <Add option="-DHAVE_OPENGL" /> </Compiler> <Linker> <Add option="-arch ppc" /> @@ -158,6 +161,11 @@ <Option compile="1" /> <Option link="1" /> </Unit> + <Unit filename="screen_state.h" /> + <Unit filename="screen_state.m"> + <Option compile="1" /> + <Option link="1" /> + </Unit> <Unit filename="screenshot.h" /> <Unit filename="screenshot.m"> <Option compile="1" /> @@ -193,6 +201,8 @@ <Unit filename="../mc.h" /> <Unit filename="../mem.h" /> <Unit filename="../opengl_collector_3Demu.h" /> + <Unit filename="../readwrite.cpp" /> + <Unit filename="../readwrite.h" /> <Unit filename="../registers.h" /> <Unit filename="../render3D.cpp" /> <Unit filename="../render3D.h" /> Modified: trunk/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj =================================================================== --- trunk/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/DeSmuME.xcodeproj/project.pbxproj 2008-09-20 20:25:02 UTC (rev 977) @@ -52,6 +52,8 @@ 729BEC7A0D9D55DB00ED561B /* video_output_view.m in Sources */ = {isa = PBXBuildFile; fileRef = 729BEC6E0D9D55DB00ED561B /* video_output_view.m */; }; 729BECE70D9D57F600ED561B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 729BECE60D9D57F600ED561B /* OpenGL.framework */; }; 729BECF00D9D581900ED561B /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 729BECEF0D9D581900ED561B /* AudioUnit.framework */; }; + 72D89DE50E83973A008D9B64 /* screen_state.m in Sources */ = {isa = PBXBuildFile; fileRef = 72D89DE40E83973A008D9B64 /* screen_state.m */; }; + 72D89E370E845C7E008D9B64 /* readwrite.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 72D89E360E845C7E008D9B64 /* readwrite.cpp */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -149,6 +151,9 @@ 729BECEF0D9D581900ED561B /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; }; 72C000010D9D59E60046B7EA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 72C000020D9D59E60046B7EA /* InfoPlist.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = InfoPlist.strings; sourceTree = "<group>"; }; + 72D89DE30E83973A008D9B64 /* screen_state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screen_state.h; sourceTree = "<group>"; }; + 72D89DE40E83973A008D9B64 /* screen_state.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = screen_state.m; sourceTree = "<group>"; }; + 72D89E360E845C7E008D9B64 /* readwrite.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = readwrite.cpp; path = ../readwrite.cpp; sourceTree = SOURCE_ROOT; }; 8D1107320486CEB800E47090 /* DeSmuME.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DeSmuME.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -170,6 +175,8 @@ isa = PBXGroup; children = ( 72D219C40E6B4DDF00439B28 /* Dialogs */, + 72D89DE30E83973A008D9B64 /* screen_state.h */, + 72D89DE40E83973A008D9B64 /* screen_state.m */, 7277B8EA0D9F25F700D283BD /* about.m */, 729BEC5C0D9D55DB00ED561B /* globals.h */, 729BEC600D9D55DB00ED561B /* main.m */, @@ -236,6 +243,7 @@ 29B97315FDCFA39411CA2CEA /* Core */ = { isa = PBXGroup; children = ( + 72D89E360E845C7E008D9B64 /* readwrite.cpp */, 728E5E200E7F54CC00608344 /* GPU_osd.h */, 7248E45E0E7E0B0E004DCFFE /* gfx3d.cpp */, 7248E45F0E7E0B0E004DCFFE /* gfx3d.h */, @@ -451,6 +459,8 @@ 7248E4620E7E0B0E004DCFFE /* gfx3d.cpp in Sources */, 7248E4630E7E0B0E004DCFFE /* OGLRender.cpp in Sources */, 728E5E210E7F54CC00608344 /* GPU_osd.cpp in Sources */, + 72D89DE50E83973A008D9B64 /* screen_state.m in Sources */, + 72D89E370E845C7E008D9B64 /* readwrite.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -502,6 +512,7 @@ ARCHS = "$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)"; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( + HAVE_OPENGL, DESMUME_OBJ_C, HAVE_LIBZ, DESMUME_COCOA, @@ -522,6 +533,7 @@ ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)"; GCC_PREPROCESSOR_DEFINITIONS = ( + HAVE_OPENGL, DESMUME_OBJ_C, HAVE_LIBZ, DESMUME_COCOA, Modified: trunk/desmume/src/cocoa/Rakefile =================================================================== --- trunk/desmume/src/cocoa/Rakefile 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/Rakefile 2008-09-20 20:25:02 UTC (rev 977) @@ -12,10 +12,10 @@ :files => Dir['*.m'] + Dir['*.mm'] + Dir['dialogs/*.m'] + Dir['dialogs/*.mm'] + ([ 'MMU', 'SPU', 'cflash', 'fs-linux', 'matrix', 'FIFO', 'NDSSystem', 'arm_instructions', 'cp15', 'mc', 'thumb_instructions', 'GPU', 'OGLRender', 'armcpu', 'gfx3d', 'render3D', 'wifi', 'GPU_osd', 'ROMReader', - 'bios', 'debug', 'gl_vertex', 'saves'].map { |core_file| '../' + core_file + '.cpp' } ), + 'bios', 'debug', 'gl_vertex', 'saves', 'readwrite'].map { |core_file| '../' + core_file + '.cpp' } ), :defines => { :global => ['DESMUME_OBJ_C'], - :cocoa => ['DESMUME_COCOA', 'HAVE_LIBZ']}, + :cocoa => ['DESMUME_COCOA', 'HAVE_LIBZ', 'HAVE_OPENGL']}, :options => { :global => [ 'arch i386', Modified: trunk/desmume/src/cocoa/main_window.h =================================================================== --- trunk/desmume/src/cocoa/main_window.h 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/main_window.h 2008-09-20 20:25:02 UTC (rev 977) @@ -85,10 +85,12 @@ - (void)toggleStatusBar; //rotation +- (void)setRotation:(float)rotation; - (void)setRotation0; - (void)setRotation90; - (void)setRotation180; - (void)setRotation270; +- (float)rotation; //layers - (void)toggleTopBackground0; Modified: trunk/desmume/src/cocoa/main_window.m =================================================================== --- trunk/desmume/src/cocoa/main_window.m 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/main_window.m 2008-09-20 20:25:02 UTC (rev 977) @@ -17,12 +17,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#import <Cocoa/Cocoa.h> -#import <OpenGL/gl.h> - //DeSmuME Cocoa includes #import "main_window.h" #import "screenshot.h" +#import "screen_state.h" #import "video_output_view.h" #import "input.h" #import "rom_info.h" @@ -34,11 +32,6 @@ #define MAX_FRAME_SKIP 10 -#define ROTATION_0 0 -#define ROTATION_90 1 -#define ROTATION_180 2 -#define ROTATION_270 3 - #define DS_SCREEN_HEIGHT_COMBINED (192*2) /*height of the two screens*/ #define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.0)) #define DS_SCREEN_Y_RATIO ((192.0 * 2.0) / 256.0) @@ -173,7 +166,7 @@ [self toggleStatusBar]; //Add callbacks - [self setVideoUpdateCallback:@selector(updateScreen:) withObject:video_output_view]; + [self setVideoUpdateCallback:@selector(setScreenState:) withObject:video_output_view]; [self setErrorCallback:@selector(emulationError) withObject:self]; //Show the window @@ -208,7 +201,7 @@ //Set status var and screen depending on whether the rom could be loaded if(result == NO) { - [video_output_view clearScreenBlack]; //black if the rom doesn't load + [video_output_view setScreenState:[ScreenState blackScreenState]]; //black if the rom doesn't load [self setStatusText:NSLocalizedString(@"No ROM Loaded", nil)]; messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't load ROM"); } else @@ -218,7 +211,7 @@ [self execute]; else { - [video_output_view clearScreenWhite]; //white if the rom loaded but is not playing + [video_output_view setScreenState:[ScreenState whiteScreenState]]; //white if the rom loaded but is not playing [self setStatusText:NSLocalizedString(@"ROM Loaded", nil)]; } @@ -283,7 +276,7 @@ if([self paused]) { [self setStatusText:NSLocalizedString(@"Emulation Reset", nil)]; - [video_output_view clearScreenWhite]; + [video_output_view setScreenState:[ScreenState whiteScreenState]]; } } @@ -400,7 +393,7 @@ [super closeROM]; //reset window - [video_output_view clearScreenBlack]; + [video_output_view setScreenState:[ScreenState blackScreenState]]; [self setStatusText:NSLocalizedString(@"No ROM Loaded", nil)]; //reset menu items @@ -517,25 +510,23 @@ return [self loadStateFromSlot:i]; } -- (void)resetMinSize +- (void)resetMinSize:(BOOL)resize_if_too_small { //keep the min size item up to date, just in case if([min_size_item target] == self) [min_size_item setState:no_smaller_than_ds?NSOnState:NSOffState]; + NSSize min_size; + if(!no_smaller_than_ds) { - [window setContentMinSize:NSMakeSize(10, status_bar_height - WINDOW_BORDER_PADDING)]; - return; - } - - NSSize min_size; - - if(video_output_view == nil) + min_size.width = 0; + min_size.height = 0; + } else if(video_output_view == nil) { min_size.width = DS_SCREEN_WIDTH; min_size.height = 0; - } else if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + } else if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) { min_size.width = DS_SCREEN_WIDTH; min_size.height = DS_SCREEN_HEIGHT_COMBINED; @@ -553,21 +544,23 @@ //set min content size for the window [window setContentMinSize:adjusted_min_size]; - //resize if too small - NSSize temp = [[window contentView] frame].size; - if(temp.width < adjusted_min_size.width && temp.height >= adjusted_min_size.height) - [self resizeScreen:NSMakeSize(min_size.width, temp.height)]; - else if(temp.width >= adjusted_min_size.width && temp.height < adjusted_min_size.height) - [self resizeScreen:NSMakeSize(temp.width, min_size.height)]; - else if(temp.width < adjusted_min_size.width && temp.height < adjusted_min_size.height) - [self resizeScreen:NSMakeSize(min_size.width, min_size.height)]; + if(resize_if_too_small) + { + NSSize temp = [[window contentView] frame].size; + if(temp.width < adjusted_min_size.width && temp.height >= adjusted_min_size.height) + [self resizeScreen:NSMakeSize(min_size.width, temp.height)]; + else if(temp.width >= adjusted_min_size.width && temp.height < adjusted_min_size.height) + [self resizeScreen:NSMakeSize(temp.width, min_size.height)]; + else if(temp.width < adjusted_min_size.width && temp.height < adjusted_min_size.height) + [self resizeScreen:NSMakeSize(min_size.width, min_size.height)]; + } } - (void)toggleMinSize { no_smaller_than_ds = !no_smaller_than_ds; - [self resetMinSize]; + [self resetMinSize:YES]; } - (void)resizeScreen:(NSSize)size @@ -599,7 +592,7 @@ { if(video_output_view == nil)return; - if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) [self resizeScreen:NSMakeSize(DS_SCREEN_WIDTH, DS_SCREEN_HEIGHT_COMBINED)]; else [self resizeScreen:NSMakeSize(DS_SCREEN_HEIGHT_COMBINED, DS_SCREEN_WIDTH)]; @@ -609,7 +602,7 @@ { if(video_output_view == nil)return; - if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) [self resizeScreen:NSMakeSize(DS_SCREEN_WIDTH * 2, DS_SCREEN_HEIGHT_COMBINED * 2)]; else [self resizeScreen:NSMakeSize(DS_SCREEN_HEIGHT_COMBINED * 2, DS_SCREEN_WIDTH * 2)]; @@ -619,7 +612,7 @@ { if(video_output_view == nil)return; - if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) [self resizeScreen:NSMakeSize(DS_SCREEN_WIDTH * 3, DS_SCREEN_HEIGHT_COMBINED * 3)]; else [self resizeScreen:NSMakeSize(DS_SCREEN_HEIGHT_COMBINED * 3, DS_SCREEN_WIDTH * 3)]; @@ -629,7 +622,7 @@ { if(video_output_view == nil)return; - if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) [self resizeScreen:NSMakeSize(DS_SCREEN_WIDTH * 4, DS_SCREEN_HEIGHT_COMBINED * 4)]; else [self resizeScreen:NSMakeSize(DS_SCREEN_HEIGHT_COMBINED * 4, DS_SCREEN_WIDTH * 4)]; @@ -654,9 +647,9 @@ if(location.x >= x_size)return NSMakePoint(-1, -1); if(location.y >= y_size)return NSMakePoint(-1, -1); - if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) { - if([video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == -180) { if(location.y < y_size / 2)return NSMakePoint(-1, -1); location.x = x_size - location.x; @@ -674,7 +667,7 @@ } else { - if([video_output_view rotation] == ROTATION_270) + if([video_output_view boundsRotation] == -270) { if(location.x < x_size / 2)return NSMakePoint(-1, -1); location.x = x_size - location.x; @@ -799,154 +792,58 @@ [video_output_view setFrame:rect]; //set new window min size - [self resetMinSize]; + [self resetMinSize:YES]; } -- (void)setRotation0 +- (void)setRotation:(float)rotation { - if(video_output_view == nil)return; + float current_rotation = [self rotation]; - if([video_output_view rotation] == ROTATION_0)return; - - if([video_output_view rotation] == ROTATION_180) - [video_output_view setRotation:ROTATION_0]; - - else + if(video_output_view && current_rotation != rotation) { - //set the rotation state - [video_output_view setRotation:ROTATION_0]; + NSSize size = [video_output_view frame].size; - //resize the window/view - NSSize video_size = [video_output_view frame].size; - float temp = video_size.width; - video_size.width = video_size.height; - video_size.height = temp; - [self resizeScreen:video_size]; + //rotate view bounds (negative because nsview does it counter-clockwise) + [video_output_view setBoundsRotation:-rotation]; + [video_output_view setNeedsDisplay:YES]; - //fix the min size - [self resetMinSize]; - } + //if view is to be rotated (not just flipped) + if(((current_rotation == 0 || current_rotation == 180) && (rotation == 90 || rotation == 270)) || + ((current_rotation == 90 || current_rotation == 270) && (rotation == 0 || rotation == 180))) + { + //swap x-y sizes + float temp = size.width; + size.width = size.height; + size.height = temp; - //set the checkmarks - if([rotation0_item target] == self) - [rotation0_item setState:NSOnState ]; - if([rotation90_item target] == self) - [rotation90_item setState:NSOffState]; - if([rotation180_item target] == self) - [rotation180_item setState:NSOffState]; - if([rotation270_item target] == self) - [rotation270_item setState:NSOffState]; -} - -- (void)setRotation90 -{ - if(video_output_view == nil)return; - - if([video_output_view rotation] == ROTATION_90)return; - - if([video_output_view rotation] == ROTATION_270) - [video_output_view setRotation:ROTATION_90]; - - else - { - //set the rotation state - [video_output_view setRotation:ROTATION_90]; - - //resize the window/screen - NSSize video_size = [video_output_view frame].size; - float temp = video_size.width; - video_size.width = video_size.height; - video_size.height = temp; - [self resizeScreen:video_size]; - - //fix min size - [self resetMinSize]; + //fit window + [self resetMinSize:NO]; + [self resizeScreen:size]; + } } //set the checkmarks + rotation = video_output_view ? [self rotation] : -1; //no checks set if video output is nil if([rotation0_item target] == self) - [rotation0_item setState:NSOffState]; + if(rotation == 0)[rotation0_item setState:NSOnState]; + else [rotation0_item setState:NSOffState]; if([rotation90_item target] == self) - [rotation90_item setState:NSOnState ]; + if(rotation == 90)[rotation90_item setState:NSOnState]; + else [rotation90_item setState:NSOffState]; if([rotation180_item target] == self) - [rotation180_item setState:NSOffState]; + if(rotation == 180)[rotation180_item setState:NSOnState]; + else [rotation180_item setState:NSOffState]; if([rotation270_item target] == self) - [rotation270_item setState:NSOffState]; + if(rotation == 270)[rotation270_item setState:NSOnState]; + else [rotation270_item setState:NSOffState]; } -- (void)setRotation180 -{ - if(video_output_view == nil)return; +- (void)setRotation0 { [self setRotation: 0]; } +- (void)setRotation90 { [self setRotation: 90]; } +- (void)setRotation180 { [self setRotation:180]; } +- (void)setRotation270 { [self setRotation:270]; } +- (float)rotation { return video_output_view ? -[video_output_view boundsRotation] : 0; } - if([video_output_view rotation] == ROTATION_180)return; - - if([video_output_view rotation] == ROTATION_0) - [video_output_view setRotation:ROTATION_180]; - - else - { - //set the rotation state - [video_output_view setRotation:ROTATION_180]; - - //resize the window/view - NSSize video_size = [video_output_view frame].size; - float temp = video_size.width; - video_size.width = video_size.height; - video_size.height = temp; - [self resizeScreen:video_size]; - - //fix the min size - [self resetMinSize]; - } - - //set the checkmarks - if([rotation0_item target] == self) - [rotation0_item setState:NSOffState]; - if([rotation90_item target] == self) - [rotation90_item setState:NSOffState]; - if([rotation180_item target] == self) - [rotation180_item setState:NSOnState ]; - if([rotation270_item target] == self) - [rotation270_item setState:NSOffState]; -} - -- (void)setRotation270 -{ - if(video_output_view == nil)return; - - if([video_output_view rotation] == ROTATION_270)return; - - if([video_output_view rotation] == ROTATION_90) - [video_output_view setRotation:ROTATION_270]; - - else - { - - //set the rotation state - [video_output_view setRotation:ROTATION_270]; - - //resize the window/screen - NSSize video_size = [video_output_view frame].size; - float temp = video_size.width; - video_size.width = video_size.height; - video_size.height = temp; - [self resizeScreen:video_size]; - - //fix the min size - [self resetMinSize]; - } - - //set the checkmarks - if([rotation0_item target] == self) - [rotation0_item setState:NSOffState]; - if([rotation90_item target] == self) - [rotation90_item setState:NSOffState]; - if([rotation180_item target] == self) - [rotation180_item setState:NSOffState]; - if([rotation270_item target] == self) - [rotation270_item setState:NSOnState]; -} - - (void)toggleTopBackground0 { [super toggleTopBackground0]; @@ -1070,8 +967,8 @@ #define APPRX_EQL(a, b) ((b >= (a - 1)) && (b <= (a + 1))) //take rotation into account - CGFloat ds_screen_width = (([video_output_view rotation] == ROTATION_0) || ([video_output_view rotation] == ROTATION_180)) ? DS_SCREEN_WIDTH : DS_SCREEN_HEIGHT_COMBINED; - CGFloat ds_screen_height = (([video_output_view rotation] == ROTATION_0) || ([video_output_view rotation] == ROTATION_180)) ? DS_SCREEN_HEIGHT_COMBINED : DS_SCREEN_WIDTH; + CGFloat ds_screen_width = (([video_output_view boundsRotation] == 0) || ([video_output_view boundsRotation] == -180)) ? DS_SCREEN_WIDTH : DS_SCREEN_HEIGHT_COMBINED; + CGFloat ds_screen_height = (([video_output_view boundsRotation] == 0) || ([video_output_view boundsRotation] == -180)) ? DS_SCREEN_HEIGHT_COMBINED : DS_SCREEN_WIDTH; if(APPRX_EQL(size.width, ds_screen_width) && APPRX_EQL(size.height, ds_screen_height)) { @@ -1136,7 +1033,7 @@ //this is a simple algorithm to constrain to the smallest axis NSSize constrained_size; - if([video_output_view rotation] == ROTATION_0 || [video_output_view rotation] == ROTATION_180) + if([video_output_view boundsRotation] == 0 || [video_output_view boundsRotation] == -180) { //this is a simple algorithm to constrain to the smallest axis @@ -1323,38 +1220,9 @@ [subBG3_item setState:NSOnState]; else [subBG3_item setState:NSOffState]; - if(video_output_view == nil) - { - [rotation0_item setState:NSOffState ]; - [rotation90_item setState:NSOffState]; - [rotation180_item setState:NSOffState]; - [rotation270_item setState:NSOffState]; - } else if([video_output_view rotation] == ROTATION_0) - { - [rotation0_item setState:NSOnState ]; - [rotation90_item setState:NSOffState]; - [rotation180_item setState:NSOffState]; - [rotation270_item setState:NSOffState]; - } else if([video_output_view rotation] == ROTATION_90) - { - [rotation0_item setState:NSOffState]; - [rotation90_item setState:NSOnState ]; - [rotation180_item setState:NSOffState]; - [rotation270_item setState:NSOffState]; - } else if([video_output_view rotation] == ROTATION_180) - { - [rotation0_item setState:NSOffState]; - [rotation90_item setState:NSOffState]; - [rotation180_item setState:NSOnState ]; - [rotation270_item setState:NSOffState]; - } else if([video_output_view rotation] == ROTATION_270) - { - [rotation0_item setState:NSOffState]; - [rotation90_item setState:NSOffState]; - [rotation180_item setState:NSOffState]; - [rotation270_item setState:NSOnState ]; - } else messageDialog(NSLocalizedString(@"Error", nil), @"Corrupt rotation variable"); + [self setRotation:[self rotation]]; + //SOUND Menu int volume; [mute_item setTarget:self]; Modified: trunk/desmume/src/cocoa/nds_control.h =================================================================== --- trunk/desmume/src/cocoa/nds_control.h 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/nds_control.h 2008-09-20 20:25:02 UTC (rev 977) @@ -19,17 +19,11 @@ #import "globals.h" +@class ScreenState; + #define MAX_SLOTS 10 #define MAX_FRAME_SKIP 10 -#define DS_SCREEN_WIDTH 256 -#define DS_SCREEN_HEIGHT 192 -#define DS_BPP 2 //bytes per pixel -#define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.0)) -#define DS_SCREEN_Y_RATIO ((192.0 * 2.0) / 256.0) - -@class ScreenState; - //This class is a compelte objective-c wrapper for //the core emulation features, other objective-c code inherit //upon or instanciate this to add interfaces for these features @@ -183,27 +177,3 @@ - (void)toggleMute; - (BOOL)muted; @end - -enum ScreenRotation { ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270 }; - -//This class is used to return screen data at the end of a frame -//we wrap it in a obj-c class so it can be passed to a selector -//and so we get retain/release niftyness -@interface ScreenState : NSObject -{ - enum ScreenRotation rotation; - unsigned char color_data[DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP]; -} -- (id)init; -- (id)initWithScreenState:(ScreenState*)state; -- (NSInteger)width; -- (NSInteger)height; -- (NSSize)size; -- (void)fillWithWhite; -- (void)fillWithBlack; -- (NSBitmapImageRep*)imageRep; -- (void)setRotation:(enum ScreenRotation)rotation; -- (enum ScreenRotation)rotation; -- (void)setColorData:(const unsigned char*)data; -- (const unsigned char*)colorData; -@end Modified: trunk/desmume/src/cocoa/nds_control.mm =================================================================== --- trunk/desmume/src/cocoa/nds_control.mm 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/nds_control.mm 2008-09-20 20:25:02 UTC (rev 977) @@ -20,9 +20,12 @@ #import "nds_control.h" #import "preferences.h" #import "sndOSX.h" +#import "screen_state.h" +#ifdef HAVE_OPENGL #import <OpenGL/OpenGL.h> #import <OpenGL/gl.h> +#endif //DeSmuME general includes #define OBJ_C @@ -47,7 +50,9 @@ GPU3DInterface *core3DList[] = { &gpu3DNull, +#ifdef HAVE_OPENGL &gpu3Dgl, +#endif NULL }; @@ -109,6 +114,7 @@ NDS_CreateDummyFirmware(&firmware); //3D Init +#ifdef HAVE_OPENGL NSOpenGLContext *prev_context = [NSOpenGLContext currentContext]; [prev_context retain]; @@ -194,6 +200,7 @@ [prev_context release]; } else [NSOpenGLContext clearCurrentContext]; +#endif //Sound Init if(SPU_ChangeSoundCore(SNDCORE_OSX, 735 * 4) != 0) @@ -1225,9 +1232,11 @@ { NSAutoreleasePool *autorelease = [[NSAutoreleasePool alloc] init]; +#ifdef HAVE_OPENGL [gl_context retain]; [gl_context makeCurrentContext]; CGLLockContext((CGLContextObj)[gl_context CGLContextObj]); +#endif u32 cycles = 0; @@ -1301,8 +1310,7 @@ { last_video_update = frame_end_time; - ScreenState *new_screen_data = [[ScreenState alloc] init]; - [new_screen_data setColorData:GPU_screen]; + ScreenState *new_screen_data = [[ScreenState alloc] initWithColorData:GPU_screen]; if(timer_based) { //for tiger compatibility @@ -1334,8 +1342,11 @@ [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:.1]]; } +#ifdef HAVE_OPENGL CGLUnlockContext((CGLContextObj)[gl_context CGLContextObj]); [gl_context release]; +#endif + [autorelease release]; paused = true; @@ -1343,191 +1354,3 @@ } @end - -////////////////////// -// ScreenState -////////////////////// - -@implementation ScreenState -- (id)init -{ - self = [super init]; - if(self == nil)return nil; - - rotation = ROTATION_0; - - return self; -} - -- (id)initWithScreenState:(ScreenState*)state -{ - self = [super init]; - if(self == nil)return nil; - - rotation = state->rotation; - memcpy(color_data, state->color_data, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); - - return self; -} - -- (NSInteger)width -{ - if(rotation==ROTATION_90 || rotation==ROTATION_270) - return DS_SCREEN_HEIGHT*2; - return DS_SCREEN_WIDTH; -} - -- (NSInteger)height -{ - if(rotation==ROTATION_90 || rotation==ROTATION_270) - return DS_SCREEN_WIDTH; - return DS_SCREEN_HEIGHT*2; -} - -- (NSSize)size -{ - NSSize result; - - if(rotation==ROTATION_90 || rotation==ROTATION_270) - { - result.width = DS_SCREEN_HEIGHT*2; - result.height = DS_SCREEN_WIDTH; - } else - { - result.width = DS_SCREEN_WIDTH; - result.height = DS_SCREEN_HEIGHT*2; - } - - return result; -} - -- (void)fillWithWhite -{ - memset(color_data, 255, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); -} - -- (void)fillWithBlack -{ - memset(color_data, 0, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); -} - -- (NSBitmapImageRep*)imageRep -{ - NSInteger width = [self width]; - NSInteger height = [self height]; - - NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL - pixelsWide:width - pixelsHigh:height - bitsPerSample:8 - samplesPerPixel:3 - hasAlpha:NO - isPlanar:NO - colorSpaceName:NSCalibratedRGBColorSpace - bytesPerRow:width * 3 - bitsPerPixel:24]; - - if(image == nil)return nil; - - u8 *bitmap_data = [image bitmapData]; - - const u16 *buffer_16 = (u16*)color_data; - - int i; - for(i = 0; i < width * height; i++) - { //this loop we go through pixel by pixel and convert from 16bit to 24bit for the NSImage - *(bitmap_data++) = (*buffer_16 & 0x001F) << 3; - *(bitmap_data++) = (*buffer_16 & 0x03E0) >> 5 << 3; - *(bitmap_data++) = (*buffer_16 & 0x7C00) >> 10 << 3; - buffer_16++; - } - - [image autorelease]; - - return image; -} - -- (void)setRotation:(enum ScreenRotation)rot -{ - if(rotation == rot)return; - - //here is where we turn the screen sideways - //if you can think of a more clever way to do this than making - //a full copy of the screen data, please implement it! - - const int width = [self width], height = [self height]; - - if((rotation==ROTATION_0 && rot==ROTATION_90) - ||(rotation==ROTATION_90 && rot==ROTATION_180) - ||(rotation==ROTATION_180 && rot==ROTATION_270) - ||(rotation==ROTATION_270 && rot==ROTATION_0)) - { //90 degree clockwise rotation - unsigned char temp_buffer[width * height * DS_BPP]; - memcpy(temp_buffer, color_data, width * height * DS_BPP); - - int x, y; - for(x = 0; x< width; x++) - for(y = 0; y < height; y++) - { - color_data[(x * height + (height - y - 1)) * 2] = temp_buffer[(y * width + x) * 2]; - color_data[(x * height + (height - y - 1)) * 2 + 1] = temp_buffer[(y * width + x) * 2 + 1]; - } - - rotation = rot; - } - - if((rotation==ROTATION_0 && rot==ROTATION_180) - ||(rotation==ROTATION_90 && rot==ROTATION_270) - ||(rotation==ROTATION_180 && rot==ROTATION_0) - ||(rotation==ROTATION_270 && rot==ROTATION_90)) - { //180 degree rotation - unsigned char temp_buffer[width * height * DS_BPP]; - memcpy(temp_buffer, color_data, width * height * DS_BPP); - - int x, y; - for(x = 0; x < width; x++) - for(y = 0; y < height; y++) - { - color_data[(x * height + y) * 2] = temp_buffer[((width - x - 1) * height + (height - y - 1)) * 2]; - color_data[(x * height + y) * 2 + 1] = temp_buffer[((width - x - 1) * height + (height - y - 1)) * 2 + 1]; - } - - rotation = rot; - } - - if((rotation==ROTATION_0 && rot==ROTATION_270) - ||(rotation==ROTATION_90 && rot==ROTATION_0) - ||(rotation==ROTATION_180 && rot==ROTATION_90) - ||(rotation==ROTATION_270 && rot==ROTATION_180)) - { //-90 degrees - unsigned char temp_buffer[width * height * DS_BPP]; - memcpy(temp_buffer, color_data, width * height * DS_BPP); - - int x, y; - for(x = 0; x< width; x++) - for(y = 0; y < height; y++) - { - color_data[((width - x - 1) * height + y) * 2] = temp_buffer[(y * width + x) * 2]; - color_data[((width - x - 1) * height + y) * 2 + 1] = temp_buffer[(y * width + x) * 2 + 1]; - } - - rotation = rot; - } - -} - -- (enum ScreenRotation)rotation -{ - return rotation; -} - -- (void)setColorData:(const unsigned char*)data -{ - memcpy(color_data, data, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); -} - -- (const unsigned char*)colorData -{ - return color_data; -} -@end Added: trunk/desmume/src/cocoa/screen_state.h =================================================================== --- trunk/desmume/src/cocoa/screen_state.h (rev 0) +++ trunk/desmume/src/cocoa/screen_state.h 2008-09-20 20:25:02 UTC (rev 977) @@ -0,0 +1,48 @@ +/* Copyright (C) 2007 Jeff Bland + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import "globals.h" + +#define DS_BPP 2 //bytes per pixel +#define DS_SCREEN_X_RATIO (256.0 / (192.0 * 2.0)) +#define DS_SCREEN_Y_RATIO ((192.0 * 2.0) / 256.0) +#define DS_SCREEN_WIDTH 256 +#define DS_SCREEN_HEIGHT 192 + +//This class is used to return screen data at the end of a frame +//we wrap it in a obj-c class so it can be passed to a selector +//and so we get retain/release niftyness +@interface ScreenState : NSObject +{ + @private + unsigned char color_data[DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP]; +} ++ (NSInteger)width; ++ (NSInteger)height; ++ (NSSize)size; ++ (ScreenState*)blackScreenState; ++ (ScreenState*)whiteScreenState; +- (id)initWithBlack; +- (id)initWithWhite; +- (id)initWithScreenState:(ScreenState*)state; +- (id)initWithColorData:(const unsigned char*)data; +- (const unsigned char*)colorData; +- (NSImage*)image; +- (NSBitmapImageRep*)imageRep; +@end \ No newline at end of file Added: trunk/desmume/src/cocoa/screen_state.m =================================================================== --- trunk/desmume/src/cocoa/screen_state.m (rev 0) +++ trunk/desmume/src/cocoa/screen_state.m 2008-09-20 20:25:02 UTC (rev 977) @@ -0,0 +1,125 @@ +/* Copyright (C) 2007 Jeff Bland + + This file is part of DeSmuME + + DeSmuME 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. + + DeSmuME 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 DeSmuME; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#import "screen_state.h" + +@implementation ScreenState ++ (NSInteger)width +{ + return DS_SCREEN_WIDTH; +} + ++ (NSInteger)height +{ + return DS_SCREEN_HEIGHT*2; +} + ++ (NSSize)size +{ + return NSMakeSize(DS_SCREEN_WIDTH, DS_SCREEN_HEIGHT*2); +} + ++ (ScreenState*)blackScreenState +{ + return [[[ScreenState alloc] initWithBlack] autorelease]; +} + ++ (ScreenState*)whiteScreenState; +{ + return [[[ScreenState alloc] initWithWhite] autorelease]; +} + +- (id)init +{ + //make sure we go through through the designated init function + [self doesNotRecognizeSelector:_cmd]; + return nil; +} + +- (id)initWithBlack +{ + self = [super init]; + if(self)memset(color_data, 0, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); + return self; +} + +- (id)initWithWhite +{ + self = [super init]; + if(self)memset(color_data, 255, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); + return self; +} + +- (id)initWithScreenState:(ScreenState*)state +{ + self = [super init]; + if(self)memcpy(color_data, state->color_data, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); + return self; +} + +- (id)initWithColorData:(const unsigned char*)data +{ + self = [super init]; + if(self)memcpy(color_data, data, DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2 * DS_BPP); + return self; +} + +- (const unsigned char*)colorData +{ + return color_data; +} + +- (NSImage*)image +{ + NSImage *result = [[NSImage alloc] initWithSize:[ScreenState size]]; + [result addRepresentation:[self imageRep]]; + return [result autorelease]; +} + +- (NSBitmapImageRep*)imageRep +{ + NSBitmapImageRep *image = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:DS_SCREEN_WIDTH + pixelsHigh:DS_SCREEN_HEIGHT*2 + bitsPerSample:8 + samplesPerPixel:3 + hasAlpha:NO + isPlanar:NO + colorSpaceName:NSCalibratedRGBColorSpace + bytesPerRow:DS_SCREEN_WIDTH*3 + bitsPerPixel:24]; + + if(image == nil)return nil; + + unsigned char *bitmap_data = [image bitmapData]; + + const unsigned short *buffer_16 = (unsigned short*)color_data; + + int i; + for(i = 0; i < DS_SCREEN_WIDTH * DS_SCREEN_HEIGHT*2; i++) + { //this loop we go through pixel by pixel and convert from 16bit to 24bit for the NSImage + *(bitmap_data++) = (*buffer_16 & 0x001F) << 3; + *(bitmap_data++) = (*buffer_16 & 0x03E0) >> 5 << 3; + *(bitmap_data++) = (*buffer_16 & 0x7C00) >> 10 << 3; + buffer_16++; + } + + return [image autorelease]; +} +@end \ No newline at end of file Modified: trunk/desmume/src/cocoa/video_output_view.h =================================================================== --- trunk/desmume/src/cocoa/video_output_view.h 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/video_output_view.h 2008-09-20 20:25:02 UTC (rev 977) @@ -19,22 +19,32 @@ #import "nds_control.h" -@interface VideoOutputView : NSView +//This class uses OpenGL for drawing for speed +//if opengl is not available it uses NSImage + +@class ScreenState; + +@interface VideoOutputView : +#ifdef HAVE_OPENGL +NSView +#else +NSImageView +#endif { - enum ScreenRotation rotation; +#ifdef HAVE_OPENGL NSOpenGLContext* context; +#endif ScreenState *screen_buffer; } +//init - (id)initWithFrame:(NSRect)frame; -- (void)dealloc; -- (void)setRotation:(enum ScreenRotation)rotation; -- (enum ScreenRotation)rotation; -- (void)drawRect:(NSRect)bounds; -- (void)setFrame:(NSRect)rect; -- (BOOL)isOpaque; -- (void)clearScreenBlack; -- (void)clearScreenWhite; -- (void)updateScreen:(ScreenState*)screen; + +//image to display +- (void)setScreenState:(ScreenState*)screen; - (const ScreenState*)screenState; + +//size in pixels of screen display (disreguarding rotation of the view) +- (float)screenHeight; +- (float)screenWidth; @end Modified: trunk/desmume/src/cocoa/video_output_view.m =================================================================== --- trunk/desmume/src/cocoa/video_output_view.m 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/cocoa/video_output_view.m 2008-09-20 20:25:02 UTC (rev 977) @@ -18,10 +18,23 @@ */ #import "video_output_view.h" -#import "nds_control.h" //for screenstate +#import "screen_state.h" +#define HORIZONTAL(angle) ((angle) == -90 || (angle) == -270) +#define VERTICAL(angle) ((angle) == 0 || (angle) == -180) + +#ifdef HAVE_OPENGL #import <OpenGL/gl.h> +#endif +#ifdef HAVE_OPENGL +//screenstate extended to hold rotated copies +@interface ScreenState(extended) +- (void)rotateTo90; +- (void)rotateTo0; +@end +#endif + @implementation VideoOutputView - (id)initWithFrame:(NSRect)frame @@ -35,24 +48,18 @@ messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't create a view for video output"); return nil; } + + screen_buffer = nil; - //Init the screen buffer ------------------------------------------------------------- - - screen_buffer = [[ScreenState alloc] init]; - - if(screen_buffer == nil) - { - messageDialog(NSLocalizedString(@"Error", nil), @"Couldn't initialize screen view data"); - - //we dont return in this case because we will hopefully get new screen buffers - //constantly as emulation is going on, so this just means that there will be no display before emulation starts - } - - //fill with black to represent initial off state - else [screen_buffer fillWithBlack]; - + //Initialize image view if for displaying the screen ---------------------------------------- +#ifndef HAVE_OPENGL + [self setImageFrameStyle: NSImageFrameNone]; + [self setImageScaling:NSScaleToFit]; + [self setEditable:NO]; + [self setEnabled:NO]; + //Initialize the OpenGL context for displaying the screen ----------------------------------- - +#else //Create the pixel format for our video output view NSOpenGLPixelFormatAttribute attrs[] = { @@ -82,53 +89,97 @@ } } - //this will init opengl for drawing + //init gl for drawing [self setFrame:frame]; + [self setBoundsRotation:0]; +#endif + //init screen buffer + [self setScreenState:[ScreenState blackScreenState]]; + return self; } - (void)dealloc { +#ifdef HAVE_OPENGL [context release]; +#endif [screen_buffer release]; [super dealloc]; } -- (void)setRotation:(enum ScreenRotation)rot +- (void)setScreenState:(ScreenState*)screen { - if(rot == rotation)return; - - //note that we use an optimization - - //rotation 180 is stored as rotation 0 - //and rotation 270 us stored as rotation 90 - //and using opengl we flip it (which is hopefully faster than rotating it manually) + if(screen_buffer == screen)return; - if((rot == ROTATION_180) || (rot == ROTATION_0)) - [screen_buffer setRotation:ROTATION_0]; - else if((rot == ROTATION_270) || (rot == ROTATION_90)) - [screen_buffer setRotation:ROTATION_90]; - else return; //invalid rotation value passed to this function + if(screen == nil) + { + messageDialog(NSLocalizedString(@"Error", nil), @"Recieved invalid screen update"); + return; + } - rotation = rot; - - [self setFrame:[self frame]]; //reset gl state to reflect new orientation - [self setNeedsDisplay:YES]; + [screen_buffer release]; //get rid of old screen data + screen_buffer = screen; + [screen_buffer retain]; //retain the new screendata since we will need it if we have to redraw before we recieve another update + + //rotate the screen +#ifdef HAVE_OPENGL + if(HORIZONTAL([self boundsRotation]))[screen_buffer rotateTo90]; +#endif + + //redraw +#ifdef HAVE_OPENGL + [self display]; +#else + [self setImage:[screen_buffer image]]; +#endif } -- (enum ScreenRotation)rotation +- (const ScreenState*)screenState { - return rotation; +#ifdef HAVE_OPENGL + ScreenState *temp = [[ScreenState alloc] initWithScreenState:screen_buffer]; + if(HORIZONTAL([self boundsRotation]))[temp rotateTo0]; + return temp; +#else + return screen_buffer; +#endif } +- (float)screenWidth +{ + return DS_SCREEN_WIDTH; +} + +- (float)screenHeight +{ + return DS_SCREEN_HEIGHT*2; +} + +#ifdef HAVE_OPENGL +- (void)viewDidMoveToWindow +{ + //the setView message doesnt work if the view + //isn't in a window, which is the case in the init func + //so we use this callback to bind the context to the window + + if([self window] != nil) + [context setView:self]; + else + [context clearDrawable]; +} +#endif + +#ifdef HAVE_OPENGL - (void)drawRect:(NSRect)bounds { if(screen_buffer == nil)return; //simply dont draw anything if we dont have a screen data object allocated [context makeCurrentContext]; - if(rotation == ROTATION_0 || rotation == ROTATION_180) + if([self boundsRotation] == 0 || [self boundsRotation] == -180) { //here we send our corrected video buffer off to OpenGL where it gets pretty much //directly copied to the frame buffer (and converted to the devices color format) @@ -140,7 +191,9 @@ glFlush(); } +#endif +#ifdef HAVE_OPENGL - (void)setFrame:(NSRect)rect { [super setFrame:rect]; @@ -151,45 +204,29 @@ //set the viewport (so the raster pos will be correct) glViewport(0, 0, rect.size.width, rect.size.height); - if(rotation == ROTATION_0) + float angle = [self boundsRotation]; + + if(angle == 0) { - - //the raster pos controls where the bitmap where will be placed glRasterPos2f(-1, 1); - - //set the pixel zoom so our bitmap streches to fit our new opengl size glPixelZoom(((float)rect.size.width) / ((float)DS_SCREEN_WIDTH), -((float)rect.size.height) / ((float)DS_SCREEN_HEIGHT*2)); - - } else if (rotation == ROTATION_90) + } else if(angle == -90) { - - //the raster pos controls where the bitmap where will be placed glRasterPos2f(-1, 1); - - //set the pixel zoom so our bitmap streches to fit our new opengl size glPixelZoom(((float)rect.size.width) / ((float)DS_SCREEN_HEIGHT*2), -((float)rect.size.height) / ((float)DS_SCREEN_WIDTH)); - - } else if (rotation == ROTATION_180) + } else if (angle == -180) { - - //the raster pos controls where the bitmap where will be placed glRasterPos2f(1, -1); - - //set the pixel zoom so our bitmap streches to fit our new opengl size glPixelZoom(-((float)rect.size.width) / ((float)DS_SCREEN_WIDTH), ((float)rect.size.height) / ((float)DS_SCREEN_HEIGHT*2)); - - } else if (rotation == ROTATION_270) + } else if (angle == -270) { - //the raster pos controls where the bitmap where will be placed glRasterPos2f(1, -1); - - //set the pixel zoom so our bitmap streches to fit our new opengl size glPixelZoom(-((float)rect.size.width) / ((float)DS_SCREEN_HEIGHT*2), ((float)rect.size.height) / ((float)DS_SCREEN_WIDTH)); - } - } +#endif +#ifdef HAVE_OPENGL - (BOOL)isOpaque { if(screen_buffer) @@ -199,67 +236,80 @@ //so this view is completely transparent return NO; } +#endif -- (void)updateScreen:(ScreenState*)screen +#ifdef HAVE_OPENGL +- (void)setBoundsRotation:(CGFloat)angle { - if(screen == nil) + float old_angle = [self boundsRotation]; + + [super setBoundsRotation:angle]; + + [context makeCurrentContext]; + + NSSize size = [self frame].size; + + if(angle == 0) { - messageDialog(NSLocalizedString(@"Error", nil), @"Recieved invalid screen update"); - return; + glRasterPos2f(-1, 1); + glPixelZoom(((float)size.width) / ((float)DS_SCREEN_WIDTH), -((float)size.height) / ((float)DS_SCREEN_HEIGHT*2)); + } else if(angle == -90) + { + glRasterPos2f(-1, 1); + glPixelZoom(((float)size.width) / ((float)DS_SCREEN_HEIGHT*2), -((float)size.height) / ((float)DS_SCREEN_WIDTH)); + } else if (angle == -180) + { + glRasterPos2f(1, -1); + glPixelZoom(-((float)size.width) / ((float)DS_SCREEN_WIDTH), ((float)size.height) / ((float)DS_SCREEN_HEIGHT*2)); + } else if (angle == -270) + { + glRasterPos2f(1, -1); + glPixelZoom(-((float)size.width) / ((float)DS_SCREEN_HEIGHT*2), ((float)size.height) / ((float)DS_SCREEN_WIDTH)); } - [screen_buffer release]; //get rid of old screen data - screen_buffer = screen; - [screen_buffer retain]; //retain the new screendata since we will need it if we have to redraw before we recieve another update + //Rotate the screen buffer + if(HORIZONTAL(angle) && VERTICAL(old_angle)) + [screen_buffer rotateTo90]; - //if the screen needs to be rotated - if(rotation == ROTATION_90 || rotation == ROTATION_270) - [screen_buffer setRotation:ROTATION_90]; // - - //then video output view draws from that buffer - [self display]; + if(VERTICAL(angle) && HORIZONTAL(old_angle)) + [screen_buffer rotateTo0]; } +#endif +@end -- (void)clearScreenWhite +#ifdef HAVE_OPENGL +@implementation ScreenState (extended) +- (void)rotateTo90 { - [screen_buffer fillWithWhite]; - [self display]; -} + int width = [ScreenState width], height = [ScreenState height]; -- (void)clearScreenBlack -{ - [screen_buffer fillWithBlack]; - [self display]; -} + unsigned char temp_buffer[width * height * DS_BPP]; + memcpy(temp_buffer, color_data, width * height * DS_BPP); -- (void)viewDidMoveToWindow -{ - //the setView message doesnt work if the view - //isn't in a window, which is the case in the init func - //so we use this callback to bind the context to the window - - if([self window] != nil) - [context setView:self]; - else - [context clearDrawable]; + int x, y; + for(x = 0; x< width; x++) + for(y = 0; y < height; y++) + { + color_data[(x * height + (height - y - 1)) * 2] = temp_buffer[(y * width + x) * 2]; + color_data[(x * height + (height - y - 1)) * 2 + 1] = temp_buffer[(y * width + x) * 2 + 1]; + } } -- (const ScreenState*)screenState +- (void)rotateTo0 { - ScreenState *result; + int height = [ScreenState width], width = [ScreenState height]; - if(rotation == ROTATION_180) - { - result = [[ScreenState alloc] initWithScreenState:screen_buffer]; - [result setRotation:ROTATION_180]; - } else if(rotation == ROTATION_270) - { - result = [[ScreenState alloc] initWithScreenState:screen_buffer]; - [result setRotation:ROTATION_270]; - } else result = screen_buffer; + unsigned char temp_buffer[width * height * DS_BPP]; + memcpy(temp_buffer, color_data, width * height * DS_BPP); - return result; + int x, y; + for(x = 0; x< width; x++) + for(y = 0; y < height; y++) + { + color_data[((width - x - 1) * height + y) * 2] = temp_buffer[(y * width + x) * 2]; + color_data[((width - x - 1) * height + y) * 2 + 1] = temp_buffer[(y * width + x) * 2 + 1]; + } } - @end +#endif Modified: trunk/desmume/src/saves.cpp =================================================================== --- trunk/desmume/src/saves.cpp 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/saves.cpp 2008-09-20 20:25:02 UTC (rev 977) @@ -227,7 +227,7 @@ u8 sram_read (u32 address) { address = address - SRAM_ADDRESS; - + if ( address > SRAM_SIZE ) return 0; @@ -241,11 +241,11 @@ if ( address < SRAM_SIZE ) MMU.CART_RAM[address] = value; - + } int sram_load (const char *file_name) { - + FILE *file; file = fopen ( file_name, "rb" ); @@ -378,10 +378,10 @@ write32le(sf->s,os); for(int i=0;i<count;i++) { - + #ifndef LOCAL_LE if(rlsb) - FlipByteOrder(sf->v,sf->s&(~SS_FLAGS)); + FlipByteOrder((u8*)sf->v,sf->s&(~SS_FLAGS)); #endif if(sf->s&SS_INDIRECT) @@ -392,7 +392,7 @@ //Now restore the original byte order. #ifndef LOCAL_LE if(rlsb) - FlipByteOrder(sf->v,sf->s&(~SS_FLAGS)); + FlipByteOrder((u8*)sf->v,sf->s&(~SS_FLAGS)); #endif } Modified: trunk/desmume/src/types.h =================================================================== --- trunk/desmume/src/types.h 2008-09-19 08:15:54 UTC (rev 976) +++ trunk/desmume/src/types.h 2008-09-20 20:25:02 UTC (rev 977) @@ -173,10 +173,10 @@ #ifdef LOCAL_BE /* local arch is big endian */ # define LE_TO_LOCAL_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff)) # define LE_TO_LOCAL_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff)) -# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00))|(((x)>>40)&0xff00))|(((x)>>56)&0xff)) +# define LE_TO_LOCAL_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff)) # define LOCAL_TO_LE_16(x) ((((x)&0xff)<<8)|(((x)>>8)&0xff)) # define LOCAL_TO_LE_32(x) ((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)>>8)&0xff00)|(((x)>>24)&0xff)) -# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00))|(((x)>>40)&0xff00))|(((x)>>56)&0xff)) +# define LOCAL_TO_LE_64(x) ((((x)&0xff)<<56)|(((x)&0xff00)<<40)|(((x)&0xff0000)<<24)|(((x)&0xff000000)<<8)|(((x)>>8)&0xff000000)|(((x)>>24)&0xff00)|(((x)>>40)&0xff00)|(((x)>>56)&0xff)) #else /* local arch is little endian */ # define LE_TO_LOCAL_16(x) (x) # define LE_TO_LOCAL_32(x) (x) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |