[Fuse-for-macosx-commits] SF.net SVN: fuse-for-macosx: [369] branches/fusegl/fuse
Brought to you by:
fredm
|
From: <fr...@us...> - 2007-05-15 12:46:37
|
Revision: 369
http://svn.sourceforge.net/fuse-for-macosx/?rev=369&view=rev
Author: fredm
Date: 2007-05-15 05:45:49 -0700 (Tue, 15 May 2007)
Log Message:
-----------
Add a second screen texture to ensure there is no reading of the old
texture while it is being updated, also add a buffer for the spectrum
screen seperate from the one being updated in the emulator thread to
prevent any synchronisation problems between the emulator and GUI
threads.
Modified Paths:
--------------
branches/fusegl/fuse/TODO
branches/fusegl/fuse/fusepb/English.lproj/InfoPlist.strings
branches/fusegl/fuse/fusepb/FuseMenus.h
branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.h
branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.m
branches/fusegl/fuse/ui/cocoa/cocoadisplay.h
branches/fusegl/fuse/ui/cocoa/cocoadisplay.m
Modified: branches/fusegl/fuse/TODO
===================================================================
--- branches/fusegl/fuse/TODO 2007-05-12 01:33:29 UTC (rev 368)
+++ branches/fusegl/fuse/TODO 2007-05-15 12:45:49 UTC (rev 369)
@@ -43,5 +43,8 @@
* Shouldn't be able to load Interface II carts in Pentagon
* Add volume option to standard fuse + a sound API method to set volume (or a
parameter to sound_lowlevel_init)
+* Save ROM into szx when using a non-default one
+* Randomise FRAMES sys var after autoload snapshot loaded in order to try and
+ get less deterministic program behaviour after load is complete
$Id: TODO,v 1.4 2004/03/02 13:38:08 pak21 Exp $
Modified: branches/fusegl/fuse/fusepb/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)
Modified: branches/fusegl/fuse/fusepb/FuseMenus.h
===================================================================
--- branches/fusegl/fuse/fusepb/FuseMenus.h 2007-05-12 01:33:29 UTC (rev 368)
+++ branches/fusegl/fuse/fusepb/FuseMenus.h 2007-05-15 12:45:49 UTC (rev 369)
@@ -28,8 +28,6 @@
#ifndef FUSEMENUS_H
#define FUSEMENUS_H
-#include "ui/cocoa/cocoadisplay.h"
-
void SetEmulationHz(float);
#endif /* #ifndef FUSEMENUS_H */
Modified: branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.h
===================================================================
--- branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.h 2007-05-12 01:33:29 UTC (rev 368)
+++ branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.h 2007-05-15 12:45:49 UTC (rev 369)
@@ -36,13 +36,16 @@
#include "ui/cocoa/cocoadisplay.h"
#include "ui/ui.h"
+#define MAX_SCREEN_BUFFERS 2
+
@class Emulator;
@interface DisplayOpenGLView : NSOpenGLView
{
/* Need texture size and dimensions and two backing textures */
- Cocoa_Texture screenTex; /* Screen texture */
- GLuint screenTexId;
+ Cocoa_Texture screenTex[MAX_SCREEN_BUFFERS]; /* Screen texture */
+ GLuint screenTexId[MAX_SCREEN_BUFFERS];
+ int currentScreenTex;
Cocoa_Texture redCassetteTex;
GLuint redCassette;
Modified: branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.m
===================================================================
--- branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.m 2007-05-12 01:33:29 UTC (rev 368)
+++ branches/fusegl/fuse/fusepb/views/DisplayOpenGLView.m 2007-05-15 12:45:49 UTC (rev 369)
@@ -137,8 +137,8 @@
break;
case 0:
default: /* Actual size */
- size.width = screenTex.image_width;
- size.height = screenTex.image_height;
+ size.width = screenTex[0].image_width;
+ size.height = screenTex[0].image_height;
}
[[self window] setContentSize:size];
@@ -224,6 +224,8 @@
[NSThread detachNewThreadSelector:@selector(connectWithPorts:)
toTarget:real_emulator withObject:portArray];
+ currentScreenTex = 0;
+
return self;
}
@@ -374,36 +376,40 @@
{
if( NO == screenTexInitialised ) return;
+ currentScreenTex = !currentScreenTex;
+
/* Need to draw texture to screen here */
/* FIXME: lock screen - direct lock probably faster [emulation lockScreen]; */
+ [buffered_screen_lock lock];
/* should draw directly from emulation screen instead of screenTex, switch between
buffers there */
- memcpy( screenTex.pixels, screen->pixels, screenTex.pitch * screenTex.full_height );
+ memcpy( screenTex[currentScreenTex].pixels, buffered_screen.pixels, screenTex[currentScreenTex].pitch * screenTex[currentScreenTex].full_height );
/* FIXME: unlock screen - direct lock probably faster [emulation unlockScreen]; */
+ [buffered_screen_lock unlock];
[[self openGLContext] makeCurrentContext];
glClear( GL_COLOR_BUFFER_BIT );
/* Bind, update and draw new image */
- glBindTexture( GL_TEXTURE_RECTANGLE_EXT, screenTexId );
+ glBindTexture( GL_TEXTURE_RECTANGLE_EXT, screenTexId[currentScreenTex] );
- glTexSubImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, screenTex.full_width,
- screenTex.full_height, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
- screenTex.pixels );
+ glTexSubImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, screenTex[currentScreenTex].full_width,
+ screenTex[currentScreenTex].full_height, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ screenTex[currentScreenTex].pixels );
glBegin( GL_QUADS );
- glTexCoord2f( (float)screenTex.image_width, (float)(screenTex.image_xoffset) );
+ glTexCoord2f( (float)screenTex[currentScreenTex].image_width, (float)(screenTex[currentScreenTex].image_xoffset) );
glVertex2f( 1.0f, 1.0f );
- glTexCoord2f( (float)screenTex.image_width, (float)screenTex.image_height );
+ glTexCoord2f( (float)screenTex[currentScreenTex].image_width, (float)screenTex[currentScreenTex].image_height );
glVertex2f( 1.0f, -1.0f );
- glTexCoord2f( (float)screenTex.image_xoffset, (float)screenTex.image_height );
+ glTexCoord2f( (float)screenTex[currentScreenTex].image_xoffset, (float)screenTex[currentScreenTex].image_height );
glVertex2f( -1.0f, -1.0f );
- glTexCoord2f( (float)screenTex.image_xoffset, (float)screenTex.image_yoffset );
+ glTexCoord2f( (float)screenTex[currentScreenTex].image_xoffset, (float)screenTex[currentScreenTex].image_yoffset );
glVertex2f( -1.0f, 1.0f );
glEnd();
@@ -482,47 +488,47 @@
if( screenTexInitialised == NO) return;
/* FIXME: May want to have a double buffered texture later */
-#if 0
- for(i = 0; i < 1; i++) {
- GLint dt = i+1;
- glDeleteTextures(1, &dt);
+ glDeleteTextures( MAX_SCREEN_BUFFERS, screenTexId );
+ for(i = 0; i < MAX_SCREEN_BUFFERS; i++)
+ {
+ free( screenTex[i].pixels );
+ screenTex[i].pixels = NULL;
}
-#endif
- glDeleteTextures( 1, &screenTexId );
screenTexInitialised = NO;
}
--(void) createTexture:(Cocoa_Texture*)newScreen;
+-(void) createTexture:(Cocoa_Texture*)newScreen
{
- GLint i;
+ GLuint i;
- screenTex.full_width = newScreen->full_width;
- screenTex.full_height = newScreen->full_height;
- screenTex.image_width = newScreen->image_width;
- screenTex.image_height = newScreen->image_height;
- screenTex.image_xoffset = newScreen->image_xoffset;
- screenTex.image_yoffset = newScreen->image_yoffset;
- screenTex.pixels = calloc( screenTex.full_width * screenTex.full_height, sizeof(uint16_t) );
- if( !screenTex.pixels ) {
- fprintf( stderr, "%s: couldn't create screenTex.pixels\n", fuse_progname );
- return;
- }
- screenTex.pitch = screenTex.full_width * sizeof(uint16_t);
-
[[self openGLContext] makeCurrentContext];
[[self openGLContext] update];
/* FIXME: May want to have a double buffered texture later */
- //for(i = 0; i < 1; i++)
- //{
- glGenTextures( 1, &screenTexId );
+ glGenTextures( MAX_SCREEN_BUFFERS, screenTexId );
+
+ for(i = 0; i < MAX_SCREEN_BUFFERS; i++)
+ {
+ screenTex[i].full_width = newScreen->full_width;
+ screenTex[i].full_height = newScreen->full_height;
+ screenTex[i].image_width = newScreen->image_width;
+ screenTex[i].image_height = newScreen->image_height;
+ screenTex[i].image_xoffset = newScreen->image_xoffset;
+ screenTex[i].image_yoffset = newScreen->image_yoffset;
+ screenTex[i].pixels = calloc( screenTex[i].full_width * screenTex[i].full_height, sizeof(uint16_t) );
+ if( !screenTex[i].pixels ) {
+ fprintf( stderr, "%s: couldn't create screenTex[%ud].pixels\n", fuse_progname, (unsigned int)i );
+ return;
+ }
+ screenTex[i].pitch = screenTex[i].full_width * sizeof(uint16_t);
+
glDisable( GL_TEXTURE_2D );
glEnable( GL_TEXTURE_RECTANGLE_EXT );
- glBindTexture( GL_TEXTURE_RECTANGLE_EXT, screenTexId );
+ glBindTexture( GL_TEXTURE_RECTANGLE_EXT, screenTexId[i] );
glTextureRangeAPPLE( GL_TEXTURE_RECTANGLE_EXT,
- screenTex.full_width * screenTex.pitch,
- screenTex.pixels );
+ screenTex[i].full_width * screenTex[i].pitch,
+ screenTex[i].pixels );
glTexParameteri( GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE,
GL_STORAGE_CACHED_APPLE );
@@ -534,10 +540,10 @@
glTexParameteri( GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
- glTexImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, screenTex.full_width,
- screenTex.full_height, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
- screenTex.pixels );
- //}
+ glTexImage2D( GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, screenTex[i].full_width,
+ screenTex[i].full_height, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV,
+ screenTex[i].pixels );
+ }
screenTexInitialised = YES;
}
Modified: branches/fusegl/fuse/ui/cocoa/cocoadisplay.h
===================================================================
--- branches/fusegl/fuse/ui/cocoa/cocoadisplay.h 2007-05-12 01:33:29 UTC (rev 368)
+++ branches/fusegl/fuse/ui/cocoa/cocoadisplay.h 2007-05-15 12:45:49 UTC (rev 369)
@@ -27,6 +27,8 @@
#ifndef FUSE_COCOADISPLAY_H
#define FUSE_COCOADISPLAY_H
+#import <Foundation/NSLock.h>
+
#include "ui/ui.h"
typedef struct Cocoa_Texture {
@@ -43,6 +45,9 @@
/* Screen texture */
extern Cocoa_Texture* screen;
+extern NSLock *buffered_screen_lock;
+extern Cocoa_Texture buffered_screen;
+
void cocoadisplay_display_updated( void );
#endif /* #ifndef FUSE_COCOADISPLAY_H */
Modified: branches/fusegl/fuse/ui/cocoa/cocoadisplay.m
===================================================================
--- branches/fusegl/fuse/ui/cocoa/cocoadisplay.m 2007-05-12 01:33:29 UTC (rev 368)
+++ branches/fusegl/fuse/ui/cocoa/cocoadisplay.m 2007-05-15 12:45:49 UTC (rev 369)
@@ -62,6 +62,12 @@
/* Screen texture after scaling (only if a transforming scaler is in place) */
Cocoa_Texture scaled_screen;
+/* Screen texture second buffer */
+Cocoa_Texture buffered_screen;
+
+/* and a lock to protect it from concurrent access */
+NSLock *buffered_screen_lock;
+
/* Colours are in 1A 5R 5G 5B format */
static uint16_t colour_values[] = {
0x0000,
@@ -117,10 +123,10 @@
static int
allocate_screen( Cocoa_Texture* screen, int height, int width,
- float scaling_factor )
+ float scaling_factor )
{
- screen->image_width = image_width * display_current_size;
- screen->image_height = image_height * display_current_size;
+ screen->image_width = width * scaling_factor;
+ screen->image_height = height * scaling_factor;
/* Need some extra bytes around when using 2xSaI */
screen->full_width = screen->image_width+3;
@@ -130,7 +136,7 @@
screen->pixels = calloc( screen->full_width*screen->full_height, sizeof(uint16_t) );
if( !screen->pixels ) {
- fprintf( stderr, "%s: couldn't create screen.pixels\n", fuse_progname );
+ fprintf( stderr, "%s: couldn't allocate screen.pixels\n", fuse_progname );
return 1;
}
@@ -168,8 +174,12 @@
screen = &scaled_screen;
}
+ error = allocate_screen( &buffered_screen, screen->image_height,
+ screen->image_width, 1.0f );
+ if( error ) return error;
+
/* Create OpenGL textures for the image in DisplayOpenGLView */
- [[DisplayOpenGLView instance] createTexture:screen];
+ [[DisplayOpenGLView instance] createTexture:&buffered_screen];
/* Redraw the entire screen... */
display_refresh_all();
@@ -213,6 +223,9 @@
if ( scaler_select_scaler( current_scaler ) )
scaler_select_scaler( SCALER_NORMAL );
+ buffered_screen_lock = [[NSLock alloc] init];
+ [buffered_screen_lock retain];
+
cocoadisplay_load_gfx_mode();
/* We can now output error messages to our output device */
@@ -229,6 +242,7 @@
/* Free the old surfaces */
free_screen( &unscaled_screen );
free_screen( &scaled_screen );
+ free_screen( &buffered_screen );
/* Setup the new GFX mode */
cocoadisplay_load_gfx_mode();
@@ -371,6 +385,12 @@
uidisplay_frame_end( void )
{
if( display_updated )
+ /* obtain lock for buffered screen */
+ [buffered_screen_lock lock];
+ /* copy screen data to buffered screen */
+ memcpy( buffered_screen.pixels, screen->pixels, screen->pitch * screen->full_height );
+ /* release lock for buffered screen */
+ [buffered_screen_lock unlock];
[[DisplayOpenGLView instance]
performSelectorOnMainThread:@selector(setNeedsDisplayYes)
withObject:nil
@@ -410,8 +430,11 @@
[[DisplayOpenGLView instance] destroyTexture];
}
+ [buffered_screen_lock release];
+
free_screen( &unscaled_screen );
free_screen( &scaled_screen );
+ free_screen( &buffered_screen );
return 0;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|