Cocoa Port:

- Do some small optimizations to the windowing system.
- Fix an occasional crashing bug that sometimes occurred when changing the display mode.
- Do some code cleanup.
This commit is contained in:
rogerman 2013-01-05 01:32:05 +00:00
parent 777fd6bc78
commit effc847ee0
6 changed files with 411 additions and 293 deletions

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -352,6 +352,7 @@ enum
// Video Messages
MESSAGE_RESIZE_VIEW,
MESSAGE_TRANSFORM_VIEW,
MESSAGE_REDRAW_VIEW,
MESSAGE_SET_GPU_STATE_FLAGS,
MESSAGE_CHANGE_DISPLAY_TYPE,

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -23,11 +23,28 @@
#import "cocoa_util.h"
typedef struct
{
double scale;
double rotation; // Angle is in degrees
double translationX;
double translationY;
double translationZ;
} DisplayOutputTransformData;
typedef struct
{
NSInteger displayModeID;
unsigned int width; // Measured in pixels
unsigned int height; // Measured in pixels
} DisplaySrcPixelAttributes;
@interface CocoaDSOutput : CocoaDSThread
{
BOOL isStateChanged;
NSUInteger frameCount;
NSData *frameData;
NSData *frameAttributesData;
NSMutableDictionary *property;
pthread_mutex_t *mutexProducer;
@ -37,12 +54,13 @@
@property (assign) BOOL isStateChanged;
@property (assign) NSUInteger frameCount;
@property (retain) NSData *frameData;
@property (retain) NSData *frameAttributesData;
@property (readonly) NSMutableDictionary *property;
@property (assign) pthread_mutex_t *mutexProducer;
@property (readonly) pthread_mutex_t *mutexConsume;
- (void) doCoreEmuFrame;
- (void) handleEmuFrameProcessed:(NSData *)theData;
- (void) handleEmuFrameProcessed:(NSData *)mainData attributes:(NSData *)attributesData;
@end
@ -95,7 +113,7 @@
@protocol CocoaDSDisplayDelegate <NSObject>
@required
- (void) doDisplayTypeChanged:(NSInteger)displayTypeID;
- (void) doDisplayModeChanged:(NSInteger)displayModeID;
@property (retain) NSPort *sendPortDisplay;
@property (assign) BOOL isHudEnabled;
@ -107,10 +125,11 @@
@required
- (void) doInitVideoOutput:(NSDictionary *)properties;
- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize;
- (void) doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight;
@optional
- (void) doResizeView:(NSRect)rect;
- (void) doTransformView:(DisplayOutputTransformData *)transformData;
- (void) doRedraw;
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID;
- (void) doDisplayOrderChanged:(NSInteger)displayOrderID;
@ -125,7 +144,7 @@
{
UInt32 gpuStateFlags;
id <CocoaDSDisplayDelegate> delegate;
NSInteger displayType;
NSInteger displayMode;
NSSize frameSize;
pthread_mutex_t *mutexRender3D;
@ -144,7 +163,7 @@
@property (assign) UInt32 gpuStateFlags;
@property (retain) id <CocoaDSDisplayDelegate> delegate;
@property (assign) NSInteger displayType;
@property (assign) NSInteger displayMode;
@property (readonly) NSSize frameSize;
@property (readonly) pthread_mutex_t *mutexRender3D;
@ -166,7 +185,7 @@
- (BOOL) render3DLineHack;
- (void) handleChangeGpuStateFlags:(NSData *)flagsData;
- (void) handleChangeDisplayType:(NSData *)displayTypeIdData;
- (void) handleChangeDisplayMode:(NSData *)displayModeData;
- (void) handleSetRender3DRenderingEngine:(NSData *)methodIdData;
- (void) handleSetRender3DHighPrecisionColorInterpolation:(NSData *)stateData;
- (void) handleSetRender3DEdgeMarking:(NSData *)stateData;
@ -180,7 +199,7 @@
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData;
- (void) handleCopyToPasteboard;
- (void) fillVideoFrameWithColor:(UInt8)colorValue;
- (void) fillVideoFrameWithColor:(UInt16)colorValue;
- (NSImage *) image;
- (NSBitmapImageRep *) bitmapImageRep;
@ -196,15 +215,17 @@
{
CocoaVideoFilter *vf;
id <CocoaDSDisplayVideoDelegate> videoDelegate;
NSInteger lastDisplayMode;
OSSpinLock spinlockVideoFilterType;
OSSpinLock spinlockVfSrcBuffer;
OSSpinLock spinlockVFBuffers;
}
@property (retain) id <CocoaDSDisplayVideoDelegate> delegate;
@property (assign) CocoaVideoFilter *vf;
- (void) handleResizeView:(NSData *)rectData;
- (void) handleTransformView:(NSData *)transformData;
- (void) handleRedrawView;
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData;
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData;
@ -220,10 +241,10 @@ extern "C"
#endif
void HandleMessageEchoResponse(NSPortMessage *portMessage);
void SetGPULayerState(int displayType, unsigned int i, bool state);
bool GetGPULayerState(int displayType, unsigned int i);
void SetGPUDisplayState(int displayType, bool state);
bool GetGPUDisplayState(int displayType);
void SetGPULayerState(int gpuType, unsigned int i, bool state);
bool GetGPULayerState(int gpuType, unsigned int i);
void SetGPUDisplayState(int gpuType, bool state);
bool GetGPUDisplayState(int gpuType);
void SetOpenGLRendererFunctions(bool (*initFunction)(),
bool (*beginOGLFunction)(),

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -45,6 +45,7 @@ GPU3DInterface *core3DList[] = {
@synthesize isStateChanged;
@synthesize frameCount;
@synthesize frameData;
@synthesize frameAttributesData;
@synthesize property;
@synthesize mutexProducer;
@synthesize mutexConsume;
@ -60,6 +61,7 @@ GPU3DInterface *core3DList[] = {
isStateChanged = NO;
frameCount = 0;
frameData = nil;
frameAttributesData = nil;
property = [[NSMutableDictionary alloc] init];
[property setValue:[NSDate date] forKey:@"outputTime"];
@ -85,6 +87,7 @@ GPU3DInterface *core3DList[] = {
}
self.frameData = nil;
self.frameAttributesData = nil;
[property release];
pthread_mutex_destroy(mutexConsume);
@ -107,7 +110,7 @@ GPU3DInterface *core3DList[] = {
switch (message)
{
case MESSAGE_EMU_FRAME_PROCESSED:
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]];
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0] attributes:[messageComponents objectAtIndex:1]];
break;
default:
@ -116,10 +119,11 @@ GPU3DInterface *core3DList[] = {
}
}
- (void) handleEmuFrameProcessed:(NSData *)theData
- (void) handleEmuFrameProcessed:(NSData *)mainData attributes:(NSData *)attributesData
{
self.frameCount++;
self.frameData = theData;
self.frameData = mainData;
self.frameAttributesData = attributesData;
}
@end
@ -353,7 +357,7 @@ GPU3DInterface *core3DList[] = {
switch (message)
{
case MESSAGE_EMU_FRAME_PROCESSED:
[self handleEmuFrameProcessed:nil];
[self handleEmuFrameProcessed:nil attributes:nil];
break;
case MESSAGE_SET_AUDIO_PROCESS_METHOD:
@ -386,47 +390,47 @@ GPU3DInterface *core3DList[] = {
}
}
- (void) handleEmuFrameProcessed:(NSData *)theData
- (void) handleEmuFrameProcessed:(NSData *)mainData attributes:(NSData *)attributesData
{
SPU_Emulate_user();
[super handleEmuFrameProcessed:theData];
[super handleEmuFrameProcessed:mainData attributes:attributesData];
}
- (void) handleSetVolume:(NSData *)volumeData
{
const float *vol = (float *)[volumeData bytes];
[self setVolume:*vol];
const float vol = *(float *)[volumeData bytes];
[self setVolume:vol];
}
- (void) handleSetAudioOutputEngine:(NSData *)methodIdData
{
const NSInteger *methodID = (NSInteger *)[methodIdData bytes];
[self setAudioOutputEngine:*methodID];
const NSInteger methodID = *(NSInteger *)[methodIdData bytes];
[self setAudioOutputEngine:methodID];
}
- (void) handleSetSpuAdvancedLogic:(NSData *)stateData
{
const BOOL *theState = (BOOL *)[stateData bytes];
[self setSpuAdvancedLogic:*theState];
const BOOL theState = *(BOOL *)[stateData bytes];
[self setSpuAdvancedLogic:theState];
}
- (void) handleSetSpuSyncMode:(NSData *)modeIdData
{
const NSInteger *modeID = (NSInteger *)[modeIdData bytes];
[self setSpuSyncMode:*modeID];
const NSInteger modeID = *(NSInteger *)[modeIdData bytes];
[self setSpuSyncMode:modeID];
}
- (void) handleSetSpuSyncMethod:(NSData *)methodIdData
{
const NSInteger *methodID = (NSInteger *)[methodIdData bytes];
[self setSpuSyncMethod:*methodID];
const NSInteger methodID = *(NSInteger *)[methodIdData bytes];
[self setSpuSyncMethod:methodID];
}
- (void) handleSetSpuInterpolationMode:(NSData *)modeIdData
{
const NSInteger *modeID = (NSInteger *)[modeIdData bytes];
[self setSpuInterpolationMode:*modeID];
const NSInteger modeID = *(NSInteger *)[modeIdData bytes];
[self setSpuInterpolationMode:modeID];
}
@end
@ -435,7 +439,7 @@ GPU3DInterface *core3DList[] = {
@synthesize gpuStateFlags;
@dynamic delegate;
@dynamic displayType;
@dynamic displayMode;
@dynamic frameSize;
@synthesize mutexRender3D;
@ -462,7 +466,8 @@ GPU3DInterface *core3DList[] = {
spinlockRender3DThreads = OS_SPINLOCK_INIT;
spinlockRender3DLineHack = OS_SPINLOCK_INIT;
displayType = DS_DISPLAY_TYPE_COMBO;
delegate = nil;
displayMode = DS_DISPLAY_TYPE_COMBO;
frameSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT * 2);
gpuStateFlags = GPUSTATE_MAIN_GPU_MASK |
@ -478,10 +483,6 @@ GPU3DInterface *core3DList[] = {
GPUSTATE_SUB_BG3_MASK |
GPUSTATE_SUB_OBJ_MASK;
frameCount = 0;
frameData = nil;
delegate = nil;
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateMainGPU"];
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateMainBG0"];
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateMainBG1"];
@ -494,7 +495,7 @@ GPU3DInterface *core3DList[] = {
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateSubBG2"];
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateSubBG3"];
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateSubOBJ"];
[property setValue:[NSNumber numberWithInteger:displayType] forKey:@"displayMode"];
[property setValue:[NSNumber numberWithInteger:displayMode] forKey:@"displayMode"];
[property setValue:NSSTRING_DISPLAYMODE_MAIN forKey:@"displayModeString"];
[property setValue:[NSNumber numberWithInteger:CORE3DLIST_NULL] forKey:@"render3DRenderingEngine"];
[property setValue:[NSNumber numberWithBool:YES] forKey:@"render3DHighPrecisionColorInterpolation"];
@ -702,12 +703,12 @@ GPU3DInterface *core3DList[] = {
return flags;
}
- (void) setDisplayType:(NSInteger)dispType
- (void) setDisplayMode:(NSInteger)displayModeID
{
NSString *newDispString = nil;
NSSize newFrameSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT);
switch (dispType)
switch (displayModeID)
{
case DS_DISPLAY_TYPE_MAIN:
newDispString = NSSTRING_DISPLAYMODE_MAIN;
@ -728,20 +729,20 @@ GPU3DInterface *core3DList[] = {
}
OSSpinLockLock(&spinlockDisplayType);
displayType = dispType;
displayMode = displayModeID;
frameSize = newFrameSize;
[property setValue:[NSNumber numberWithInteger:dispType] forKey:@"displayMode"];
[property setValue:[NSNumber numberWithInteger:displayModeID] forKey:@"displayMode"];
[property setValue:newDispString forKey:@"displayModeString"];
OSSpinLockUnlock(&spinlockDisplayType);
}
- (NSInteger) displayType
- (NSInteger) displayMode
{
OSSpinLockLock(&spinlockDisplayType);
NSInteger dispType = displayType;
NSInteger displayModeID = displayMode;
OSSpinLockUnlock(&spinlockDisplayType);
return dispType;
return displayModeID;
}
- (NSSize) frameSize
@ -977,29 +978,36 @@ GPU3DInterface *core3DList[] = {
- (void) doCoreEmuFrame
{
NSData *gpuData = nil;
NSInteger dispType = self.displayType;
NSInteger displayModeID = [self displayMode];
NSSize displayFrameSize = [self frameSize];
// Here, we copy the raw GPU data from the emulation core.
//
// The core data contains the GPU pixels from both the main and touch screens. So
// depending on the display type, we copy only the pixels from the respective screen.
if (dispType == DS_DISPLAY_TYPE_MAIN)
if (displayModeID == DS_DISPLAY_TYPE_MAIN)
{
gpuData = [[NSData alloc] initWithBytes:GPU_screen length:GPU_SCREEN_SIZE_BYTES];
}
else if(dispType == DS_DISPLAY_TYPE_TOUCH)
else if(displayModeID == DS_DISPLAY_TYPE_TOUCH)
{
gpuData = [[NSData alloc] initWithBytes:(GPU_screen + GPU_SCREEN_SIZE_BYTES) length:GPU_SCREEN_SIZE_BYTES];
}
else if(dispType == DS_DISPLAY_TYPE_COMBO)
else if(displayModeID == DS_DISPLAY_TYPE_COMBO)
{
gpuData = [[NSData alloc] initWithBytes:GPU_screen length:GPU_SCREEN_SIZE_BYTES * 2];
}
[CocoaDSUtil messageSendOneWayWithData:self.receivePort msgID:MESSAGE_EMU_FRAME_PROCESSED data:gpuData];
DisplaySrcPixelAttributes attr = {displayModeID, (unsigned int)displayFrameSize.width, (unsigned int)displayFrameSize.height};
NSData *attributesData = [[NSData alloc] initWithBytes:&attr length:sizeof(DisplaySrcPixelAttributes)];
NSArray *messageComponents = [[NSArray alloc] initWithObjects:gpuData, attributesData, nil];
[CocoaDSUtil messageSendOneWayWithMessageComponents:self.receivePort msgID:MESSAGE_EMU_FRAME_PROCESSED array:messageComponents];
// Now that we've finished sending the GPU data, release the local copy.
[gpuData release];
[attributesData release];
[messageComponents release];
}
- (void)handlePortMessage:(NSPortMessage *)portMessage
@ -1010,7 +1018,7 @@ GPU3DInterface *core3DList[] = {
switch (message)
{
case MESSAGE_EMU_FRAME_PROCESSED:
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]];
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0] attributes:[messageComponents objectAtIndex:1]];
break;
case MESSAGE_SET_GPU_STATE_FLAGS:
@ -1018,7 +1026,7 @@ GPU3DInterface *core3DList[] = {
break;
case MESSAGE_CHANGE_DISPLAY_TYPE:
[self handleChangeDisplayType:[messageComponents objectAtIndex:0]];
[self handleChangeDisplayMode:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_SET_RENDER3D_METHOD:
@ -1075,97 +1083,97 @@ GPU3DInterface *core3DList[] = {
}
}
- (void) handleEmuFrameProcessed:(NSData *)theData
- (void) handleEmuFrameProcessed:(NSData *)mainData attributes:(NSData *)attributesData
{
[super handleEmuFrameProcessed:theData];
[super handleEmuFrameProcessed:mainData attributes:attributesData];
}
- (void) handleChangeGpuStateFlags:(NSData *)flagsData
{
const NSInteger *flags = (NSInteger *)[flagsData bytes];
self.gpuStateFlags = (UInt32)*flags;
[self handleEmuFrameProcessed:self.frameData];
const NSInteger flags = *(NSInteger *)[flagsData bytes];
self.gpuStateFlags = (UInt32)flags;
[self handleEmuFrameProcessed:self.frameData attributes:self.frameAttributesData];
}
- (void) handleChangeDisplayType:(NSData *)displayTypeIdData
- (void) handleChangeDisplayMode:(NSData *)displayModeData
{
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayTypeChanged:)])
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayModeChanged:)])
{
return;
}
const NSInteger *theType = (NSInteger *)[displayTypeIdData bytes];
self.displayType = *theType;
[delegate doDisplayTypeChanged:*theType];
const NSInteger displayModeID = *(NSInteger *)[displayModeData bytes];
self.displayMode = displayModeID;
[delegate doDisplayModeChanged:displayModeID];
}
- (void) handleSetRender3DRenderingEngine:(NSData *)methodIdData
{
const NSInteger *methodID = (NSInteger *)[methodIdData bytes];
[self setRender3DRenderingEngine:*methodID];
const NSInteger methodID = *(NSInteger *)[methodIdData bytes];
[self setRender3DRenderingEngine:methodID];
}
- (void) handleSetRender3DHighPrecisionColorInterpolation:(NSData *)stateData
{
const BOOL *theState = (BOOL *)[stateData bytes];
[self setRender3DHighPrecisionColorInterpolation:*theState];
const BOOL theState = *(BOOL *)[stateData bytes];
[self setRender3DHighPrecisionColorInterpolation:theState];
}
- (void) handleSetRender3DEdgeMarking:(NSData *)stateData
{
const BOOL *theState = (BOOL *)[stateData bytes];
[self setRender3DEdgeMarking:*theState];
const BOOL theState = *(BOOL *)[stateData bytes];
[self setRender3DEdgeMarking:theState];
}
- (void) handleSetRender3DFog:(NSData *)stateData
{
const BOOL *theState = (BOOL *)[stateData bytes];
[self setRender3DFog:*theState];
const BOOL theState = *(BOOL *)[stateData bytes];
[self setRender3DFog:theState];
}
- (void) handleSetRender3DTextures:(NSData *)stateData
{
const BOOL *theState = (BOOL *)[stateData bytes];
[self setRender3DTextures:*theState];
const BOOL theState = *(BOOL *)[stateData bytes];
[self setRender3DTextures:theState];
}
- (void) handleSetRender3DDepthComparisonThreshold:(NSData *)thresholdData
{
const NSUInteger *threshold = (NSUInteger *)[thresholdData bytes];
[self setRender3DDepthComparisonThreshold:*threshold];
const NSUInteger threshold = *(NSUInteger *)[thresholdData bytes];
[self setRender3DDepthComparisonThreshold:threshold];
}
- (void) handleSetRender3DThreads:(NSData *)numberThreadsData
{
const NSUInteger *numberThreads = (NSUInteger *)[numberThreadsData bytes];
[self setRender3DThreads:*numberThreads];
const NSUInteger numberThreads = *(NSUInteger *)[numberThreadsData bytes];
[self setRender3DThreads:numberThreads];
}
- (void) handleSetRender3DLineHack:(NSData *)stateData
{
const BOOL *theState = (BOOL *)[stateData bytes];
[self setRender3DLineHack:*theState];
const BOOL theState = *(BOOL *)[stateData bytes];
[self setRender3DLineHack:theState];
}
- (void) handleSetViewToBlack
{
[self fillVideoFrameWithColor:0];
[self fillVideoFrameWithColor:0x8000];
}
- (void) handleSetViewToWhite
{
[self fillVideoFrameWithColor:255];
[self fillVideoFrameWithColor:0xFFFF];
}
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData
{
NSString *fileURLString = [[NSString alloc] initWithData:fileURLStringData encoding:NSUTF8StringEncoding];
NSURL *fileURL = [NSURL URLWithString:fileURLString];
NSBitmapImageFileType *fileType = (NSBitmapImageFileType *)[fileTypeData bytes];
NSBitmapImageFileType fileType = *(NSBitmapImageFileType *)[fileTypeData bytes];
NSDictionary *userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
fileURL, @"fileURL",
[NSNumber numberWithInteger:(NSInteger)*fileType], @"fileType",
[NSNumber numberWithInteger:(NSInteger)fileType], @"fileType",
[self image], @"screenshotImage",
nil];
@ -1188,22 +1196,35 @@ GPU3DInterface *core3DList[] = {
[pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType];
}
- (void) fillVideoFrameWithColor:(UInt8)colorValue
- (void) fillVideoFrameWithColor:(UInt16)colorValue
{
UInt16 *gpuBytes = (UInt16 *)malloc(GPU_SCREEN_SIZE_BYTES * 2);
NSData *gpuData = nil;
NSInteger displayModeID = [self displayMode];
NSSize displayFrameSize = [self frameSize];
size_t numberBytes = GPU_SCREEN_SIZE_BYTES * 2;
if (displayModeID == DS_DISPLAY_TYPE_MAIN || displayModeID == DS_DISPLAY_TYPE_TOUCH)
{
numberBytes = GPU_SCREEN_SIZE_BYTES;
}
UInt16 *gpuBytes = (UInt16 *)malloc(numberBytes);
if (gpuBytes == NULL)
{
return;
}
memset(gpuBytes, colorValue, GPU_SCREEN_SIZE_BYTES * 2);
NSData *gpuData = [[[NSData alloc] initWithBytes:gpuBytes length:GPU_SCREEN_SIZE_BYTES * 2] autorelease];
const UInt16 colorValuePattern[] = {colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue, colorValue};
memset_pattern16(gpuBytes, colorValuePattern, numberBytes);
gpuData = [[[NSData alloc] initWithBytes:gpuBytes length:numberBytes] autorelease];
free(gpuBytes);
gpuBytes = nil;
[self handleEmuFrameProcessed:gpuData];
DisplaySrcPixelAttributes attr = {displayModeID, (unsigned int)displayFrameSize.width, (unsigned int)displayFrameSize.height};
NSData *attributesData = [[[NSData alloc] initWithBytes:&attr length:sizeof(DisplaySrcPixelAttributes)] autorelease];
[self handleEmuFrameProcessed:gpuData attributes:attributesData];
}
- (NSImage *) image
@ -1384,9 +1405,10 @@ GPU3DInterface *core3DList[] = {
}
videoDelegate = nil;
lastDisplayMode = DS_DISPLAY_TYPE_COMBO;
spinlockVideoFilterType = OS_SPINLOCK_INIT;
spinlockVfSrcBuffer = OS_SPINLOCK_INIT;
spinlockVFBuffers = OS_SPINLOCK_INIT;
if ([[NSProcessInfo processInfo] activeProcessorCount] >= 2)
{
@ -1443,18 +1465,11 @@ GPU3DInterface *core3DList[] = {
return theDelegate;
}
- (void) setDisplayType:(NSInteger)dispType
{
[super setDisplayType:dispType];
OSSpinLockLock(&spinlockVfSrcBuffer);
[vf setSourceSize:self.frameSize];
OSSpinLockUnlock(&spinlockVfSrcBuffer);
}
- (void) setVfType:(NSInteger)videoFilterTypeID
{
OSSpinLockLock(&spinlockVFBuffers);
[vf changeFilter:(VideoFilterTypeID)videoFilterTypeID];
OSSpinLockUnlock(&spinlockVFBuffers);
OSSpinLockLock(&spinlockVideoFilterType);
[property setValue:[NSNumber numberWithInteger:videoFilterTypeID] forKey:@"videoFilterType"];
@ -1488,13 +1503,17 @@ GPU3DInterface *core3DList[] = {
switch (message)
{
case MESSAGE_EMU_FRAME_PROCESSED:
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]];
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0] attributes:[messageComponents objectAtIndex:1]];
break;
case MESSAGE_RESIZE_VIEW:
[self handleResizeView:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_TRANSFORM_VIEW:
[self handleTransformView:[messageComponents objectAtIndex:0]];
break;
case MESSAGE_REDRAW_VIEW:
[self handleRedrawView];
break;
@ -1525,39 +1544,43 @@ GPU3DInterface *core3DList[] = {
}
}
- (void) handleEmuFrameProcessed:(NSData *)theData
- (void) handleEmuFrameProcessed:(NSData *)mainData attributes:(NSData *)attributesData
{
if (theData == nil)
if (mainData == nil || attributesData == nil)
{
return;
}
NSSize destSize = [vf destSize];
size_t dataSize = (size_t)destSize.width * (size_t)destSize.height * sizeof(UInt32);
if ([vf typeID] == VideoFilterTypeID_None)
{
destSize = self.frameSize;
dataSize = (size_t)destSize.width * (size_t)destSize.height * sizeof(UInt16);
}
const DisplaySrcPixelAttributes attr = *(DisplaySrcPixelAttributes *)[attributesData bytes];
const NSInteger displayModeID = attr.displayModeID;
// Tell the video delegate to process the video frame with our copied GPU data.
OSSpinLockLock(&spinlockVFBuffers);
if (lastDisplayMode != displayModeID)
{
const NSSize newSrcSize = NSMakeSize((CGFloat)attr.width, (CGFloat)attr.height);
[vf setSourceSize:newSrcSize];
lastDisplayMode = displayModeID;
}
const NSInteger destWidth = (NSInteger)[vf destSize].width;
const NSInteger destHeight = (NSInteger)[vf destSize].height;
if ([vf typeID] == VideoFilterTypeID_None)
{
[videoDelegate doProcessVideoFrame:[theData bytes] frameSize:self.frameSize];
[videoDelegate doProcessVideoFrame:[mainData bytes] displayMode:displayModeID width:destWidth height:destHeight];
}
else
{
NSSize srcSize = [vf srcSize];
OSSpinLockLock(&spinlockVfSrcBuffer);
RGBA5551ToRGBA8888Buffer((const uint16_t *)[theData bytes], (uint32_t *)[vf srcBufferPtr], ((unsigned int)srcSize.width * (unsigned int)srcSize.height));
OSSpinLockUnlock(&spinlockVfSrcBuffer);
UInt32 *vfDestBuffer = [vf runFilter];
[videoDelegate doProcessVideoFrame:vfDestBuffer frameSize:[vf destSize]];
RGBA5551ToRGBA8888Buffer((const uint16_t *)[mainData bytes], (uint32_t *)[vf srcBufferPtr], [mainData length] / sizeof(UInt16));
const UInt32 *vfDestBuffer = [vf runFilter];
[videoDelegate doProcessVideoFrame:vfDestBuffer displayMode:displayModeID width:destWidth height:destHeight];
}
OSSpinLockUnlock(&spinlockVFBuffers);
[super handleEmuFrameProcessed:theData];
[super handleEmuFrameProcessed:mainData attributes:attributesData];
}
- (void) handleResizeView:(NSData *)rectData
@ -1567,8 +1590,18 @@ GPU3DInterface *core3DList[] = {
return;
}
const NSRect *resizeRect = (NSRect *)[rectData bytes];
[videoDelegate doResizeView:*resizeRect];
const NSRect resizeRect = *(NSRect *)[rectData bytes];
[videoDelegate doResizeView:resizeRect];
}
- (void) handleTransformView:(NSData *)transformData
{
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doTransformView:)])
{
return;
}
[videoDelegate doTransformView:(DisplayOutputTransformData *)[transformData bytes]];
}
- (void) handleRedrawView
@ -1588,8 +1621,8 @@ GPU3DInterface *core3DList[] = {
return;
}
const NSInteger *theOrientation = (NSInteger *)[displayOrientationIdData bytes];
[videoDelegate doDisplayOrientationChanged:*theOrientation];
const NSInteger theOrientation = *(NSInteger *)[displayOrientationIdData bytes];
[videoDelegate doDisplayOrientationChanged:theOrientation];
}
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData
@ -1599,8 +1632,8 @@ GPU3DInterface *core3DList[] = {
return;
}
const NSInteger *theOrder = (NSInteger *)[displayOrderIdData bytes];
[videoDelegate doDisplayOrderChanged:*theOrder];
const NSInteger theOrder = *(NSInteger *)[displayOrderIdData bytes];
[videoDelegate doDisplayOrderChanged:theOrder];
}
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData
@ -1610,9 +1643,9 @@ GPU3DInterface *core3DList[] = {
return;
}
const BOOL *theState = (BOOL *)[bilinearStateData bytes];
[videoDelegate doBilinearOutputChanged:*theState];
[self handleEmuFrameProcessed:self.frameData];
const BOOL theState = *(BOOL *)[bilinearStateData bytes];
[videoDelegate doBilinearOutputChanged:theState];
[self handleEmuFrameProcessed:self.frameData attributes:self.frameAttributesData];
}
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData
@ -1622,8 +1655,8 @@ GPU3DInterface *core3DList[] = {
return;
}
const BOOL *theState = (BOOL *)[verticalSyncStateData bytes];
[videoDelegate doVerticalSyncChanged:*theState];
const BOOL theState = *(BOOL *)[verticalSyncStateData bytes];
[videoDelegate doVerticalSyncChanged:theState];
}
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData
@ -1633,10 +1666,10 @@ GPU3DInterface *core3DList[] = {
return;
}
const NSInteger *theType = (NSInteger *)[videoFilterTypeIdData bytes];
[self setVfType:*theType];
[videoDelegate doVideoFilterChanged:*theType frameSize:[vf destSize]];
[self handleEmuFrameProcessed:self.frameData];
const NSInteger theType = *(NSInteger *)[videoFilterTypeIdData bytes];
[self setVfType:theType];
[videoDelegate doVideoFilterChanged:theType frameSize:[vf destSize]];
[self handleEmuFrameProcessed:self.frameData attributes:self.frameAttributesData];
}
@end
@ -1651,7 +1684,7 @@ void HandleMessageEchoResponse(NSPortMessage *portMessage)
[sendDate release];
}
void SetGPULayerState(int displayType, unsigned int i, bool state)
void SetGPULayerState(int gpuType, unsigned int i, bool state)
{
GPU *theGpu = NULL;
@ -1661,7 +1694,7 @@ void SetGPULayerState(int displayType, unsigned int i, bool state)
return;
}
switch (displayType)
switch (gpuType)
{
case DS_GPU_TYPE_MAIN:
theGpu = SubScreen.gpu;
@ -1693,7 +1726,7 @@ void SetGPULayerState(int displayType, unsigned int i, bool state)
}
}
bool GetGPULayerState(int displayType, unsigned int i)
bool GetGPULayerState(int gpuType, unsigned int i)
{
bool result = false;
@ -1703,7 +1736,7 @@ bool GetGPULayerState(int displayType, unsigned int i)
return result;
}
switch (displayType)
switch (gpuType)
{
case DS_GPU_TYPE_MAIN:
if (SubScreen.gpu != nil)
@ -1733,9 +1766,9 @@ bool GetGPULayerState(int displayType, unsigned int i)
return result;
}
void SetGPUDisplayState(int displayType, bool state)
void SetGPUDisplayState(int gpuType, bool state)
{
switch (displayType)
switch (gpuType)
{
case DS_GPU_TYPE_MAIN:
CommonSettings.showGpu.sub = state;
@ -1755,11 +1788,11 @@ void SetGPUDisplayState(int displayType, bool state)
}
}
bool GetGPUDisplayState(int displayType)
bool GetGPUDisplayState(int gpuType)
{
bool result = false;
switch (displayType)
switch (gpuType)
{
case DS_GPU_TYPE_MAIN:
result = CommonSettings.showGpu.sub;

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -30,14 +30,15 @@
@required
- (void) doInitVideoOutput:(NSDictionary *)properties;
- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize;
- (void) doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight;
@property (retain) DisplayViewDelegate *dispViewDelegate;
@optional
- (void) doResizeView:(NSRect)rect;
- (void) doTransformView:(DisplayOutputTransformData *)transformData;
- (void) doRedraw;
- (void) doDisplayTypeChanged:(NSInteger)displayTypeID;
- (void) doDisplayModeChanged:(NSInteger)displayModeID;
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID;
- (void) doDisplayOrderChanged:(NSInteger)displayOrderID;
- (void) doBilinearOutputChanged:(BOOL)useBilinear;
@ -80,7 +81,7 @@
@property (assign) double rotation;
@property (assign) BOOL useBilinearOutput;
@property (assign) BOOL useVerticalSync;
@property (assign) NSInteger displayType;
@property (assign) NSInteger displayMode;
@property (assign) NSInteger displayOrientation;
@property (assign) NSInteger displayOrder;
@property (readonly) NSMutableDictionary *bindings;
@ -113,7 +114,7 @@
NSBitmapImageRep *currentImageRep;
}
- (NSBitmapImageRep *) bitmapImageRep:(const void *)videoFrameData imageSize:(NSSize)imageSize;
- (NSBitmapImageRep *) bitmapImageRep:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)imageWidth height:(const NSInteger)imageHeight;
@end
@ -127,6 +128,8 @@
BOOL isVAOSupported;
DisplayViewDelegate *dispViewDelegate;
NSInteger lastDisplayMode;
NSInteger currentDisplayOrientation;
GLint glTexRenderStyle;
GLenum glTexPixelFormat;
GLvoid *glTexBack;
@ -150,15 +153,14 @@
GLint *vtxBuffer;
GLfloat *texCoordBuffer;
GLubyte *vtxIndexBuffer;
GLsizei vtxElementCount;
unsigned int vtxBufferOffset;
}
- (void) drawVideoFrame;
- (void) uploadDisplayTextures:(const GLvoid *)textureData textureSize:(NSSize)textureSize;
- (void) renderDisplay;
- (void) updateDisplayVertices;
- (void) uploadDisplayTextures:(const GLvoid *)textureData width:(const GLsizei)texWidth height:(const GLsizei)texHeight;
- (void) renderDisplayUsingDisplayMode:(const NSInteger)displayModeID;
- (void) updateDisplayVerticesUsingDisplayMode:(const NSInteger)displayModeID orientation:(const NSInteger)displayOrientationID;
@end

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -103,7 +103,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
@dynamic rotation;
@dynamic useBilinearOutput;
@dynamic useVerticalSync;
@dynamic displayType;
@dynamic displayMode;
@dynamic displayOrientation;
@dynamic displayOrder;
@synthesize bindings;
@ -216,6 +216,16 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
OSSpinLockLock(&spinlockScale);
[bindings setValue:[NSNumber numberWithDouble:s] forKey:@"scale"];
OSSpinLockUnlock(&spinlockScale);
DisplayOutputTransformData transformData = { s,
[self rotation],
0.0,
0.0,
0.0 };
[CocoaDSUtil messageSendOneWayWithData:[self sendPortDisplay]
msgID:MESSAGE_TRANSFORM_VIEW
data:[NSData dataWithBytes:&transformData length:sizeof(DisplayOutputTransformData)]];
}
- (double) scale
@ -232,6 +242,16 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
OSSpinLockLock(&spinlockRotation);
[bindings setValue:[NSNumber numberWithDouble:angleDegrees] forKey:@"rotation"];
OSSpinLockUnlock(&spinlockRotation);
DisplayOutputTransformData transformData = { [self scale],
angleDegrees,
0.0,
0.0,
0.0 };
[CocoaDSUtil messageSendOneWayWithData:[self sendPortDisplay]
msgID:MESSAGE_TRANSFORM_VIEW
data:[NSData dataWithBytes:&transformData length:sizeof(DisplayOutputTransformData)]];
}
- (double) rotation
@ -279,12 +299,12 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
return theState;
}
- (void) setDisplayType:(NSInteger)theType
- (void) setDisplayMode:(NSInteger)displayModeID
{
NSSize newDisplaySize = NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT);
NSString *modeString = @"Unknown";
switch (theType)
switch (displayModeID)
{
case DS_DISPLAY_TYPE_MAIN:
modeString = NSSTRING_DISPLAYMODE_MAIN;
@ -313,7 +333,8 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
OSSpinLockLock(&spinlockDisplayType);
[bindings setValue:[NSNumber numberWithInteger:theType] forKey:@"displayMode"];
NSInteger oldMode = [[bindings valueForKey:@"displayMode"] integerValue];
[bindings setValue:[NSNumber numberWithInteger:displayModeID] forKey:@"displayMode"];
[bindings setValue:modeString forKey:@"displayModeString"];
OSSpinLockUnlock(&spinlockDisplayType);
@ -321,16 +342,24 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
normalSize = newDisplaySize;
OSSpinLockUnlock(&spinlockNormalSize);
[CocoaDSUtil messageSendOneWayWithInteger:self.sendPortDisplay msgID:MESSAGE_CHANGE_DISPLAY_TYPE integerValue:theType];
[CocoaDSUtil messageSendOneWayWithInteger:self.sendPortDisplay msgID:MESSAGE_CHANGE_DISPLAY_TYPE integerValue:displayModeID];
// If the display mode swaps between Main Only and Touch Only, the view will not resize to implicitly
// redraw the view. So when swapping between these two display modes, explicitly tell the view to redraw.
if ( (oldMode == DS_DISPLAY_TYPE_MAIN && displayModeID == DS_DISPLAY_TYPE_TOUCH) ||
(oldMode == DS_DISPLAY_TYPE_TOUCH && displayModeID == DS_DISPLAY_TYPE_MAIN) )
{
[view setNeedsDisplay:YES];
}
}
- (NSInteger) displayType
- (NSInteger) displayMode
{
OSSpinLockLock(&spinlockDisplayType);
NSInteger theType = [[bindings valueForKey:@"displayMode"] integerValue];
NSInteger displayModeID = [[bindings valueForKey:@"displayMode"] integerValue];
OSSpinLockUnlock(&spinlockDisplayType);
return theType;
return displayModeID;
}
- (void) setDisplayOrientation:(NSInteger)theOrientation
@ -339,7 +368,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
[bindings setValue:[NSNumber numberWithInteger:theOrientation] forKey:@"displayOrientation"];
OSSpinLockUnlock(&spinlockDisplayOrientation);
if ([self displayType] == DS_DISPLAY_TYPE_COMBO)
if ([self displayMode] == DS_DISPLAY_TYPE_COMBO)
{
NSSize newDisplaySize = NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT);
@ -474,7 +503,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
NSPoint touchLoc = GetNormalPointFromTransformedPoint(clickLoc, [self normalSize], [[self view] bounds].size, [self scale], viewAngle);
// Normalize the touch location to the DS.
if ([self displayType] == DS_DISPLAY_TYPE_COMBO)
if ([self displayMode] == DS_DISPLAY_TYPE_COMBO)
{
NSInteger theOrientation = [self displayOrientation];
NSInteger theOrder = [self displayOrder];
@ -576,9 +605,9 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
- (BOOL) handleMouseButton:(NSEvent *)theEvent buttonPressed:(BOOL)buttonPressed
{
BOOL isHandled = NO;
NSInteger dispType = [self displayType];
NSInteger displayModeID = [self displayMode];
if (self.cdsController == nil || (dispType != DS_DISPLAY_TYPE_TOUCH && dispType != DS_DISPLAY_TYPE_COMBO))
if (self.cdsController == nil || (displayModeID != DS_DISPLAY_TYPE_TOUCH && displayModeID != DS_DISPLAY_TYPE_COMBO))
{
return isHandled;
}
@ -633,9 +662,9 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
[view doInitVideoOutput:properties];
}
- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize
- (void) doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight
{
[view doProcessVideoFrame:videoFrameData frameSize:frameSize];
[view doProcessVideoFrame:videoFrameData displayMode:displayModeID width:frameWidth height:frameHeight];
}
- (void) doResizeView:(NSRect)rect
@ -648,6 +677,16 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
[view doResizeView:rect];
}
- (void) doTransformView:(DisplayOutputTransformData *)transformData
{
if (view == nil || ![view respondsToSelector:@selector(doTransformView:)])
{
return;
}
[view doTransformView:transformData];
}
- (void) doRedraw
{
if (view == nil || ![view respondsToSelector:@selector(doRedraw)])
@ -658,14 +697,14 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
[view doRedraw];
}
- (void) doDisplayTypeChanged:(NSInteger)displayTypeID
- (void) doDisplayModeChanged:(NSInteger)displayModeID
{
if (view == nil || ![view respondsToSelector:@selector(doDisplayTypeChanged:)])
if (view == nil || ![view respondsToSelector:@selector(doDisplayModeChanged:)])
{
return;
}
[view doDisplayTypeChanged:displayTypeID];
[view doDisplayModeChanged:displayModeID];
}
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID
@ -766,24 +805,22 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
[CocoaDSUtil messageSendOneWayWithRect:dispViewDelegate.sendPortDisplay msgID:MESSAGE_RESIZE_VIEW rect:rect];
}
- (NSBitmapImageRep *) bitmapImageRep:(const void *)videoFrameData imageSize:(NSSize)imageSize
- (NSBitmapImageRep *) bitmapImageRep:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)imageWidth height:(const NSInteger)imageHeight
{
if (videoFrameData == nil)
{
return nil;
}
NSUInteger w = (NSUInteger)imageSize.width;
NSUInteger h = (NSUInteger)imageSize.height;
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
pixelsWide:w
pixelsHigh:h
pixelsWide:imageWidth
pixelsHigh:imageHeight
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:w * 4
bytesPerRow:imageWidth * 4
bitsPerPixel:32];
if(!imageRep)
@ -792,10 +829,10 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
uint32_t *bitmapData = (uint32_t *)[imageRep bitmapData];
RGBA5551ToRGBA8888Buffer((const uint16_t *)videoFrameData, bitmapData, (w * h));
RGBA5551ToRGBA8888Buffer((const uint16_t *)videoFrameData, bitmapData, (imageWidth * imageHeight));
#ifdef __BIG_ENDIAN__
uint32_t *bitmapDataEnd = bitmapData + (w * h);
uint32_t *bitmapDataEnd = bitmapData + (imageWidth * imageHeight);
while (bitmapData < bitmapDataEnd)
{
*bitmapData++ = CFSwapInt32LittleToHost(*bitmapData);
@ -913,10 +950,10 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
currentImageRep = nil;
}
- (void)doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize
- (void)doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight
{
// Render the frame in an NSBitmapImageRep
NSBitmapImageRep *newImageRep = [self bitmapImageRep:videoFrameData imageSize:frameSize];
NSBitmapImageRep *newImageRep = [self bitmapImageRep:videoFrameData displayMode:displayModeID width:frameWidth height:frameHeight];
if (newImageRep == nil)
{
return;
@ -951,6 +988,8 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
dispViewDelegate = nil;
lastDisplayMode = DS_DISPLAY_TYPE_COMBO;
currentDisplayOrientation = DS_DISPLAY_ORIENTATION_VERTICAL;
glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
glTexRenderStyle = GL_LINEAR;
@ -964,7 +1003,6 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
texCoordBuffer = new GLfloat[2 * 8];
vtxIndexBuffer = new GLubyte[12];
vtxBufferOffset = 0;
vtxElementCount = 12;
// Create a new context for the OpenGL-based emulated 3D renderer
NSOpenGLPixelFormatAttribute attrs[] =
@ -1067,42 +1105,10 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
NSRect oldFrame = [self frame];
[super setFrame:rect];
GLfloat angleDegrees = (GLfloat)[dispViewDelegate rotation];
GLfloat s = (GLfloat)[dispViewDelegate scale];
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
glViewport(0, 0, rect.size.width, rect.size.height);
glClear(GL_COLOR_BUFFER_BIT);
if (isShadersSupported)
{
glUniform2f(uniformViewSize, rect.size.width, rect.size.height);
glUniform1f(uniformAngleDegrees, angleDegrees);
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-rect.size.width/2, -rect.size.width/2 + rect.size.width, -rect.size.height/2, -rect.size.height/2 + rect.size.height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(angleDegrees), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
CGLUnlockContext(cglDisplayContext);
if (rect.size.width == oldFrame.size.width && rect.size.height == oldFrame.size.height)
{
[CocoaDSUtil messageSendOneWay:dispViewDelegate.sendPortDisplay msgID:MESSAGE_REDRAW_VIEW];
}
else
if (rect.size.width != oldFrame.size.width || rect.size.height != oldFrame.size.height)
{
[CocoaDSUtil messageSendOneWayWithRect:dispViewDelegate.sendPortDisplay msgID:MESSAGE_RESIZE_VIEW rect:rect];
[self setNeedsDisplay:YES];
}
}
@ -1245,7 +1251,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
CGLFlushDrawable(cglDisplayContext);
}
- (void) uploadDisplayTextures:(const GLvoid *)textureData textureSize:(NSSize)textureSize
- (void) uploadDisplayTextures:(const GLvoid *)textureData width:(const GLsizei)texWidth height:(const GLsizei)texHeight
{
if (textureData == NULL)
{
@ -1253,11 +1259,11 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
glBindTexture(GL_TEXTURE_2D, displayTexID);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texWidth, texHeight, GL_RGBA, glTexPixelFormat, textureData);
glBindTexture(GL_TEXTURE_2D, 0);
}
- (void) renderDisplay
- (void) renderDisplayUsingDisplayMode:(const NSInteger)displayModeID
{
GLubyte *elementPointer = NULL;
@ -1311,6 +1317,25 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
// Perform the render.
if (lastDisplayMode != displayModeID)
{
lastDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:currentDisplayOrientation];
if (isVBOSupported)
{
glBindBuffer(GL_ARRAY_BUFFER, vboVertexID);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLint) * (2 * 8), vtxBuffer + vtxBufferOffset);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
}
GLsizei vtxElementCount = 6;
if (displayModeID == DS_DISPLAY_TYPE_COMBO)
{
vtxElementCount = 12;
}
glClear(GL_COLOR_BUFFER_BIT);
glBindTexture(GL_TEXTURE_2D, displayTexID);
glDrawElements(GL_TRIANGLES, vtxElementCount, GL_UNSIGNED_BYTE, elementPointer);
@ -1348,18 +1373,15 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
}
- (void) updateDisplayVertices
- (void) updateDisplayVerticesUsingDisplayMode:(const NSInteger)displayModeID orientation:(const NSInteger)displayOrientationID
{
NSInteger displayType = [dispViewDelegate displayType];
GLint w = (GLint)GPU_DISPLAY_WIDTH;
GLint h = (GLint)GPU_DISPLAY_HEIGHT;
if (displayType == DS_DISPLAY_TYPE_COMBO)
if (displayModeID == DS_DISPLAY_TYPE_COMBO)
{
NSInteger displayOrientation = [dispViewDelegate displayOrientation];
// displayOrder == DS_DISPLAY_ORDER_MAIN_FIRST
if (displayOrientation == DS_DISPLAY_ORIENTATION_VERTICAL)
if (displayOrientationID == DS_DISPLAY_ORIENTATION_VERTICAL)
{
vtxBuffer[0] = -w/2; vtxBuffer[1] = h; // Top display, top left
vtxBuffer[2] = w/2; vtxBuffer[3] = h; // Top display, top right
@ -1371,7 +1393,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
vtxBuffer[12] = w/2; vtxBuffer[13] = -h; // Bottom display, bottom right
vtxBuffer[14] = -w/2; vtxBuffer[15] = -h; // Bottom display, bottom left
}
else // displayOrientation == DS_DISPLAY_ORIENTATION_HORIZONTAL
else // displayOrientationID == DS_DISPLAY_ORIENTATION_HORIZONTAL
{
vtxBuffer[0] = -w; vtxBuffer[1] = h/2; // Left display, top left
vtxBuffer[2] = 0; vtxBuffer[3] = h/2; // Left display, top right
@ -1388,7 +1410,7 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
memcpy(vtxBuffer + (2 * 8), vtxBuffer + (1 * 8), sizeof(GLint) * (1 * 8));
memcpy(vtxBuffer + (3 * 8), vtxBuffer + (0 * 8), sizeof(GLint) * (1 * 8));
}
else // displayType == DS_DISPLAY_TYPE_MAIN || displayType == DS_DISPLAY_TYPE_TOUCH
else // displayModeID == DS_DISPLAY_TYPE_MAIN || displayModeID == DS_DISPLAY_TYPE_TOUCH
{
vtxBuffer[0] = -w/2; vtxBuffer[1] = h/2; // First display, top left
vtxBuffer[2] = w/2; vtxBuffer[3] = h/2; // First display, top right
@ -1507,13 +1529,13 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
// No init needed, so do nothing.
}
- (void)doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize
- (void)doProcessVideoFrame:(const void *)videoFrameData displayMode:(const NSInteger)displayModeID width:(const NSInteger)frameWidth height:(const NSInteger)frameHeight
{
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self uploadDisplayTextures:videoFrameData textureSize:frameSize];
[self renderDisplay];
[self uploadDisplayTextures:videoFrameData width:frameWidth height:frameHeight];
[self renderDisplayUsingDisplayMode:displayModeID];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
@ -1521,7 +1543,47 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
- (void)doResizeView:(NSRect)rect
{
// Do nothing
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
glViewport(0, 0, rect.size.width, rect.size.height);
if (isShadersSupported)
{
glUniform2f(uniformViewSize, rect.size.width, rect.size.height);
}
else
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-rect.size.width/2, -rect.size.width/2 + rect.size.width, -rect.size.height/2, -rect.size.height/2 + rect.size.height, -1.0, 1.0);
}
CGLUnlockContext(cglDisplayContext);
}
- (void) doTransformView:(DisplayOutputTransformData *)transformData
{
GLfloat angleDegrees = (GLfloat)transformData->rotation;
GLfloat s = (GLfloat)transformData->scale;
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
if (isShadersSupported)
{
glUniform1f(uniformAngleDegrees, angleDegrees);
glUniform1f(uniformScalar, s);
}
else
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CLOCKWISE_DEGREES(angleDegrees), 0.0f, 0.0f, 1.0f);
glScalef(s, s, 1.0f);
}
CGLUnlockContext(cglDisplayContext);
}
- (void)doRedraw
@ -1529,24 +1591,16 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
[self renderDisplay];
[self renderDisplayUsingDisplayMode:lastDisplayMode];
[self drawVideoFrame];
CGLUnlockContext(cglDisplayContext);
}
- (void)doDisplayTypeChanged:(NSInteger)displayTypeID
- (void)doDisplayModeChanged:(NSInteger)displayModeID
{
if (displayTypeID == DS_DISPLAY_TYPE_COMBO)
{
vtxElementCount = 12;
}
else
{
vtxElementCount = 6;
}
[self updateDisplayVertices];
lastDisplayMode = displayModeID;
[self updateDisplayVerticesUsingDisplayMode:displayModeID orientation:currentDisplayOrientation];
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
@ -1581,7 +1635,8 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID
{
[self updateDisplayVertices];
currentDisplayOrientation = displayOrientationID;
[self updateDisplayVerticesUsingDisplayMode:lastDisplayMode orientation:displayOrientationID];
CGLLockContext(cglDisplayContext);
CGLSetCurrentContext(cglDisplayContext);
@ -1617,9 +1672,9 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO)
if (lastDisplayMode == DS_DISPLAY_TYPE_COMBO)
{
[self renderDisplay];
[self renderDisplayUsingDisplayMode:lastDisplayMode];
[self drawVideoFrame];
}
@ -1667,28 +1722,28 @@ CGLContextObj OSXOpenGLRendererContext = NULL;
}
}
GLfloat w = (GLfloat)(videoFilterDestSize.width / potW);
GLfloat h = (GLfloat)(videoFilterDestSize.height / potH);
GLfloat s = (GLfloat)(videoFilterDestSize.width / potW);
GLfloat t = (GLfloat)(videoFilterDestSize.height / potH);
// Set up texture coordinates
if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO)
if ([dispViewDelegate displayMode] == DS_DISPLAY_TYPE_COMBO)
{
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = w; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = w; texCoordBuffer[5] = h/2.0f;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = h/2.0f;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t/2.0f;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t/2.0f;
texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = h/2.0f;
texCoordBuffer[10] = w; texCoordBuffer[11] = h/2.0f;
texCoordBuffer[12] = w; texCoordBuffer[13] = h;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = h;
texCoordBuffer[8] = 0.0f; texCoordBuffer[9] = t/2.0f;
texCoordBuffer[10] = s; texCoordBuffer[11] = t/2.0f;
texCoordBuffer[12] = s; texCoordBuffer[13] = t;
texCoordBuffer[14] = 0.0f; texCoordBuffer[15] = t;
}
else // displayType == DS_DISPLAY_TYPE_MAIN || displayType == DS_DISPLAY_TYPE_TOUCH
else // displayMode == DS_DISPLAY_TYPE_MAIN || displayMode == DS_DISPLAY_TYPE_TOUCH
{
texCoordBuffer[0] = 0.0f; texCoordBuffer[1] = 0.0f;
texCoordBuffer[2] = w; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = w; texCoordBuffer[5] = h;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = h;
texCoordBuffer[2] = s; texCoordBuffer[3] = 0.0f;
texCoordBuffer[4] = s; texCoordBuffer[5] = t;
texCoordBuffer[6] = 0.0f; texCoordBuffer[7] = t;
memcpy(texCoordBuffer + (1 * 8), texCoordBuffer + (0 * 8), sizeof(GLfloat) * (1 * 8));
}

View File

@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team
Copyright (C) 2013 DeSmuME team
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -151,11 +151,9 @@
- (void) setContentScalar:(double)s
{
[dispViewDelegate setScale:s];
// Resize the window when contentScalar changes.
NSSize drawBounds = [dispViewDelegate normalSize];
[self resizeWithTransform:drawBounds scalar:s rotation:[dispViewDelegate rotation]];
// No need to set the view's scale here since window resizing will implicitly change it.
[self resizeWithTransform:[dispViewDelegate normalSize] scalar:s rotation:[dispViewDelegate rotation]];
}
- (void) setContentRotation:(double)angleDegrees
@ -174,25 +172,21 @@
[dispViewDelegate setRotation:newAngleDegrees];
// Set the minimum content size for the window, since this will change based on rotation.
NSSize drawBounds = minDisplayViewSize;
NSSize minContentSize = GetTransformedBounds(drawBounds, 1.0, CLOCKWISE_DEGREES(newAngleDegrees));
NSSize minContentSize = GetTransformedBounds(minDisplayViewSize, 1.0, CLOCKWISE_DEGREES(newAngleDegrees));
minContentSize.height += statusBarHeight;
[window setContentMinSize:minContentSize];
// Resize the window.
NSSize oldBounds = [window frame].size;
const NSSize oldBounds = [window frame].size;
[self resizeWithTransform:[dispViewDelegate normalSize] scalar:[dispViewDelegate scale] rotation:newAngleDegrees];
NSSize newBounds = [window frame].size;
const NSSize newBounds = [window frame].size;
// If the window size didn't change, it is possible that the old and new rotation angles
// are 180 degrees offset from each other. In this case, we'll need to force the
// display view to update itself.
if (oldBounds.width == newBounds.width && oldBounds.height == newBounds.height)
{
NSRect newContentFrame = [[window contentView] bounds];
newContentFrame.origin.y = statusBarHeight;
newContentFrame.size.height -= statusBarHeight;
[displayView setFrame:newContentFrame];
[displayView setNeedsDisplay:YES];
}
}
@ -202,26 +196,27 @@
angleDegrees = CLOCKWISE_DEGREES(angleDegrees);
// Get the maximum scalar size within drawBounds. Constrain scalar to maxScalar if necessary.
NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, angleDegrees);
double maxScalar = [self maxContentScalar:checkSize];
const NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, angleDegrees);
const double maxScalar = [self maxContentScalar:checkSize];
if (scalar > maxScalar)
{
scalar = maxScalar;
}
// Get the new bounds for the window's content view based on the transformed draw bounds.
NSSize transformedBounds = GetTransformedBounds(normalBounds, scalar, angleDegrees);
const NSSize transformedBounds = GetTransformedBounds(normalBounds, scalar, angleDegrees);
// Get the center of the content view in screen coordinates.
NSRect windowContentRect = [[window contentView] bounds];
double translationX = (windowContentRect.size.width - transformedBounds.width) / 2.0;
double translationY = ((windowContentRect.size.height - statusBarHeight) - transformedBounds.height) / 2.0;
const NSRect windowContentRect = [[window contentView] bounds];
const double translationX = (windowContentRect.size.width - transformedBounds.width) / 2.0;
const double translationY = ((windowContentRect.size.height - statusBarHeight) - transformedBounds.height) / 2.0;
// Resize the window.
NSRect windowFrame = [window frame];
NSRect newFrame = [window frameRectForContentRect:NSMakeRect(windowFrame.origin.x + translationX, windowFrame.origin.y + translationY, transformedBounds.width, transformedBounds.height + statusBarHeight)];
const NSRect windowFrame = [window frame];
const NSRect newFrame = [window frameRectForContentRect:NSMakeRect(windowFrame.origin.x + translationX, windowFrame.origin.y + translationY, transformedBounds.width, transformedBounds.height + statusBarHeight)];
[window setFrame:newFrame display:YES animate:NO];
// Return the actual scale used for the view (may be constrained).
return scalar;
}
@ -229,13 +224,11 @@
{
// Determine the maximum scale based on the visible screen size (which
// doesn't include the menu bar or dock).
NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
NSRect windowFrame = [window frameRectForContentRect:NSMakeRect(0.0, 0.0, contentBounds.width, contentBounds.height + statusBarHeight)];
const NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
const NSRect windowFrame = [window frameRectForContentRect:NSMakeRect(0.0, 0.0, contentBounds.width, contentBounds.height + statusBarHeight)];
const NSSize visibleScreenBounds = { (screenFrame.size.width - (windowFrame.size.width - contentBounds.width)), (screenFrame.size.height - (windowFrame.size.height - contentBounds.height)) };
NSSize visibleScreenBounds = { (screenFrame.size.width - (windowFrame.size.width - contentBounds.width)), (screenFrame.size.height - (windowFrame.size.height - contentBounds.height)) };
double maxS = GetMaxScalarInBounds(contentBounds.width, contentBounds.height, visibleScreenBounds.width, visibleScreenBounds.height);
return maxS;
return GetMaxScalarInBounds(contentBounds.width, contentBounds.height, visibleScreenBounds.width, visibleScreenBounds.height);
}
- (void) setVolume:(float)vol
@ -297,7 +290,7 @@
{
isMinSizeNormal = theState;
if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO)
if ([dispViewDelegate displayMode] == DS_DISPLAY_TYPE_COMBO)
{
if ([dispViewDelegate displayOrientation] == DS_DISPLAY_ORIENTATION_HORIZONTAL)
{
@ -899,13 +892,27 @@
- (IBAction) changeDisplayMode:(id)sender
{
[dispViewDelegate setDisplayType:[CocoaDSUtil getIBActionSenderTag:sender]];
NSInteger newDisplayModeID = [CocoaDSUtil getIBActionSenderTag:sender];
if (newDisplayModeID == [dispViewDelegate displayMode])
{
return;
}
[dispViewDelegate setDisplayMode:newDisplayModeID];
[self resizeWithTransform:[dispViewDelegate normalSize] scalar:[dispViewDelegate scale] rotation:[dispViewDelegate rotation]];
}
- (IBAction) changeDisplayOrientation:(id)sender
{
[dispViewDelegate setDisplayOrientation:[CocoaDSUtil getIBActionSenderTag:sender]];
NSInteger newDisplayOrientation = [CocoaDSUtil getIBActionSenderTag:sender];
if (newDisplayOrientation == [dispViewDelegate displayOrientation])
{
return;
}
[dispViewDelegate setDisplayOrientation:newDisplayOrientation];
[self setIsMinSizeNormal:[self isMinSizeNormal]];
[self resizeWithTransform:[dispViewDelegate normalSize] scalar:[dispViewDelegate scale] rotation:[dispViewDelegate rotation]];
}
@ -1723,7 +1730,7 @@
{
if ([(id)theItem isMemberOfClass:[NSMenuItem class]])
{
if ([dispViewDelegate displayType] == [theItem tag])
if ([dispViewDelegate displayMode] == [theItem tag])
{
[(NSMenuItem*)theItem setState:NSOnState];
}
@ -1873,7 +1880,6 @@
const NSSize checkSize = GetTransformedBounds(normalBounds, 1.0, [dispViewDelegate rotation]);
const NSSize contentBounds = NSMakeSize(contentRect.size.width, contentRect.size.height - statusBarHeight);
const double maxS = GetMaxScalarInBounds(checkSize.width, checkSize.height, contentBounds.width, contentBounds.height);
[dispViewDelegate setScale:maxS];
// Make a new content Rect with our max scalar, and convert it back to a frame Rect.
const NSRect finalContentRect = NSMakeRect(0.0f, 0.0f, checkSize.width * maxS, (checkSize.height * maxS) + statusBarHeight);
@ -1892,7 +1898,7 @@
{
return;
}
const NSSize normalBounds = [dispViewDelegate normalSize];
const double r = [dispViewDelegate rotation];
@ -2040,7 +2046,7 @@
// Set the display settings per user preferences.
double displayScalar = (double)([[NSUserDefaults standardUserDefaults] floatForKey:@"DisplayView_Size"] / 100.0);
double displayRotation = (double)[[NSUserDefaults standardUserDefaults] floatForKey:@"DisplayView_Rotation"];
[dispViewDelegate setDisplayType:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_Mode"]];
[dispViewDelegate setDisplayMode:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayView_Mode"]];
[dispViewDelegate setDisplayOrientation:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Orientation"]];
[dispViewDelegate setDisplayOrder:[[NSUserDefaults standardUserDefaults] integerForKey:@"DisplayViewCombo_Order"]];
[self setContentScalar:displayScalar];