Cocoa Port:
- Optimize OpenGL blitter for better performance (now uses display lists instead of rendering in immediate mode). - Some refactoring and code cleanup of the video output code.
This commit is contained in:
parent
ba35ebce6a
commit
c87672f680
|
@ -95,23 +95,28 @@
|
|||
@protocol CocoaDSDisplayDelegate <NSObject>
|
||||
|
||||
@required
|
||||
- (void) doInitVideoOutput:(NSDictionary *)properties;
|
||||
- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize;
|
||||
- (void) doDisplayTypeChanged:(NSInteger)displayTypeID;
|
||||
|
||||
@property (retain) NSPort *sendPortDisplay;
|
||||
@property (assign) BOOL isHudEnabled;
|
||||
@property (assign) BOOL isHudEditingModeEnabled;
|
||||
|
||||
@end
|
||||
|
||||
@protocol CocoaDSDisplayVideoDelegate <CocoaDSDisplayDelegate>
|
||||
|
||||
@required
|
||||
- (void) doInitVideoOutput:(NSDictionary *)properties;
|
||||
- (void) doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize;
|
||||
|
||||
@optional
|
||||
- (void) doResizeView:(NSRect)rect;
|
||||
- (void) doRedraw;
|
||||
- (void) doDisplayTypeChanged:(NSInteger)displayTypeID;
|
||||
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID;
|
||||
- (void) doDisplayOrderChanged:(NSInteger)displayOrderID;
|
||||
- (void) doBilinearOutputChanged:(BOOL)useBilinear;
|
||||
- (void) doVerticalSyncChanged:(BOOL)useVerticalSync;
|
||||
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID;
|
||||
|
||||
@property (assign) BOOL isHudEnabled;
|
||||
@property (assign) BOOL isHudEditingModeEnabled;
|
||||
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -121,14 +126,12 @@
|
|||
UInt32 gpuStateFlags;
|
||||
id <CocoaDSDisplayDelegate> delegate;
|
||||
NSInteger displayType;
|
||||
CocoaVideoFilter *vf;
|
||||
NSSize frameSize;
|
||||
|
||||
pthread_mutex_t *mutexRender3D;
|
||||
OSSpinLock spinlockDelegate;
|
||||
OSSpinLock spinlockGpuState;
|
||||
OSSpinLock spinlockDisplayType;
|
||||
OSSpinLock spinlockVideoFilterType;
|
||||
OSSpinLock spinlockVfSrcBuffer;
|
||||
OSSpinLock spinlockRender3DRenderingEngine;
|
||||
OSSpinLock spinlockRender3DHighPrecisionColorInterpolation;
|
||||
OSSpinLock spinlockRender3DEdgeMarking;
|
||||
|
@ -142,7 +145,7 @@
|
|||
@property (assign) UInt32 gpuStateFlags;
|
||||
@property (retain) id <CocoaDSDisplayDelegate> delegate;
|
||||
@property (assign) NSInteger displayType;
|
||||
@property (assign) CocoaVideoFilter *vf;
|
||||
@property (readonly) NSSize frameSize;
|
||||
@property (readonly) pthread_mutex_t *mutexRender3D;
|
||||
|
||||
- (void) setRender3DRenderingEngine:(NSInteger)methodID;
|
||||
|
@ -162,15 +165,8 @@
|
|||
- (void) setRender3DLineHack:(BOOL)state;
|
||||
- (BOOL) render3DLineHack;
|
||||
|
||||
- (void) handleResizeView:(NSData *)rectData;
|
||||
- (void) handleRedrawView;
|
||||
- (void) handleChangeGpuStateFlags:(NSData *)flagsData;
|
||||
- (void) handleChangeDisplayType:(NSData *)displayTypeIdData;
|
||||
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData;
|
||||
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData;
|
||||
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData;
|
||||
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData;
|
||||
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData;
|
||||
- (void) handleSetRender3DRenderingEngine:(NSData *)methodIdData;
|
||||
- (void) handleSetRender3DHighPrecisionColorInterpolation:(NSData *)stateData;
|
||||
- (void) handleSetRender3DEdgeMarking:(NSData *)stateData;
|
||||
|
@ -196,6 +192,28 @@
|
|||
|
||||
@end
|
||||
|
||||
@interface CocoaDSDisplayVideo : CocoaDSDisplay
|
||||
{
|
||||
CocoaVideoFilter *vf;
|
||||
id <CocoaDSDisplayVideoDelegate> videoDelegate;
|
||||
|
||||
OSSpinLock spinlockVideoFilterType;
|
||||
OSSpinLock spinlockVfSrcBuffer;
|
||||
}
|
||||
|
||||
@property (retain) id <CocoaDSDisplayVideoDelegate> delegate;
|
||||
@property (assign) CocoaVideoFilter *vf;
|
||||
|
||||
- (void) handleResizeView:(NSData *)rectData;
|
||||
- (void) handleRedrawView;
|
||||
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData;
|
||||
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData;
|
||||
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData;
|
||||
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData;
|
||||
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData;
|
||||
|
||||
@end
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
|
|
|
@ -434,9 +434,9 @@ GPU3DInterface *core3DList[] = {
|
|||
@implementation CocoaDSDisplay
|
||||
|
||||
@synthesize gpuStateFlags;
|
||||
@synthesize delegate;
|
||||
@synthesize displayType;
|
||||
@synthesize vf;
|
||||
@dynamic delegate;
|
||||
@dynamic displayType;
|
||||
@dynamic frameSize;
|
||||
@synthesize mutexRender3D;
|
||||
|
||||
- (id)init
|
||||
|
@ -453,8 +453,6 @@ GPU3DInterface *core3DList[] = {
|
|||
spinlockDelegate = OS_SPINLOCK_INIT;
|
||||
spinlockGpuState = OS_SPINLOCK_INIT;
|
||||
spinlockDisplayType = OS_SPINLOCK_INIT;
|
||||
spinlockVideoFilterType = OS_SPINLOCK_INIT;
|
||||
spinlockVfSrcBuffer = OS_SPINLOCK_INIT;
|
||||
spinlockRender3DRenderingEngine = OS_SPINLOCK_INIT;
|
||||
spinlockRender3DHighPrecisionColorInterpolation = OS_SPINLOCK_INIT;
|
||||
spinlockRender3DEdgeMarking = OS_SPINLOCK_INIT;
|
||||
|
@ -465,7 +463,7 @@ GPU3DInterface *core3DList[] = {
|
|||
spinlockRender3DLineHack = OS_SPINLOCK_INIT;
|
||||
|
||||
displayType = DS_DISPLAY_TYPE_COMBO;
|
||||
vf = [[CocoaVideoFilter alloc] initWithSize:NSMakeSize(GPU_DISPLAY_WIDTH, GPU_DISPLAY_HEIGHT * 2) typeID:VideoFilterTypeID_None numberThreads:2];
|
||||
frameSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT * 2);
|
||||
|
||||
gpuStateFlags = GPUSTATE_MAIN_GPU_MASK |
|
||||
GPUSTATE_MAIN_BG0_MASK |
|
||||
|
@ -498,8 +496,6 @@ GPU3DInterface *core3DList[] = {
|
|||
[property setValue:[NSNumber numberWithBool:YES] forKey:@"gpuStateSubOBJ"];
|
||||
[property setValue:[NSNumber numberWithInteger:displayType] forKey:@"displayMode"];
|
||||
[property setValue:NSSTRING_DISPLAYMODE_MAIN forKey:@"displayModeString"];
|
||||
[property setValue:[NSNumber numberWithInteger:(NSInteger)VideoFilterTypeID_None] forKey:@"videoFilterType"];
|
||||
[property setValue:[CocoaVideoFilter typeStringByID:VideoFilterTypeID_None] forKey:@"videoFilterTypeString"];
|
||||
[property setValue:[NSNumber numberWithInteger:CORE3DLIST_NULL] forKey:@"render3DRenderingEngine"];
|
||||
[property setValue:[NSNumber numberWithBool:YES] forKey:@"render3DHighPrecisionColorInterpolation"];
|
||||
[property setValue:[NSNumber numberWithBool:YES] forKey:@"render3DEdgeMarking"];
|
||||
|
@ -515,7 +511,6 @@ GPU3DInterface *core3DList[] = {
|
|||
- (void)dealloc
|
||||
{
|
||||
self.delegate = nil;
|
||||
[vf release];
|
||||
|
||||
pthread_mutex_destroy(self.mutexRender3D);
|
||||
free(self.mutexRender3D);
|
||||
|
@ -710,7 +705,7 @@ GPU3DInterface *core3DList[] = {
|
|||
- (void) setDisplayType:(NSInteger)dispType
|
||||
{
|
||||
NSString *newDispString = nil;
|
||||
NSSize newSrcSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT);
|
||||
NSSize newFrameSize = NSMakeSize((CGFloat)GPU_DISPLAY_WIDTH, (CGFloat)GPU_DISPLAY_HEIGHT);
|
||||
|
||||
switch (dispType)
|
||||
{
|
||||
|
@ -724,7 +719,7 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
case DS_DISPLAY_TYPE_COMBO:
|
||||
newDispString = NSSTRING_DISPLAYMODE_COMBO;
|
||||
newSrcSize.height *= 2;
|
||||
newFrameSize.height *= 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -734,13 +729,10 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
OSSpinLockLock(&spinlockDisplayType);
|
||||
displayType = dispType;
|
||||
frameSize = newFrameSize;
|
||||
[property setValue:[NSNumber numberWithInteger:dispType] forKey:@"displayMode"];
|
||||
[property setValue:newDispString forKey:@"displayModeString"];
|
||||
OSSpinLockUnlock(&spinlockDisplayType);
|
||||
|
||||
OSSpinLockLock(&spinlockVfSrcBuffer);
|
||||
[vf setSourceSize:newSrcSize];
|
||||
OSSpinLockUnlock(&spinlockVfSrcBuffer);
|
||||
}
|
||||
|
||||
- (NSInteger) displayType
|
||||
|
@ -752,23 +744,13 @@ GPU3DInterface *core3DList[] = {
|
|||
return dispType;
|
||||
}
|
||||
|
||||
- (void) setVfType:(NSInteger)videoFilterTypeID
|
||||
- (NSSize) frameSize
|
||||
{
|
||||
[vf changeFilter:(VideoFilterTypeID)videoFilterTypeID];
|
||||
OSSpinLockLock(&spinlockDisplayType);
|
||||
NSSize size = frameSize;
|
||||
OSSpinLockUnlock(&spinlockDisplayType);
|
||||
|
||||
OSSpinLockLock(&spinlockVideoFilterType);
|
||||
[property setValue:[NSNumber numberWithInteger:videoFilterTypeID] forKey:@"videoFilterType"];
|
||||
[property setValue:NSLocalizedString([vf typeString], nil) forKey:@"videoFilterTypeString"];
|
||||
OSSpinLockUnlock(&spinlockVideoFilterType);
|
||||
}
|
||||
|
||||
- (NSInteger) vfType
|
||||
{
|
||||
OSSpinLockLock(&spinlockVideoFilterType);
|
||||
NSInteger theType = [(NSNumber *)[property valueForKey:@"videoFilterType"] integerValue];
|
||||
OSSpinLockUnlock(&spinlockVideoFilterType);
|
||||
|
||||
return theType;
|
||||
return size;
|
||||
}
|
||||
|
||||
- (void) setRender3DRenderingEngine:(NSInteger)methodID
|
||||
|
@ -943,15 +925,14 @@ GPU3DInterface *core3DList[] = {
|
|||
}
|
||||
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
CommonSettings.num_cores = numberCores;
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
|
||||
CommonSettings.num_cores = numberCores;
|
||||
if ([self render3DRenderingEngine] == CORE3DLIST_SWRASTERIZE)
|
||||
{
|
||||
pthread_mutex_lock(self.mutexProducer);
|
||||
NDS_3D_ChangeCore(CORE3DLIST_SWRASTERIZE);
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(self.mutexProducer);
|
||||
}
|
||||
|
||||
- (NSUInteger) render3DThreads
|
||||
|
@ -989,15 +970,6 @@ GPU3DInterface *core3DList[] = {
|
|||
return state;
|
||||
}
|
||||
|
||||
- (void) runThread:(id)object
|
||||
{
|
||||
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
||||
[delegate doInitVideoOutput:self.property];
|
||||
[tempPool release];
|
||||
|
||||
[super runThread:object];
|
||||
}
|
||||
|
||||
- (void) doCoreEmuFrame
|
||||
{
|
||||
NSData *gpuData = nil;
|
||||
|
@ -1037,14 +1009,6 @@ GPU3DInterface *core3DList[] = {
|
|||
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_RESIZE_VIEW:
|
||||
[self handleResizeView:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_REDRAW_VIEW:
|
||||
[self handleRedrawView];
|
||||
break;
|
||||
|
||||
case MESSAGE_SET_GPU_STATE_FLAGS:
|
||||
[self handleChangeGpuStateFlags:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
@ -1053,26 +1017,6 @@ GPU3DInterface *core3DList[] = {
|
|||
[self handleChangeDisplayType:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_DISPLAY_ORIENTATION:
|
||||
[self handleChangeDisplayOrientation:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_DISPLAY_ORDER:
|
||||
[self handleChangeDisplayOrder:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_BILINEAR_OUTPUT:
|
||||
[self handleChangeBilinearOutput:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_VERTICAL_SYNC:
|
||||
[self handleChangeVerticalSync:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_VIDEO_FILTER:
|
||||
[self handleChangeVideoFilter:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_SET_RENDER3D_METHOD:
|
||||
[self handleSetRender3DRenderingEngine:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
@ -1129,47 +1073,9 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
- (void) handleEmuFrameProcessed:(NSData *)theData
|
||||
{
|
||||
// Tell the video output object to process the video frame with our copied GPU data.
|
||||
if ([vf typeID] == VideoFilterTypeID_None)
|
||||
{
|
||||
[delegate doProcessVideoFrame:[theData bytes] frameSize:[vf destSize]];
|
||||
}
|
||||
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);
|
||||
|
||||
const UInt32 *vfDestBufferPtr = [vf runFilter];
|
||||
[delegate doProcessVideoFrame:vfDestBufferPtr frameSize:[vf destSize]];
|
||||
}
|
||||
|
||||
[super handleEmuFrameProcessed:theData];
|
||||
}
|
||||
|
||||
- (void) handleResizeView:(NSData *)rectData
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doResizeView:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSRect *resizeRect = (NSRect *)[rectData bytes];
|
||||
[delegate doResizeView:*resizeRect];
|
||||
}
|
||||
|
||||
- (void) handleRedrawView
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doRedraw)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[delegate doRedraw];
|
||||
}
|
||||
|
||||
- (void) handleChangeGpuStateFlags:(NSData *)flagsData
|
||||
{
|
||||
const NSInteger *flags = (NSInteger *)[flagsData bytes];
|
||||
|
@ -1189,64 +1095,6 @@ GPU3DInterface *core3DList[] = {
|
|||
[delegate doDisplayTypeChanged:*theType];
|
||||
}
|
||||
|
||||
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrientationChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSInteger *theOrientation = (NSInteger *)[displayOrientationIdData bytes];
|
||||
[delegate doDisplayOrientationChanged:*theOrientation];
|
||||
}
|
||||
|
||||
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doDisplayOrderChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSInteger *theOrder = (NSInteger *)[displayOrderIdData bytes];
|
||||
[delegate doDisplayOrderChanged:*theOrder];
|
||||
}
|
||||
|
||||
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doBilinearOutputChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const BOOL *theState = (BOOL *)[bilinearStateData bytes];
|
||||
[delegate doBilinearOutputChanged:*theState];
|
||||
[self handleEmuFrameProcessed:self.frameData];
|
||||
}
|
||||
|
||||
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doVerticalSyncChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const BOOL *theState = (BOOL *)[verticalSyncStateData bytes];
|
||||
[delegate doVerticalSyncChanged:*theState];
|
||||
}
|
||||
|
||||
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData
|
||||
{
|
||||
if (delegate == nil || ![delegate respondsToSelector:@selector(doVideoFilterChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSInteger *theType = (NSInteger *)[videoFilterTypeIdData bytes];
|
||||
[self setVfType:*theType];
|
||||
[delegate doVideoFilterChanged:*theType];
|
||||
[self handleEmuFrameProcessed:self.frameData];
|
||||
}
|
||||
|
||||
- (void) handleSetRender3DRenderingEngine:(NSData *)methodIdData
|
||||
{
|
||||
const NSInteger *methodID = (NSInteger *)[methodIdData bytes];
|
||||
|
@ -1356,7 +1204,7 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
- (NSImage *) image
|
||||
{
|
||||
NSImage *newImage = [[NSImage alloc] initWithSize:[vf srcSize]];
|
||||
NSImage *newImage = [[NSImage alloc] initWithSize:self.frameSize];
|
||||
if (newImage == nil)
|
||||
{
|
||||
return newImage;
|
||||
|
@ -1384,7 +1232,7 @@ GPU3DInterface *core3DList[] = {
|
|||
return nil;
|
||||
}
|
||||
|
||||
NSSize srcSize = [vf srcSize];
|
||||
NSSize srcSize = self.frameSize;
|
||||
NSUInteger w = (NSUInteger)srcSize.width;
|
||||
NSUInteger h = (NSUInteger)srcSize.height;
|
||||
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
|
||||
|
@ -1519,6 +1367,269 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
@end
|
||||
|
||||
@implementation CocoaDSDisplayVideo
|
||||
|
||||
@synthesize vf;
|
||||
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil)
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
videoDelegate = nil;
|
||||
|
||||
spinlockVideoFilterType = OS_SPINLOCK_INIT;
|
||||
spinlockVfSrcBuffer = OS_SPINLOCK_INIT;
|
||||
|
||||
vf = [[CocoaVideoFilter alloc] initWithSize:frameSize typeID:VideoFilterTypeID_None numberThreads:2];
|
||||
|
||||
[property setValue:[NSNumber numberWithInteger:(NSInteger)VideoFilterTypeID_None] forKey:@"videoFilterType"];
|
||||
[property setValue:[CocoaVideoFilter typeStringByID:VideoFilterTypeID_None] forKey:@"videoFilterTypeString"];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[vf release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) setDelegate:(id <CocoaDSDisplayVideoDelegate>)theDelegate
|
||||
{
|
||||
OSSpinLockLock(&spinlockDelegate);
|
||||
|
||||
if (theDelegate == videoDelegate)
|
||||
{
|
||||
OSSpinLockUnlock(&spinlockDelegate);
|
||||
return;
|
||||
}
|
||||
|
||||
if (theDelegate != nil)
|
||||
{
|
||||
[theDelegate retain];
|
||||
[theDelegate setSendPortDisplay:self.receivePort];
|
||||
}
|
||||
|
||||
[videoDelegate release];
|
||||
videoDelegate = theDelegate;
|
||||
|
||||
OSSpinLockUnlock(&spinlockDelegate);
|
||||
|
||||
[super setDelegate:theDelegate];
|
||||
}
|
||||
|
||||
- (id <CocoaDSDisplayVideoDelegate>) delegate
|
||||
{
|
||||
OSSpinLockLock(&spinlockDelegate);
|
||||
id <CocoaDSDisplayVideoDelegate> theDelegate = videoDelegate;
|
||||
OSSpinLockUnlock(&spinlockDelegate);
|
||||
|
||||
return theDelegate;
|
||||
}
|
||||
|
||||
- (void) setDisplayType:(NSInteger)dispType
|
||||
{
|
||||
[super setDisplayType:dispType];
|
||||
|
||||
OSSpinLockLock(&spinlockVfSrcBuffer);
|
||||
[vf setSourceSize:self.frameSize];
|
||||
OSSpinLockUnlock(&spinlockVfSrcBuffer);
|
||||
}
|
||||
|
||||
- (void) setVfType:(NSInteger)videoFilterTypeID
|
||||
{
|
||||
[vf changeFilter:(VideoFilterTypeID)videoFilterTypeID];
|
||||
|
||||
OSSpinLockLock(&spinlockVideoFilterType);
|
||||
[property setValue:[NSNumber numberWithInteger:videoFilterTypeID] forKey:@"videoFilterType"];
|
||||
[property setValue:NSLocalizedString([vf typeString], nil) forKey:@"videoFilterTypeString"];
|
||||
OSSpinLockUnlock(&spinlockVideoFilterType);
|
||||
}
|
||||
|
||||
- (NSInteger) vfType
|
||||
{
|
||||
OSSpinLockLock(&spinlockVideoFilterType);
|
||||
NSInteger theType = [(NSNumber *)[property valueForKey:@"videoFilterType"] integerValue];
|
||||
OSSpinLockUnlock(&spinlockVideoFilterType);
|
||||
|
||||
return theType;
|
||||
}
|
||||
|
||||
- (void) runThread:(id)object
|
||||
{
|
||||
NSAutoreleasePool *tempPool = [[NSAutoreleasePool alloc] init];
|
||||
[videoDelegate doInitVideoOutput:self.property];
|
||||
[tempPool release];
|
||||
|
||||
[super runThread:object];
|
||||
}
|
||||
|
||||
- (void)handlePortMessage:(NSPortMessage *)portMessage
|
||||
{
|
||||
NSInteger message = (NSInteger)[portMessage msgid];
|
||||
NSArray *messageComponents = [portMessage components];
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case MESSAGE_EMU_FRAME_PROCESSED:
|
||||
[self handleEmuFrameProcessed:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_RESIZE_VIEW:
|
||||
[self handleResizeView:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_REDRAW_VIEW:
|
||||
[self handleRedrawView];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_DISPLAY_ORIENTATION:
|
||||
[self handleChangeDisplayOrientation:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_DISPLAY_ORDER:
|
||||
[self handleChangeDisplayOrder:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_BILINEAR_OUTPUT:
|
||||
[self handleChangeBilinearOutput:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_VERTICAL_SYNC:
|
||||
[self handleChangeVerticalSync:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
case MESSAGE_CHANGE_VIDEO_FILTER:
|
||||
[self handleChangeVideoFilter:[messageComponents objectAtIndex:0]];
|
||||
break;
|
||||
|
||||
default:
|
||||
[super handlePortMessage:portMessage];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) handleEmuFrameProcessed:(NSData *)theData
|
||||
{
|
||||
if (theData == 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);
|
||||
}
|
||||
|
||||
// Tell the video delegate to process the video frame with our copied GPU data.
|
||||
if ([vf typeID] == VideoFilterTypeID_None)
|
||||
{
|
||||
[videoDelegate doProcessVideoFrame:[theData bytes] frameSize:self.frameSize];
|
||||
}
|
||||
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]];
|
||||
}
|
||||
|
||||
[super handleEmuFrameProcessed:theData];
|
||||
}
|
||||
|
||||
- (void) handleResizeView:(NSData *)rectData
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doResizeView:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSRect *resizeRect = (NSRect *)[rectData bytes];
|
||||
[videoDelegate doResizeView:*resizeRect];
|
||||
}
|
||||
|
||||
- (void) handleRedrawView
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doRedraw)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[videoDelegate doRedraw];
|
||||
}
|
||||
|
||||
- (void) handleChangeDisplayOrientation:(NSData *)displayOrientationIdData
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayOrientationChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSInteger *theOrientation = (NSInteger *)[displayOrientationIdData bytes];
|
||||
[videoDelegate doDisplayOrientationChanged:*theOrientation];
|
||||
}
|
||||
|
||||
- (void) handleChangeDisplayOrder:(NSData *)displayOrderIdData
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doDisplayOrderChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSInteger *theOrder = (NSInteger *)[displayOrderIdData bytes];
|
||||
[videoDelegate doDisplayOrderChanged:*theOrder];
|
||||
}
|
||||
|
||||
- (void) handleChangeBilinearOutput:(NSData *)bilinearStateData
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doBilinearOutputChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const BOOL *theState = (BOOL *)[bilinearStateData bytes];
|
||||
[videoDelegate doBilinearOutputChanged:*theState];
|
||||
[self handleEmuFrameProcessed:self.frameData];
|
||||
}
|
||||
|
||||
- (void) handleChangeVerticalSync:(NSData *)verticalSyncStateData
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doVerticalSyncChanged:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const BOOL *theState = (BOOL *)[verticalSyncStateData bytes];
|
||||
[videoDelegate doVerticalSyncChanged:*theState];
|
||||
}
|
||||
|
||||
- (void) handleChangeVideoFilter:(NSData *)videoFilterTypeIdData
|
||||
{
|
||||
if (videoDelegate == nil || ![videoDelegate respondsToSelector:@selector(doVideoFilterChanged:frameSize:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const NSInteger *theType = (NSInteger *)[videoFilterTypeIdData bytes];
|
||||
[self setVfType:*theType];
|
||||
[videoDelegate doVideoFilterChanged:*theType frameSize:[vf destSize]];
|
||||
[self handleEmuFrameProcessed:self.frameData];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void HandleMessageEchoResponse(NSPortMessage *portMessage)
|
||||
{
|
||||
NSPortMessage *echo = [[NSPortMessage alloc] initWithSendPort:[portMessage receivePort] receivePort:[portMessage sendPort] components:nil];
|
||||
|
|
|
@ -181,9 +181,9 @@
|
|||
[newDispViewDelegate setCdsController:newController];
|
||||
|
||||
// Init the DS displays.
|
||||
CocoaDSDisplay *newComboDisplay = [[[CocoaDSDisplay alloc] init] autorelease];
|
||||
[newComboDisplay setDelegate:newDispViewDelegate];
|
||||
[newCore addOutput:newComboDisplay];
|
||||
CocoaDSDisplayVideo *newVideoDisplay = [[[CocoaDSDisplayVideo alloc] init] autorelease];
|
||||
[newVideoDisplay setDelegate:newDispViewDelegate];
|
||||
[newCore addOutput:newVideoDisplay];
|
||||
NSPort *guiPort = [NSPort port];
|
||||
[[NSRunLoop currentRunLoop] addPort:guiPort forMode:NSDefaultRunLoopMode];
|
||||
|
||||
|
@ -202,11 +202,11 @@
|
|||
}
|
||||
|
||||
// Start up the threads for our outputs.
|
||||
[NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newComboDisplay withObject:nil];
|
||||
[NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newVideoDisplay withObject:nil];
|
||||
[NSThread detachNewThreadSelector:@selector(runThread:) toTarget:newSpeaker withObject:nil];
|
||||
|
||||
// Wait until the GPU and SPU are finished starting up.
|
||||
while ([newComboDisplay thread] == nil || [newSpeaker thread] == nil)
|
||||
while ([newVideoDisplay thread] == nil || [newSpeaker thread] == nil)
|
||||
{
|
||||
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
|
||||
}
|
||||
|
|
|
@ -42,11 +42,11 @@
|
|||
- (void) doDisplayOrderChanged:(NSInteger)displayOrderID;
|
||||
- (void) doBilinearOutputChanged:(BOOL)useBilinear;
|
||||
- (void) doVerticalSyncChanged:(BOOL)useVerticalSync;
|
||||
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID;
|
||||
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize;
|
||||
|
||||
@end
|
||||
|
||||
@interface DisplayViewDelegate : NSObject <CocoaDSDisplayDelegate>
|
||||
@interface DisplayViewDelegate : NSObject <CocoaDSDisplayVideoDelegate>
|
||||
{
|
||||
NSView <DisplayViewDelegate> *view;
|
||||
NSPort *sendPortDisplay;
|
||||
|
@ -130,14 +130,14 @@
|
|||
GLfloat swRasterizerMainVertex[4][2];
|
||||
GLfloat swRasterizerTouchTexCoord[4][2];
|
||||
GLfloat swRasterizerTouchVertex[4][2];
|
||||
GLuint swRasterizerDisplayListIndex;
|
||||
}
|
||||
|
||||
- (void) drawVideoFrame;
|
||||
- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize
|
||||
mainBytes:(const GLvoid *)mainBytes
|
||||
touchBytes:(const GLvoid *)touchBytes;
|
||||
- (void) uploadSWRasterizerTextureData:(const GLvoid *)textureData textureSize:(NSSize)textureSize;
|
||||
- (void) renderSWRasterizer;
|
||||
- (void) setupSWRasterizerVertices;
|
||||
- (void) updateDisplayLists;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -650,14 +650,14 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
[view doVerticalSyncChanged:useVerticalSync];
|
||||
}
|
||||
|
||||
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID
|
||||
- (void) doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize
|
||||
{
|
||||
if (view == nil || ![view respondsToSelector:@selector(doVideoFilterChanged:)])
|
||||
if (view == nil || ![view respondsToSelector:@selector(doVideoFilterChanged:frameSize:)])
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[view doVideoFilterChanged:videoFilterTypeID];
|
||||
[view doVideoFilterChanged:videoFilterTypeID frameSize:videoFilterDestSize];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -902,14 +902,45 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
glTexBackSize = NSMakeSize(w, h);
|
||||
|
||||
OSXDefaultOpenGLContext = [[self openGLContext] retain];
|
||||
|
||||
NSOpenGLContext *prevContext = [NSOpenGLContext currentContext];
|
||||
[OSXDefaultOpenGLContext makeCurrentContext];
|
||||
|
||||
glGenTextures(2, swRasterizerDrawTexture);
|
||||
swRasterizerDisplayListIndex = glGenLists(3);
|
||||
|
||||
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
|
||||
&OSXOpenGLRendererBegin,
|
||||
&OSXOpenGLRendererEnd);
|
||||
|
||||
if (prevContext != nil)
|
||||
{
|
||||
[prevContext makeCurrentContext];
|
||||
}
|
||||
else
|
||||
{
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
NSOpenGLContext *prevContext = [NSOpenGLContext currentContext];
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
|
||||
glDeleteTextures(2, swRasterizerDrawTexture);
|
||||
glDeleteLists(swRasterizerDisplayListIndex, 3);
|
||||
|
||||
if (prevContext != nil)
|
||||
{
|
||||
[prevContext makeCurrentContext];
|
||||
}
|
||||
else
|
||||
{
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
free(glTexBack);
|
||||
glTexBack = NULL;
|
||||
|
@ -950,12 +981,6 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClearDepth(1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glGenTextures(2, &swRasterizerDrawTexture[0]);
|
||||
|
||||
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
|
||||
&OSXOpenGLRendererBegin,
|
||||
&OSXOpenGLRendererEnd);
|
||||
}
|
||||
|
||||
- (void) drawVideoFrame
|
||||
|
@ -963,100 +988,75 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
CGLFlushDrawable((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
}
|
||||
|
||||
- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize
|
||||
mainBytes:(const GLvoid *)mainBytes
|
||||
touchBytes:(const GLvoid *)touchBytes
|
||||
- (void) uploadSWRasterizerTextureData:(const GLvoid *)textureData textureSize:(NSSize)textureSize
|
||||
{
|
||||
uint32_t w = GetNearestPositivePOT((uint32_t)textureSize.width);
|
||||
uint32_t h = GetNearestPositivePOT((uint32_t)textureSize.height);
|
||||
NSInteger displayType = [dispViewDelegate displayType];
|
||||
|
||||
size_t bitDepth = sizeof(uint32_t);
|
||||
|
||||
if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
|
||||
if (textureData == NULL)
|
||||
{
|
||||
bitDepth = sizeof(uint16_t);
|
||||
return;
|
||||
}
|
||||
|
||||
if (glTexBackSize.width != w || glTexBackSize.height != h)
|
||||
switch (displayType)
|
||||
{
|
||||
glTexBackSize.width = w;
|
||||
glTexBackSize.height = h;
|
||||
|
||||
free(glTexBack);
|
||||
glTexBack = (GLvoid *)calloc((size_t)w * (size_t)h, bitDepth);
|
||||
if (glTexBack == NULL)
|
||||
case DS_DISPLAY_TYPE_MAIN:
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData);
|
||||
break;
|
||||
|
||||
case DS_DISPLAY_TYPE_TOUCH:
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData);
|
||||
break;
|
||||
|
||||
case DS_DISPLAY_TYPE_COMBO:
|
||||
{
|
||||
return;
|
||||
textureSize.height /= 2;
|
||||
size_t offset = (size_t)textureSize.width * (size_t)textureSize.height;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, textureData);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, (uint16_t *)textureData + offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, (uint32_t *)textureData + offset);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
swRasterizerMainTexCoord[0][0] = 0.0f;
|
||||
swRasterizerMainTexCoord[0][1] = 0.0f;
|
||||
swRasterizerMainTexCoord[1][0] = (GLfloat)(textureSize.width / w);
|
||||
swRasterizerMainTexCoord[1][1] = 0.0f;
|
||||
swRasterizerMainTexCoord[2][0] = (GLfloat)(textureSize.width / w);
|
||||
swRasterizerMainTexCoord[2][1] = (GLfloat)(textureSize.height / h);
|
||||
swRasterizerMainTexCoord[3][0] = 0.0f;
|
||||
swRasterizerMainTexCoord[3][1] = (GLfloat)(textureSize.height / h);
|
||||
|
||||
swRasterizerTouchTexCoord[0][0] = 0.0f;
|
||||
swRasterizerTouchTexCoord[0][1] = 0.0f;
|
||||
swRasterizerTouchTexCoord[1][0] = (GLfloat)(textureSize.width / w);
|
||||
swRasterizerTouchTexCoord[1][1] = 0.0f;
|
||||
swRasterizerTouchTexCoord[2][0] = (GLfloat)(textureSize.width / w);
|
||||
swRasterizerTouchTexCoord[2][1] = (GLfloat)(textureSize.height / h);
|
||||
swRasterizerTouchTexCoord[3][0] = 0.0f;
|
||||
swRasterizerTouchTexCoord[3][1] = (GLfloat)(textureSize.height / h);
|
||||
|
||||
// Main screen
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, mainBytes);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle);
|
||||
|
||||
// Touch screen
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (GLsizei)textureSize.width, (GLsizei)textureSize.height, GL_RGBA, glTexPixelFormat, touchBytes);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle);
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
}
|
||||
|
||||
- (void) renderSWRasterizer
|
||||
{
|
||||
NSInteger displayType = [dispViewDelegate displayType];
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Render the main screen
|
||||
if (displayType == DS_DISPLAY_TYPE_MAIN || displayType == DS_DISPLAY_TYPE_COMBO)
|
||||
switch (displayType)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(swRasterizerMainTexCoord[i][0], swRasterizerMainTexCoord[i][1]);
|
||||
glVertex2f(swRasterizerMainVertex[i][0], swRasterizerMainVertex[i][1]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Render the touch screen
|
||||
if (displayType == DS_DISPLAY_TYPE_TOUCH || displayType == DS_DISPLAY_TYPE_COMBO)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(swRasterizerTouchTexCoord[i][0], swRasterizerTouchTexCoord[i][1]);
|
||||
glVertex2f(swRasterizerTouchVertex[i][0], swRasterizerTouchVertex[i][1]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
case DS_DISPLAY_TYPE_MAIN:
|
||||
glCallList(swRasterizerDisplayListIndex);
|
||||
break;
|
||||
|
||||
case DS_DISPLAY_TYPE_TOUCH:
|
||||
glCallList(swRasterizerDisplayListIndex + 1);
|
||||
break;
|
||||
|
||||
case DS_DISPLAY_TYPE_COMBO:
|
||||
glCallList(swRasterizerDisplayListIndex + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1158,7 +1158,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else // displayType == DS_DISPLAY_TYPE_MAIN || displayType == DS_DISPLAY_TYPE_TOUCH
|
||||
{
|
||||
swRasterizerMainVertex[0][0] = -w/2.0f;
|
||||
swRasterizerMainVertex[0][1] = h/2.0f;
|
||||
|
@ -1180,6 +1180,71 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
}
|
||||
}
|
||||
|
||||
- (void) updateDisplayLists
|
||||
{
|
||||
// Main screen only
|
||||
glNewList(swRasterizerDisplayListIndex, GL_COMPILE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(swRasterizerMainTexCoord[i][0], swRasterizerMainTexCoord[i][1]);
|
||||
glVertex2f(swRasterizerMainVertex[i][0], swRasterizerMainVertex[i][1]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
glEndList();
|
||||
|
||||
// Touch screen only
|
||||
glNewList(swRasterizerDisplayListIndex + 1, GL_COMPILE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(swRasterizerTouchTexCoord[i][0], swRasterizerTouchTexCoord[i][1]);
|
||||
glVertex2f(swRasterizerTouchVertex[i][0], swRasterizerTouchVertex[i][1]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
glEndList();
|
||||
|
||||
// Combo screens
|
||||
glNewList(swRasterizerDisplayListIndex + 2, GL_COMPILE);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(swRasterizerMainTexCoord[i][0], swRasterizerMainTexCoord[i][1]);
|
||||
glVertex2f(swRasterizerMainVertex[i][0], swRasterizerMainVertex[i][1]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
for (unsigned int i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(swRasterizerTouchTexCoord[i][0], swRasterizerTouchTexCoord[i][1]);
|
||||
glVertex2f(swRasterizerTouchVertex[i][0], swRasterizerTouchVertex[i][1]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
glEndList();
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)theEvent
|
||||
{
|
||||
BOOL isHandled = [dispViewDelegate handleKeyPress:theEvent keyPressed:YES];
|
||||
|
@ -1292,10 +1357,9 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
SetupOpenGLView((GLsizei)rect.size.width, (GLsizei)rect.size.height, scale, rotation);
|
||||
[[self openGLContext] update];
|
||||
|
||||
CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
|
||||
[dispViewDelegate setViewToBlack];
|
||||
}
|
||||
|
||||
- (void)doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize
|
||||
|
@ -1304,44 +1368,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
|
||||
switch ([dispViewDelegate displayType])
|
||||
{
|
||||
case DS_DISPLAY_TYPE_MAIN:
|
||||
[self uploadSWRasterizerTexturesUsingSize:frameSize
|
||||
mainBytes:videoFrameData
|
||||
touchBytes:videoFrameData];
|
||||
break;
|
||||
|
||||
case DS_DISPLAY_TYPE_TOUCH:
|
||||
[self uploadSWRasterizerTexturesUsingSize:frameSize
|
||||
mainBytes:videoFrameData
|
||||
touchBytes:videoFrameData];
|
||||
break;
|
||||
|
||||
case DS_DISPLAY_TYPE_COMBO:
|
||||
{
|
||||
frameSize.height /= 2.0;
|
||||
|
||||
if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
|
||||
{
|
||||
[self uploadSWRasterizerTexturesUsingSize:frameSize
|
||||
mainBytes:videoFrameData
|
||||
touchBytes:(const uint16_t *)videoFrameData + ((size_t)frameSize.width * (size_t)frameSize.height)];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self uploadSWRasterizerTexturesUsingSize:frameSize
|
||||
mainBytes:videoFrameData
|
||||
touchBytes:(const uint32_t *)videoFrameData + ((size_t)frameSize.width * (size_t)frameSize.height)];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
[self uploadSWRasterizerTextureData:videoFrameData textureSize:frameSize];
|
||||
[self renderSWRasterizer];
|
||||
[self drawVideoFrame];
|
||||
|
||||
|
@ -1359,6 +1386,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
|
||||
[self setupSWRasterizerVertices];
|
||||
[self updateDisplayLists];
|
||||
}
|
||||
|
||||
- (void)doRedraw
|
||||
|
@ -1375,6 +1403,7 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
- (void)doDisplayTypeChanged:(NSInteger)displayTypeID
|
||||
{
|
||||
[self setupSWRasterizerVertices];
|
||||
[self updateDisplayLists];
|
||||
}
|
||||
|
||||
- (void)doBilinearOutputChanged:(BOOL)useBilinear
|
||||
|
@ -1384,16 +1413,28 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
{
|
||||
glTexRenderStyle = GL_LINEAR;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glTexRenderStyle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glTexRenderStyle);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
}
|
||||
|
||||
- (void) doDisplayOrientationChanged:(NSInteger)displayOrientationID
|
||||
{
|
||||
[self setupSWRasterizerVertices];
|
||||
[self updateDisplayLists];
|
||||
}
|
||||
|
||||
- (void) doDisplayOrderChanged:(NSInteger)displayOrderID
|
||||
{
|
||||
[self setupSWRasterizerVertices];
|
||||
[self updateDisplayLists];
|
||||
|
||||
if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO)
|
||||
{
|
||||
|
@ -1413,13 +1454,67 @@ NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
|||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID
|
||||
- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID frameSize:(NSSize)videoFilterDestSize
|
||||
{
|
||||
size_t colorDepth = sizeof(uint32_t);
|
||||
glTexPixelFormat = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
|
||||
if (videoFilterTypeID == VideoFilterTypeID_None)
|
||||
{
|
||||
colorDepth = sizeof(uint16_t);
|
||||
glTexPixelFormat = GL_UNSIGNED_SHORT_1_5_5_5_REV;
|
||||
}
|
||||
|
||||
if ([dispViewDelegate displayType] == DS_DISPLAY_TYPE_COMBO)
|
||||
{
|
||||
videoFilterDestSize.height /= 2.0;
|
||||
}
|
||||
|
||||
uint32_t w = GetNearestPositivePOT((uint32_t)videoFilterDestSize.width);
|
||||
uint32_t h = GetNearestPositivePOT((uint32_t)videoFilterDestSize.height);
|
||||
|
||||
if (glTexBackSize.width != w || glTexBackSize.height != h)
|
||||
{
|
||||
glTexBackSize.width = w;
|
||||
glTexBackSize.height = h;
|
||||
|
||||
free(glTexBack);
|
||||
glTexBack = (GLvoid *)calloc((size_t)w * (size_t)h, colorDepth);
|
||||
if (glTexBack == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Main screen
|
||||
swRasterizerMainTexCoord[0][0] = 0.0f;
|
||||
swRasterizerMainTexCoord[0][1] = 0.0f;
|
||||
swRasterizerMainTexCoord[1][0] = (GLfloat)(videoFilterDestSize.width / w);
|
||||
swRasterizerMainTexCoord[1][1] = 0.0f;
|
||||
swRasterizerMainTexCoord[2][0] = (GLfloat)(videoFilterDestSize.width / w);
|
||||
swRasterizerMainTexCoord[2][1] = (GLfloat)(videoFilterDestSize.height / h);
|
||||
swRasterizerMainTexCoord[3][0] = 0.0f;
|
||||
swRasterizerMainTexCoord[3][1] = (GLfloat)(videoFilterDestSize.height / h);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack);
|
||||
|
||||
// Touch screen
|
||||
swRasterizerTouchTexCoord[0][0] = 0.0f;
|
||||
swRasterizerTouchTexCoord[0][1] = 0.0f;
|
||||
swRasterizerTouchTexCoord[1][0] = (GLfloat)(videoFilterDestSize.width / w);
|
||||
swRasterizerTouchTexCoord[1][1] = 0.0f;
|
||||
swRasterizerTouchTexCoord[2][0] = (GLfloat)(videoFilterDestSize.width / w);
|
||||
swRasterizerTouchTexCoord[2][1] = (GLfloat)(videoFilterDestSize.height / h);
|
||||
swRasterizerTouchTexCoord[3][0] = 0.0f;
|
||||
swRasterizerTouchTexCoord[3][1] = (GLfloat)(videoFilterDestSize.height / h);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, glTexPixelFormat, glTexBack);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, NULL);
|
||||
|
||||
[self updateDisplayLists];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue