Cocoa Port:
- Refactor video output code to not assume the use of SoftRasterizer - Change SoftRasterizer-based video output in combo display mode to draw a separate quad for each DS screen, instead of drawing one big quad for both screens - Begin adding preliminary support for the OpenGL 3D renderer - Misc. code cleanup
This commit is contained in:
parent
4e7b94f75e
commit
4f282c9499
|
@ -180,6 +180,8 @@
|
|||
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData;
|
||||
- (void) handleCopyToPasteboard;
|
||||
|
||||
- (void) fillVideoFrameWithColor:(UInt8)colorValue;
|
||||
|
||||
- (NSImage *) image;
|
||||
- (NSBitmapImageRep *) bitmapImageRep;
|
||||
|
||||
|
@ -195,14 +197,16 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
bool opengl_init();
|
||||
|
||||
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 SetOpenGLRendererFunctions(bool (*initFunction)(),
|
||||
bool (*beginOGLFunction)(),
|
||||
void (*endOGLFunction)());
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
GPU3DInterface *core3DList[] = {
|
||||
&gpu3DNull,
|
||||
&gpu3DRasterize,
|
||||
//&gpu3Dgl,
|
||||
&gpu3Dgl,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1267,74 +1267,12 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
- (void) handleSetViewToBlack
|
||||
{
|
||||
NSSize destSize = [vf destSize];
|
||||
NSUInteger dataSize = (NSUInteger)destSize.width * (NSUInteger)destSize.height;
|
||||
|
||||
void *texData = NULL;
|
||||
if ([vf typeID] == VideoFilterTypeID_None)
|
||||
{
|
||||
texData = calloc(dataSize, sizeof(UInt16));
|
||||
dataSize *= sizeof(UInt16);
|
||||
}
|
||||
else
|
||||
{
|
||||
texData = calloc(dataSize, sizeof(UInt32));
|
||||
dataSize *= sizeof(UInt32);
|
||||
}
|
||||
|
||||
if (texData == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NSData *gpuData = [[[NSData alloc] initWithBytes:texData length:dataSize] autorelease];
|
||||
if (gpuData == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[delegate doProcessVideoFrame:texData frameSize:destSize];
|
||||
|
||||
self.frameData = gpuData;
|
||||
|
||||
free(texData);
|
||||
texData = nil;
|
||||
[self fillVideoFrameWithColor:0];
|
||||
}
|
||||
|
||||
- (void) handleSetViewToWhite
|
||||
{
|
||||
NSSize destSize = [vf destSize];
|
||||
NSUInteger dataSize = (NSUInteger)destSize.width * (NSUInteger)destSize.height;
|
||||
|
||||
if ([vf typeID] == VideoFilterTypeID_None)
|
||||
{
|
||||
dataSize *= sizeof(UInt16);
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize *= sizeof(UInt32);
|
||||
}
|
||||
|
||||
void *texData = malloc(dataSize);
|
||||
if (texData == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
memset(texData, 255, dataSize);
|
||||
|
||||
NSData *gpuData = [[[NSData alloc] initWithBytes:texData length:dataSize] autorelease];
|
||||
if (gpuData == nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
[delegate doProcessVideoFrame:texData frameSize:destSize];
|
||||
|
||||
self.frameData = gpuData;
|
||||
|
||||
free(texData);
|
||||
texData = nil;
|
||||
[self fillVideoFrameWithColor:255];
|
||||
}
|
||||
|
||||
- (void) handleRequestScreenshot:(NSData *)fileURLStringData fileTypeData:(NSData *)fileTypeData
|
||||
|
@ -1368,6 +1306,24 @@ GPU3DInterface *core3DList[] = {
|
|||
[pboard setData:[screenshot TIFFRepresentationUsingCompression:NSTIFFCompressionLZW factor:1.0f] forType:NSTIFFPboardType];
|
||||
}
|
||||
|
||||
- (void) fillVideoFrameWithColor:(UInt8)colorValue
|
||||
{
|
||||
UInt16 *gpuBytes = (UInt16 *)malloc(GPU_SCREEN_SIZE_BYTES * 2);
|
||||
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];
|
||||
|
||||
free(gpuBytes);
|
||||
gpuBytes = nil;
|
||||
|
||||
[self handleEmuFrameProcessed:gpuData];
|
||||
}
|
||||
|
||||
- (NSImage *) image
|
||||
{
|
||||
NSImage *newImage = [[NSImage alloc] initWithSize:[vf srcSize]];
|
||||
|
@ -1533,11 +1489,6 @@ GPU3DInterface *core3DList[] = {
|
|||
|
||||
@end
|
||||
|
||||
bool opengl_init(void)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleMessageEchoResponse(NSPortMessage *portMessage)
|
||||
{
|
||||
NSPortMessage *echo = [[NSPortMessage alloc] initWithSendPort:[portMessage receivePort] receivePort:[portMessage sendPort] components:nil];
|
||||
|
@ -1676,3 +1627,12 @@ bool GetGPUDisplayState(int displayType)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SetOpenGLRendererFunctions(bool (*initFunction)(),
|
||||
bool (*beginOGLFunction)(),
|
||||
void (*endOGLFunction)())
|
||||
{
|
||||
oglrender_init = initFunction;
|
||||
oglrender_beginOpenGL = beginOGLFunction;
|
||||
oglrender_endOpenGL = endOGLFunction;
|
||||
}
|
||||
|
|
|
@ -130,11 +130,14 @@
|
|||
GLenum glTexPixelFormat;
|
||||
GLvoid *glTexBack;
|
||||
NSSize glTexBackSize;
|
||||
GLuint drawTexture[1];
|
||||
GLuint swRasterizerDrawTexture[2];
|
||||
}
|
||||
|
||||
- (void) drawVideoFrame;
|
||||
- (void) uploadFrameTexture:(const GLvoid *)frameBytes textureSize:(NSSize)textureSize;
|
||||
- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize
|
||||
mainBytes:(const GLvoid *)mainBytes
|
||||
touchBytes:(const GLvoid *)touchBytes;
|
||||
- (void) renderSWRasterizer;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -144,6 +147,9 @@ extern "C"
|
|||
#endif
|
||||
|
||||
void SetupOpenGLView(GLsizei width, GLsizei height, GLfloat scalar, GLfloat angleDegrees);
|
||||
bool OSXOpenGLRendererInit();
|
||||
bool OSXOpenGLRendererBegin();
|
||||
void OSXOpenGLRendererEnd();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#undef BOOL
|
||||
|
||||
NSOpenGLContext *OSXDefaultOpenGLContext = nil;
|
||||
|
||||
@implementation DisplayViewDelegate
|
||||
|
||||
@synthesize view;
|
||||
|
@ -797,6 +799,9 @@
|
|||
glTexBack = (GLvoid *)calloc(w * h, sizeof(UInt16));
|
||||
glTexBackSize = NSMakeSize(w, h);
|
||||
|
||||
OSXDefaultOpenGLContext = [[self openGLContext] retain];
|
||||
[OSXDefaultOpenGLContext makeCurrentContext];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -843,52 +848,31 @@
|
|||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClearDepth(1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glGenTextures(1, &drawTexture[0]);
|
||||
glBindTexture(GL_TEXTURE_2D, drawTexture[0]);
|
||||
|
||||
glGenTextures(2, &swRasterizerDrawTexture[0]);
|
||||
|
||||
SetOpenGLRendererFunctions(&OSXOpenGLRendererInit,
|
||||
&OSXOpenGLRendererBegin,
|
||||
&OSXOpenGLRendererEnd);
|
||||
}
|
||||
|
||||
- (void) drawVideoFrame
|
||||
{
|
||||
GLfloat w = (GLfloat)dispViewDelegate.normalSize.width;
|
||||
GLfloat h = (GLfloat)dispViewDelegate.normalSize.height;
|
||||
GLfloat texRatioW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((UInt32)lastFrameSize.width);
|
||||
GLfloat texRatioH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((UInt32)lastFrameSize.height);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-(w/2.0f), (h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioW, 0.0f);
|
||||
glVertex3f((w/2.0f), (h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioW, texRatioH);
|
||||
glVertex3f((w/2.0f), -(h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(0.0f, texRatioH);
|
||||
glVertex3f(-(w/2.0f), -(h/2.0f), 0.0f);
|
||||
|
||||
glEnd();
|
||||
|
||||
CGLFlushDrawable((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
}
|
||||
|
||||
- (void) uploadFrameTexture:(const GLvoid *)frameBytes textureSize:(NSSize)textureSize
|
||||
- (void) uploadSWRasterizerTexturesUsingSize:(NSSize)textureSize
|
||||
mainBytes:(const GLvoid *)mainBytes
|
||||
touchBytes:(const GLvoid *)touchBytes
|
||||
{
|
||||
UInt32 w = GetNearestPositivePOT((UInt32)textureSize.width);
|
||||
UInt32 h = GetNearestPositivePOT((UInt32)textureSize.height);
|
||||
NSUInteger bitDepth;
|
||||
uint32_t w = GetNearestPositivePOT((uint32_t)textureSize.width);
|
||||
uint32_t h = GetNearestPositivePOT((uint32_t)textureSize.height);
|
||||
|
||||
size_t bitDepth = sizeof(uint32_t);
|
||||
|
||||
if (glTexPixelFormat == GL_UNSIGNED_SHORT_1_5_5_5_REV)
|
||||
{
|
||||
bitDepth = sizeof(UInt16);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitDepth = sizeof(UInt32);
|
||||
bitDepth = sizeof(uint16_t);
|
||||
}
|
||||
|
||||
if (glTexBackSize.width != w || glTexBackSize.height != h)
|
||||
|
@ -897,17 +881,107 @@
|
|||
glTexBackSize.height = h;
|
||||
|
||||
free(glTexBack);
|
||||
glTexBack = (GLvoid *)calloc(w * h, bitDepth);
|
||||
glTexBack = (GLvoid *)calloc((size_t)w * (size_t)h, bitDepth);
|
||||
if (glTexBack == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 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, frameBytes);
|
||||
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);
|
||||
}
|
||||
|
||||
- (void) renderSWRasterizer
|
||||
{
|
||||
NSInteger displayType = [dispViewDelegate displayType];
|
||||
GLfloat w = (GLfloat)dispViewDelegate.normalSize.width;
|
||||
GLfloat h = (GLfloat)dispViewDelegate.normalSize.height;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (displayType == DS_DISPLAY_TYPE_COMBO)
|
||||
{
|
||||
GLfloat texRatioMainW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.width);
|
||||
GLfloat texRatioMainH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.height);
|
||||
GLfloat texRatioTouchW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.width);
|
||||
GLfloat texRatioTouchH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.height);
|
||||
|
||||
// Main screen
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[0]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-(w/2.0f), (h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioMainW, 0.0f);
|
||||
glVertex3f((w/2.0f), (h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioMainW, texRatioMainH);
|
||||
glVertex3f((w/2.0f), 0.0f, 0.0f);
|
||||
|
||||
glTexCoord2f(0.0f, texRatioMainH);
|
||||
glVertex3f(-(w/2.0f), 0.0f, 0.0f);
|
||||
|
||||
glEnd();
|
||||
|
||||
// Touch screen
|
||||
glBindTexture(GL_TEXTURE_2D, swRasterizerDrawTexture[1]);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-(w/2.0f), 0.0f, 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioTouchW, 0.0f);
|
||||
glVertex3f((w/2.0f), 0.0f, 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioTouchW, texRatioTouchH);
|
||||
glVertex3f((w/2.0f), -(h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(0.0f, texRatioTouchH);
|
||||
glVertex3f(-(w/2.0f), -(h/2.0f), 0.0f);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
GLfloat texRatioW = (GLfloat)lastFrameSize.width / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.width);
|
||||
GLfloat texRatioH = (GLfloat)lastFrameSize.height / (GLfloat)GetNearestPositivePOT((uint32_t)lastFrameSize.height);
|
||||
GLuint drawTexture = swRasterizerDrawTexture[0];
|
||||
|
||||
if (displayType == DS_DISPLAY_TYPE_TOUCH)
|
||||
{
|
||||
drawTexture = swRasterizerDrawTexture[1];
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, drawTexture);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex3f(-(w/2.0f), (h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioW, 0.0f);
|
||||
glVertex3f((w/2.0f), (h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(texRatioW, texRatioH);
|
||||
glVertex3f((w/2.0f), -(h/2.0f), 0.0f);
|
||||
|
||||
glTexCoord2f(0.0f, texRatioH);
|
||||
glVertex3f(-(w/2.0f), -(h/2.0f), 0.0f);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)theEvent
|
||||
|
@ -1030,11 +1104,51 @@
|
|||
|
||||
- (void)doProcessVideoFrame:(const void *)videoFrameData frameSize:(NSSize)frameSize
|
||||
{
|
||||
lastFrameSize = frameSize;
|
||||
|
||||
CGLLockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
[self uploadFrameTexture:(const GLvoid *)videoFrameData textureSize:frameSize];
|
||||
lastFrameSize = frameSize;
|
||||
|
||||
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 renderSWRasterizer];
|
||||
[self drawVideoFrame];
|
||||
|
||||
CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
|
@ -1056,6 +1170,7 @@
|
|||
CGLLockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
[self renderSWRasterizer];
|
||||
[self drawVideoFrame];
|
||||
|
||||
CGLUnlockContext((CGLContextObj)[[self openGLContext] CGLContextObj]);
|
||||
|
@ -1072,17 +1187,14 @@
|
|||
|
||||
- (void) doVerticalSyncChanged:(BOOL)useVerticalSync
|
||||
{
|
||||
GLint swapInt = 1;
|
||||
GLint swapInt = 0;
|
||||
|
||||
if (useVerticalSync)
|
||||
{
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
else
|
||||
{
|
||||
swapInt = 0;
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
swapInt = 1;
|
||||
}
|
||||
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
- (void)doVideoFilterChanged:(NSInteger)videoFilterTypeID
|
||||
|
@ -1107,3 +1219,23 @@ void SetupOpenGLView(GLsizei width, GLsizei height, GLfloat scalar, GLfloat angl
|
|||
glRotatef((GLfloat)CLOCKWISE_DEGREES(angleDegrees), 0.0f, 0.0f, 1.0f);
|
||||
glScalef(scalar, scalar, 0.0f);
|
||||
}
|
||||
|
||||
bool OSXOpenGLRendererInit()
|
||||
{
|
||||
[OSXDefaultOpenGLContext makeCurrentContext];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OSXOpenGLRendererBegin()
|
||||
{
|
||||
CGLLockContext((CGLContextObj)[OSXDefaultOpenGLContext CGLContextObj]);
|
||||
[OSXDefaultOpenGLContext makeCurrentContext];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSXOpenGLRendererEnd()
|
||||
{
|
||||
CGLUnlockContext((CGLContextObj)[OSXDefaultOpenGLContext CGLContextObj]);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue