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
This commit is contained in:
parent
cddc94aa9b
commit
73f5bdbcce
|
@ -508,7 +508,7 @@ void setTexture(unsigned int format, unsigned int texpal)
|
|||
{
|
||||
//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 @@ void setTexture(unsigned int format, unsigned int texpal)
|
|||
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;
|
||||
|
|
|
@ -43,6 +43,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA]]>
|
|||
<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 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA]]>
|
|||
<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 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA]]>
|
|||
<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 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA]]>
|
|||
<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" />
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -12,10 +12,10 @@ compile = {
|
|||
: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',
|
||||
|
|
|
@ -85,10 +85,12 @@
|
|||
- (void)toggleStatusBar;
|
||||
|
||||
//rotation
|
||||
- (void)setRotation:(float)rotation;
|
||||
- (void)setRotation0;
|
||||
- (void)setRotation90;
|
||||
- (void)setRotation180;
|
||||
- (void)setRotation270;
|
||||
- (float)rotation;
|
||||
|
||||
//layers
|
||||
- (void)toggleTopBackground0;
|
||||
|
|
|
@ -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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
[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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
//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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
[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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
if([self paused])
|
||||
{
|
||||
[self setStatusText:NSLocalizedString(@"Emulation Reset", nil)];
|
||||
[video_output_view clearScreenWhite];
|
||||
[video_output_view setScreenState:[ScreenState whiteScreenState]];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,7 +393,7 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
[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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
//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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
{
|
||||
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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
{
|
||||
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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
{
|
||||
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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
{
|
||||
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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
} 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,153 +792,57 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
[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;
|
||||
|
||||
//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:NSOnState ];
|
||||
if(rotation == 0)[rotation0_item setState:NSOnState];
|
||||
else [rotation0_item setState:NSOffState];
|
||||
if([rotation90_item target] == self)
|
||||
[rotation90_item setState:NSOffState];
|
||||
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)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];
|
||||
}
|
||||
|
||||
//set the checkmarks
|
||||
if([rotation0_item target] == self)
|
||||
[rotation0_item setState:NSOffState];
|
||||
if([rotation90_item target] == self)
|
||||
[rotation90_item setState:NSOnState ];
|
||||
if([rotation180_item target] == self)
|
||||
[rotation180_item setState:NSOffState];
|
||||
if([rotation270_item target] == self)
|
||||
[rotation270_item setState:NSOffState];
|
||||
}
|
||||
|
||||
- (void)setRotation180
|
||||
{
|
||||
if(video_output_view == nil)return;
|
||||
|
||||
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)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; }
|
||||
|
||||
- (void)toggleTopBackground0
|
||||
{
|
||||
|
@ -1070,8 +967,8 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
#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 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
//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,37 +1220,8 @@ NSMenuItem *screenshot_to_file_item = nil;
|
|||
[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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 @@ volatile desmume_BOOL execute = true;
|
|||
|
||||
GPU3DInterface *core3DList[] = {
|
||||
&gpu3DNull,
|
||||
#ifdef HAVE_OPENGL
|
||||
&gpu3Dgl,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -109,6 +114,7 @@ bool opengl_init()
|
|||
NDS_CreateDummyFirmware(&firmware);
|
||||
|
||||
//3D Init
|
||||
#ifdef HAVE_OPENGL
|
||||
NSOpenGLContext *prev_context = [NSOpenGLContext currentContext];
|
||||
[prev_context retain];
|
||||
|
||||
|
@ -194,6 +200,7 @@ bool opengl_init()
|
|||
[prev_context release];
|
||||
} else
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
#endif
|
||||
|
||||
//Sound Init
|
||||
if(SPU_ChangeSoundCore(SNDCORE_OSX, 735 * 4) != 0)
|
||||
|
@ -1225,9 +1232,11 @@ bool opengl_init()
|
|||
{
|
||||
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 @@ bool opengl_init()
|
|||
{
|
||||
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 @@ bool opengl_init()
|
|||
[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 @@ bool opengl_init()
|
|||
}
|
||||
|
||||
@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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -18,9 +18,22 @@
|
|||
*/
|
||||
|
||||
#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
|
||||
|
||||
|
@ -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,126 +89,31 @@
|
|||
}
|
||||
}
|
||||
|
||||
//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
|
||||
|
||||
rotation = rot;
|
||||
|
||||
[self setFrame:[self frame]]; //reset gl state to reflect new orientation
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
- (enum ScreenRotation)rotation
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
- (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)
|
||||
{
|
||||
//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)
|
||||
glDrawPixels(DS_SCREEN_WIDTH, DS_SCREEN_HEIGHT*2, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (const GLvoid*)[screen_buffer colorData]);
|
||||
} else
|
||||
{
|
||||
glDrawPixels(DS_SCREEN_HEIGHT*2, DS_SCREEN_WIDTH, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (const GLvoid*)[screen_buffer colorData]);
|
||||
}
|
||||
|
||||
glFlush();
|
||||
}
|
||||
|
||||
- (void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
|
||||
[context update];
|
||||
[context makeCurrentContext];
|
||||
|
||||
//set the viewport (so the raster pos will be correct)
|
||||
glViewport(0, 0, rect.size.width, rect.size.height);
|
||||
|
||||
if(rotation == ROTATION_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)
|
||||
{
|
||||
|
||||
//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)
|
||||
{
|
||||
|
||||
//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)
|
||||
{
|
||||
//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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)isOpaque
|
||||
{
|
||||
if(screen_buffer)
|
||||
return YES;
|
||||
|
||||
//if there is no screen buffer, then we can't draw anything
|
||||
//so this view is completely transparent
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)updateScreen:(ScreenState*)screen
|
||||
{
|
||||
if(screen == nil)
|
||||
{
|
||||
messageDialog(NSLocalizedString(@"Error", nil), @"Recieved invalid screen update");
|
||||
|
@ -212,26 +124,41 @@
|
|||
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
|
||||
|
||||
//if the screen needs to be rotated
|
||||
if(rotation == ROTATION_90 || rotation == ROTATION_270)
|
||||
[screen_buffer setRotation:ROTATION_90]; //
|
||||
//rotate the screen
|
||||
#ifdef HAVE_OPENGL
|
||||
if(HORIZONTAL([self boundsRotation]))[screen_buffer rotateTo90];
|
||||
#endif
|
||||
|
||||
//then video output view draws from that buffer
|
||||
//redraw
|
||||
#ifdef HAVE_OPENGL
|
||||
[self display];
|
||||
#else
|
||||
[self setImage:[screen_buffer image]];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)clearScreenWhite
|
||||
- (const ScreenState*)screenState
|
||||
{
|
||||
[screen_buffer fillWithWhite];
|
||||
[self display];
|
||||
#ifdef HAVE_OPENGL
|
||||
ScreenState *temp = [[ScreenState alloc] initWithScreenState:screen_buffer];
|
||||
if(HORIZONTAL([self boundsRotation]))[temp rotateTo0];
|
||||
return temp;
|
||||
#else
|
||||
return screen_buffer;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)clearScreenBlack
|
||||
- (float)screenWidth
|
||||
{
|
||||
[screen_buffer fillWithBlack];
|
||||
[self display];
|
||||
return DS_SCREEN_WIDTH;
|
||||
}
|
||||
|
||||
- (float)screenHeight
|
||||
{
|
||||
return DS_SCREEN_HEIGHT*2;
|
||||
}
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
- (void)viewDidMoveToWindow
|
||||
{
|
||||
//the setView message doesnt work if the view
|
||||
|
@ -243,23 +170,146 @@
|
|||
else
|
||||
[context clearDrawable];
|
||||
}
|
||||
#endif
|
||||
|
||||
- (const ScreenState*)screenState
|
||||
#ifdef HAVE_OPENGL
|
||||
- (void)drawRect:(NSRect)bounds
|
||||
{
|
||||
ScreenState *result;
|
||||
if(screen_buffer == nil)return; //simply dont draw anything if we dont have a screen data object allocated
|
||||
|
||||
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;
|
||||
[context makeCurrentContext];
|
||||
|
||||
return result;
|
||||
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)
|
||||
glDrawPixels(DS_SCREEN_WIDTH, DS_SCREEN_HEIGHT*2, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (const GLvoid*)[screen_buffer colorData]);
|
||||
} else
|
||||
{
|
||||
glDrawPixels(DS_SCREEN_HEIGHT*2, DS_SCREEN_WIDTH, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, (const GLvoid*)[screen_buffer colorData]);
|
||||
}
|
||||
|
||||
glFlush();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
- (void)setFrame:(NSRect)rect
|
||||
{
|
||||
[super setFrame:rect];
|
||||
|
||||
[context update];
|
||||
[context makeCurrentContext];
|
||||
|
||||
//set the viewport (so the raster pos will be correct)
|
||||
glViewport(0, 0, rect.size.width, rect.size.height);
|
||||
|
||||
float angle = [self boundsRotation];
|
||||
|
||||
if(angle == 0)
|
||||
{
|
||||
glRasterPos2f(-1, 1);
|
||||
glPixelZoom(((float)rect.size.width) / ((float)DS_SCREEN_WIDTH), -((float)rect.size.height) / ((float)DS_SCREEN_HEIGHT*2));
|
||||
} else if(angle == -90)
|
||||
{
|
||||
glRasterPos2f(-1, 1);
|
||||
glPixelZoom(((float)rect.size.width) / ((float)DS_SCREEN_HEIGHT*2), -((float)rect.size.height) / ((float)DS_SCREEN_WIDTH));
|
||||
} else if (angle == -180)
|
||||
{
|
||||
glRasterPos2f(1, -1);
|
||||
glPixelZoom(-((float)rect.size.width) / ((float)DS_SCREEN_WIDTH), ((float)rect.size.height) / ((float)DS_SCREEN_HEIGHT*2));
|
||||
} else if (angle == -270)
|
||||
{
|
||||
glRasterPos2f(1, -1);
|
||||
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)
|
||||
return YES;
|
||||
|
||||
//if there is no screen buffer, then we can't draw anything
|
||||
//so this view is completely transparent
|
||||
return NO;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
- (void)setBoundsRotation:(CGFloat)angle
|
||||
{
|
||||
float old_angle = [self boundsRotation];
|
||||
|
||||
[super setBoundsRotation:angle];
|
||||
|
||||
[context makeCurrentContext];
|
||||
|
||||
NSSize size = [self frame].size;
|
||||
|
||||
if(angle == 0)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
//Rotate the screen buffer
|
||||
if(HORIZONTAL(angle) && VERTICAL(old_angle))
|
||||
[screen_buffer rotateTo90];
|
||||
|
||||
if(VERTICAL(angle) && HORIZONTAL(old_angle))
|
||||
[screen_buffer rotateTo0];
|
||||
}
|
||||
#endif
|
||||
@end
|
||||
|
||||
#ifdef HAVE_OPENGL
|
||||
@implementation ScreenState (extended)
|
||||
- (void)rotateTo90
|
||||
{
|
||||
int width = [ScreenState width], height = [ScreenState height];
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)rotateTo0
|
||||
{
|
||||
int height = [ScreenState width], width = [ScreenState height];
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
||||
@end
|
||||
#endif
|
||||
|
||||
|
|
|
@ -227,7 +227,7 @@ void loadstate_slot(int num)
|
|||
|
||||
u8 sram_read (u32 address) {
|
||||
address = address - SRAM_ADDRESS;
|
||||
|
||||
|
||||
if ( address > SRAM_SIZE )
|
||||
return 0;
|
||||
|
||||
|
@ -241,11 +241,11 @@ void sram_write (u32 address, u8 value) {
|
|||
|
||||
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 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
|
|||
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 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
|
|||
//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
|
||||
|
||||
}
|
||||
|
|
|
@ -173,10 +173,10 @@ typedef int desmume_BOOL;
|
|||
#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)
|
||||
|
|
Loading…
Reference in New Issue