From 5b6f1c5f5e1c34015d013c9617c20fe2ecb1c71f Mon Sep 17 00:00:00 2001 From: stephena Date: Wed, 23 Jun 2004 03:43:47 +0000 Subject: [PATCH] Reworked the OpenGL class yet again. I figured out how to fix the problems in Windows without all the invasive changes, so I reverted most of it. Snapshots are now fully working in both software/OpenGL and windowed/fullscreen modes. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@278 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- stella/src/common/FrameBufferGL.cxx | 54 ++++++++++----------------- stella/src/common/FrameBufferSoft.cxx | 9 +++-- stella/src/emucore/FrameBuffer.cxx | 14 ++++++- stella/src/emucore/FrameBuffer.hxx | 7 +++- 4 files changed, 41 insertions(+), 43 deletions(-) diff --git a/stella/src/common/FrameBufferGL.cxx b/stella/src/common/FrameBufferGL.cxx index 72a775c3c..e248349f0 100644 --- a/stella/src/common/FrameBufferGL.cxx +++ b/stella/src/common/FrameBufferGL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferGL.cxx,v 1.4 2004-06-23 00:33:37 stephena Exp $ +// $Id: FrameBufferGL.cxx,v 1.5 2004-06-23 03:43:47 stephena Exp $ //============================================================================ #include @@ -47,14 +47,15 @@ FrameBufferGL::~FrameBufferGL() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferGL::createScreen() { - uInt32 screenWidth = 0, screenHeight = 0; - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, myRGB[0] ); SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, myRGB[1] ); SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, myRGB[2] ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + uInt32 screenWidth = 0; + uInt32 screenHeight = 0; + myDimensions.w = (Uint16) (myWidth * theZoomLevel * theAspectRatio); myDimensions.h = (Uint16) myHeight * theZoomLevel; @@ -67,8 +68,8 @@ bool FrameBufferGL::createScreen() myDimensions.x = rect.x; myDimensions.y = rect.y; - screenWidth = rect.w; - screenHeight = rect.h; + screenWidth = rect.w; + screenHeight = rect.h; } else { @@ -87,13 +88,14 @@ bool FrameBufferGL::createScreen() glPushAttrib(GL_ENABLE_BIT); // Center the screen horizontally and vertically - glViewport(0, 0, screenWidth, screenHeight); + glViewport(myDimensions.x, myDimensions.y, myDimensions.w, myDimensions.h); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); - glOrtho(0.0, screenWidth, screenHeight, 0.0, 0.0, 1.0); + glOrtho(0.0, (GLdouble) myDimensions.w/(theZoomLevel * theAspectRatio), + (GLdouble) myDimensions.h/theZoomLevel, 0.0, 0.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); @@ -199,9 +201,6 @@ bool FrameBufferGL::init() break; } - // Set the color used to erase the screen - glClearColor(0, 0, 0, 1); - // Create the screen if(!createScreen()) return false; @@ -283,37 +282,23 @@ void FrameBufferGL::drawMediaSource() } } + // If necessary, erase the screen + if(theRedrawEntireFrameIndicator) + glClear(GL_COLOR_BUFFER_BIT); + // Texturemap complete texture to surface so we have free scaling // and antialiasing glBindTexture(GL_TEXTURE_2D, myTextureID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, myTexture->w, myTexture->h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); -// glColor3f(0.0, 0.0, 0.0); -// glRecti(0, 0, myDimensions.w, myDimensions.h); glBegin(GL_QUADS); - glTexCoord2f(myTexCoord[0], myTexCoord[1]); - glVertex2i(myDimensions.x, myDimensions.y); - - glTexCoord2f(myTexCoord[2], myTexCoord[1]); - glVertex2i(myDimensions.x + myDimensions.w, myDimensions.y); - - glTexCoord2f(myTexCoord[2], myTexCoord[3]); - glVertex2i(myDimensions.x + myDimensions.w, myDimensions.y + myDimensions.h); - - glTexCoord2f(myTexCoord[0], myTexCoord[3]); - glVertex2i(myDimensions.x, myDimensions.y + myDimensions.h); - glEnd(); - -/* - glBegin(GL_QUADS); - glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0); + glTexCoord2f(myTexCoord[0], myTexCoord[1]); glVertex2i(0, 0); glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(myWidth, 0); glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(myWidth, myHeight); - glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight); + glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight); glEnd(); -*/ // The frame doesn't need to be completely redrawn anymore theRedrawEntireFrameIndicator = false; @@ -377,10 +362,10 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data) { // Invert the row, since OpenGL rows start at the bottom // of the framebuffer - row = myDimensions.h - row - 1; + row = myDimensions.h + myDimensions.y - row - 1; glPixelStorei(GL_PACK_ALIGNMENT, 1); - glReadPixels(0, row, myDimensions.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data); + glReadPixels(myDimensions.x, row, myDimensions.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -540,17 +525,16 @@ SDL_Rect FrameBufferGL::viewport(uInt32 width, uInt32 height) }; // List of valid fullscreen OpenGL modes - Screenmode myScreenmode[7] = { + Screenmode myScreenmode[6] = { {320, 240 }, {640, 480 }, {800, 600 }, {1024, 768 }, {1280, 1024}, - {1400, 1050}, {1600, 1200} }; - for(uInt32 i = 0; i < 7; i++) + for(uInt32 i = 0; i < 6; i++) { if(width <= myScreenmode[i].w && height <= myScreenmode[i].h) { diff --git a/stella/src/common/FrameBufferSoft.cxx b/stella/src/common/FrameBufferSoft.cxx index 92d6c6a8b..28e6cabd4 100644 --- a/stella/src/common/FrameBufferSoft.cxx +++ b/stella/src/common/FrameBufferSoft.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBufferSoft.cxx,v 1.2 2004-06-20 23:30:48 stephena Exp $ +// $Id: FrameBufferSoft.cxx,v 1.3 2004-06-23 03:43:47 stephena Exp $ //============================================================================ #include @@ -42,10 +42,11 @@ FrameBufferSoft::~FrameBufferSoft() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool FrameBufferSoft::createScreen() { - int w = myWidth * theZoomLevel; - int h = myHeight * theZoomLevel; + myDimensions.x = myDimensions.y = 0; + myDimensions.w = myWidth * theZoomLevel; + myDimensions.h = myHeight * theZoomLevel; - myScreen = SDL_SetVideoMode(w, h, 0, mySDLFlags); + myScreen = SDL_SetVideoMode(myDimensions.w, myDimensions.h, 0, mySDLFlags); if(myScreen == NULL) { cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl; diff --git a/stella/src/emucore/FrameBuffer.cxx b/stella/src/emucore/FrameBuffer.cxx index a2ed3982b..64a429ce3 100644 --- a/stella/src/emucore/FrameBuffer.cxx +++ b/stella/src/emucore/FrameBuffer.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBuffer.cxx,v 1.8 2004-04-27 00:50:51 stephena Exp $ +// $Id: FrameBuffer.cxx,v 1.9 2004-06-23 03:43:47 stephena Exp $ //============================================================================ #include @@ -70,6 +70,7 @@ FrameBuffer::FrameBuffer() myRemapMenuMaxLines(0), myMessageTime(0), myMessageText(""), + myMenuRedraws(2), myInfoMenuWidth(0) { } @@ -210,7 +211,15 @@ void FrameBuffer::update() } // Now the screen is up to date - theMenuChangedIndicator = theRedrawEntireFrameIndicator = false; + theRedrawEntireFrameIndicator = false; + + // This is a performance hack to only draw the menus when necessary + // Software mode is single-buffered, so we don't have to worry + // However, OpenGL mode is double-buffered, so we need to draw the + // menus at least twice (so they'll be in both buffers) + // Otherwise, we get horrible flickering + myMenuRedraws--; + theMenuChangedIndicator = (myMenuRedraws != 0); } } @@ -334,6 +343,7 @@ void FrameBuffer::sendKeyEvent(StellaEvent::KeyCode key, Int32 state) // Redraw the menus whenever a key event is received theMenuChangedIndicator = true; + myMenuRedraws = 2; // Check which type of widget is pending switch(myCurrentWidget) diff --git a/stella/src/emucore/FrameBuffer.hxx b/stella/src/emucore/FrameBuffer.hxx index 289b84040..8d7eae03b 100644 --- a/stella/src/emucore/FrameBuffer.hxx +++ b/stella/src/emucore/FrameBuffer.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: FrameBuffer.hxx,v 1.9 2004-06-23 00:15:32 stephena Exp $ +// $Id: FrameBuffer.hxx,v 1.10 2004-06-23 03:43:47 stephena Exp $ //============================================================================ #ifndef FRAMEBUFFER_HXX @@ -35,7 +35,7 @@ class Console; can be changed. @author Stephen Anthony - @version $Id: FrameBuffer.hxx,v 1.9 2004-06-23 00:15:32 stephena Exp $ + @version $Id: FrameBuffer.hxx,v 1.10 2004-06-23 03:43:47 stephena Exp $ */ class FrameBuffer { @@ -324,6 +324,9 @@ class FrameBuffer // Message text string myMessageText; + // Number of times menu have been drawn + uInt32 myMenuRedraws; + // The width of the information menu, determined by the longest string Int32 myInfoMenuWidth;