OpenGL mode is working again, except it doesn't yet render any text.

Also took the opportunity to clean up the FrameBuffer classes.  There
was a lot of cruddy code there ...


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@387 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-03-28 00:04:54 +00:00
parent b5fb1d277d
commit 8d67d0c760
10 changed files with 822 additions and 699 deletions

View File

@ -13,7 +13,7 @@
## See the file "license" for information on usage and redistribution of ## See the file "license" for information on usage and redistribution of
## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## this file, and for a DISCLAIMER OF ALL WARRANTIES.
## ##
## $Id: makefile,v 1.68 2005-03-27 03:07:33 stephena Exp $ ## $Id: makefile,v 1.69 2005-03-28 00:04:49 stephena Exp $
##============================================================================ ##============================================================================
##============================================================================ ##============================================================================

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBufferGL.cxx,v 1.14 2005-02-22 18:40:52 stephena Exp $ // $Id: FrameBufferGL.cxx,v 1.15 2005-03-28 00:04:53 stephena Exp $
//============================================================================ //============================================================================
#include <SDL.h> #include <SDL.h>
@ -26,6 +26,8 @@
#include "MediaSrc.hxx" #include "MediaSrc.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include "OSystem.hxx" #include "OSystem.hxx"
#include "StellaFont.hxx"
#include "GuiUtils.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBufferGL::FrameBufferGL(OSystem* osystem) FrameBufferGL::FrameBufferGL(OSystem* osystem)
@ -34,7 +36,8 @@ FrameBufferGL::FrameBufferGL(OSystem* osystem)
myScreenmode(0), myScreenmode(0),
myScreenmodeCount(0), myScreenmodeCount(0),
myFilterParam(GL_NEAREST), myFilterParam(GL_NEAREST),
myFilterParamName("GL_NEAREST") myFilterParamName("GL_NEAREST"),
myFSScaleFactor(1.0)
{ {
} }
@ -155,6 +158,12 @@ bool FrameBufferGL::initSubsystem()
<< endl; << endl;
} }
// Precompute the GUI palette
// We abuse the concept of 'enum' by referring directly to the integer values
for(uInt8 i = 0; i < 5; i++)
for(uInt8 j = 0; j < 3; j++)
myGUIPalette[i][j] = (float)(myGUIColors[i][j]) / 255.0;
return true; return true;
} }
@ -167,15 +176,12 @@ bool FrameBufferGL::createScreen()
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] ); SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
uInt32 screenWidth = 0; // Set the screen coordinates
uInt32 screenHeight = 0;
GLdouble orthoWidth = 0.0; GLdouble orthoWidth = 0.0;
GLdouble orthoHeight = 0.0; GLdouble orthoHeight = 0.0;
setDimensions(&orthoWidth, &orthoHeight);
// Get the screen coordinates myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
viewport(&screenWidth, &screenHeight, &orthoWidth, &orthoHeight);
myScreen = SDL_SetVideoMode(screenWidth, screenHeight, 0, mySDLFlags);
if(myScreen == NULL) if(myScreen == NULL)
{ {
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl; cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
@ -184,8 +190,8 @@ bool FrameBufferGL::createScreen()
glPushAttrib(GL_ENABLE_BIT); glPushAttrib(GL_ENABLE_BIT);
// Center the screen horizontally and vertically // Center the image horizontally and vertically
glViewport(myDimensions.x, myDimensions.y, myDimensions.w, myDimensions.h); glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glPushMatrix(); glPushMatrix();
@ -254,58 +260,18 @@ void FrameBufferGL::drawMediaSource()
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels); GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
uInt32 w = myBaseDim.w, h = myBaseDim.h;
glBegin(GL_QUADS); 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[1]); glVertex2i(w, 0);
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(myWidth, myHeight); glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(w, h);
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, myHeight); glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, h);
glEnd(); glEnd();
// The frame doesn't need to be completely redrawn anymore // The frame doesn't need to be completely redrawn anymore
theRedrawEntireFrameIndicator = false; theRedrawEntireFrameIndicator = false;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h)
{
// First draw the box in the background, alpha-blended
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glColor4f(0.0, 0.0, 0.0, 0.7);
glRecti(x, y, x+w, y+h);
// Now draw the outer edges
glLineWidth(theZoomLevel);
glColor4f(0.8, 0.8, 0.8, 1.0);
glBegin(GL_LINE_LOOP);
glVertex2i(x, y ); // Top Left
glVertex2i(x+w, y ); // Top Right
glVertex2i(x+w, y+h); // Bottom Right
glVertex2i(x, y+h); // Bottom Left
glEnd();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::drawText(uInt32 x, uInt32 y, const string& message)
{
for(uInt32 i = 0; i < message.length(); i++)
drawChar(x + i*8, y, (uInt32) message[i]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::drawChar(uInt32 x, uInt32 y, uInt32 c)
{
if(c >= 256 )
return;
glBindTexture(GL_TEXTURE_2D, myFontTextureID[c]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(x, y );
glTexCoord2f(1, 0); glVertex2i(x+8, y );
glTexCoord2f(1, 1); glVertex2i(x+8, y+8);
glTexCoord2f(0, 1); glVertex2i(x, y+8);
glEnd();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::preFrameUpdate() void FrameBufferGL::preFrameUpdate()
{ {
@ -323,12 +289,205 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data)
{ {
// Invert the row, since OpenGL rows start at the bottom // Invert the row, since OpenGL rows start at the bottom
// of the framebuffer // of the framebuffer
row = myDimensions.h + myDimensions.y - row - 1; row = myImageDim.h + myImageDim.y - row - 1;
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(myDimensions.x, row, myDimensions.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data); glReadPixels(myImageDim.x, row, myImageDim.w, 1, GL_RGB, GL_UNSIGNED_BYTE, data);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::toggleFilter()
{
if(myFilterParam == GL_NEAREST)
{
myFilterParam = GL_LINEAR;
myOSystem->settings().setString("gl_filter", "linear");
showMessage("Filtering: GL_LINEAR");
}
else
{
myFilterParam = GL_NEAREST;
myOSystem->settings().setString("gl_filter", "nearest");
showMessage("Filtering: GL_NEAREST");
}
glBindTexture(GL_TEXTURE_2D, myTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam);
for(uInt32 i = 0; i < 256; i++)
{
glBindTexture(GL_TEXTURE_2D, myFontTextureID[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam);
}
// The filtering has changed, so redraw the entire screen
theRedrawEntireFrameIndicator = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::hLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor color)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glLineWidth(1);
glColor4f(myGUIPalette[color][0],
myGUIPalette[color][1],
myGUIPalette[color][2],
1.0);
glBegin(GL_LINES);
glVertex2i(x, y);
glVertex2i(x2, y);
glEnd();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::vLine(uInt32 x, uInt32 y, uInt32 y2, OverlayColor color)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glLineWidth(1);
glColor4f(myGUIPalette[color][0],
myGUIPalette[color][1],
myGUIPalette[color][2],
1.0);
glBegin(GL_LINES);
glVertex2i(x, y );
glVertex2i(x, y2);
glEnd();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color, uInt32 level)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glColor4f(myGUIPalette[color][0],
myGUIPalette[color][1],
myGUIPalette[color][2],
0.7);
glRecti(x, y, x+w, y+h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color)
{
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glColor4f(myGUIPalette[color][0],
myGUIPalette[color][1],
myGUIPalette[color][2],
1.0);
glRecti(x, y, x+w, y+h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color)
{
cerr << "FrameBufferGL::frameRect()\n";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::drawChar(uInt8 chr, uInt32 xorig, uInt32 yorig,
OverlayColor color)
{
/*
// If this character is not included in the font, use the default char.
if(chr < myFont->desc().firstchar ||
chr >= myFont->desc().firstchar + myFont->desc().size)
{
if (chr == ' ')
return;
chr = myFont->desc().defaultchar;
}
const Int32 w = myFont->getCharWidth(chr);
const Int32 h = myFont->getFontHeight();
chr -= myFont->desc().firstchar;
const uInt16* tmp = myFont->desc().bits + (myFont->desc().offset ?
myFont->desc().offset[chr] : (chr * h));
SDL_Rect rect;
for(int y = 0; y < h; y++)
{
const uInt16 buffer = *tmp++;
uInt16 mask = 0x8000;
// if(ty + y < 0 || ty + y >= dst->h)
// continue;
for(int x = 0; x < w; x++, mask >>= 1)
{
// if (tx + x < 0 || tx + x >= dst->w)
// continue;
if ((buffer & mask) != 0)
{
rect.x = (x + xorig) * theZoomLevel;
rect.y = (y + yorig) * theZoomLevel;
rect.w = rect.h = theZoomLevel;
SDL_FillRect(myScreen, &rect, myGUIPalette[color]);
}
}
}
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
OverlayColor color, Int32 h)
{
/*
SDL_Rect rect;
for(int y = 0; y < h; y++)
{
uInt32 mask = 0xF0000000;
// if(ty + y < 0 || ty + y >= _screen.h)
// continue;
for(int x = 0; x < 8; x++, mask >>= 4)
{
// if(tx + x < 0 || tx + x >= _screen.w)
// continue;
if(bitmap[y] & mask)
{
rect.x = (x + xorig) * theZoomLevel;
rect.y = (y + yorig) * theZoomLevel;
rect.w = rect.h = theZoomLevel;
SDL_FillRect(myScreen, &rect, myGUIPalette[color]);
}
}
}
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::translateCoords(Int32* x, Int32* y)
{
// Wow, what a mess :)
*x = (Int32) (((*x - myImageDim.x) / (theZoomLevel * myFSScaleFactor * theAspectRatio)));
*y = (Int32) (((*y - myImageDim.y) / (theZoomLevel * myFSScaleFactor)));
}
/*
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::drawChar(uInt32 x, uInt32 y, uInt32 c)
{
if(c >= 256 )
return;
glBindTexture(GL_TEXTURE_2D, myFontTextureID[c]);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2i(x, y );
glTexCoord2f(1, 0); glVertex2i(x+8, y );
glTexCoord2f(1, 1); glVertex2i(x+8, y+8);
glTexCoord2f(0, 1); glVertex2i(x, y+8);
glEnd();
}
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferGL::createTextures() bool FrameBufferGL::createTextures()
{ {
@ -338,13 +497,13 @@ bool FrameBufferGL::createTextures()
glDeleteTextures(1, &myTextureID); glDeleteTextures(1, &myTextureID);
glDeleteTextures(256, myFontTextureID); glDeleteTextures(256, myFontTextureID);
uInt32 w = power_of_two(myWidth); uInt32 w = power_of_two(myBaseDim.w);
uInt32 h = power_of_two(myHeight); uInt32 h = power_of_two(myBaseDim.h);
myTexCoord[0] = 0.0f; myTexCoord[0] = 0.0f;
myTexCoord[1] = 0.0f; myTexCoord[1] = 0.0f;
myTexCoord[2] = (GLfloat) myWidth / w; myTexCoord[2] = (GLfloat) myBaseDim.w / w;
myTexCoord[3] = (GLfloat) myHeight / h; myTexCoord[3] = (GLfloat) myBaseDim.h / h;
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16, myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16,
0x0000F800, 0x000007E0, 0x0000001F, 0x00000000); 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000);
@ -374,6 +533,7 @@ bool FrameBufferGL::createTextures()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
myTexture->pixels); myTexture->pixels);
/*
// Now create the font textures. There are 256 fonts of 8x8 pixels. // Now create the font textures. There are 256 fonts of 8x8 pixels.
// These will be stored in 256 textures of size 8x8. // These will be stored in 256 textures of size 8x8.
SDL_Surface* fontTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, 32, SDL_Surface* fontTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, 32,
@ -423,6 +583,7 @@ bool FrameBufferGL::createTextures()
} }
SDL_FreeSurface(fontTexture); SDL_FreeSurface(fontTexture);
*/
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
@ -435,150 +596,101 @@ bool FrameBufferGL::createTextures()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::toggleFilter() void FrameBufferGL::setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight)
{ {
if(myFilterParam == GL_NEAREST) // We always know the initial image width and height
{ // We have to determine final image dimensions as well as screen dimensions
myFilterParam = GL_LINEAR; myImageDim.x = 0;
myOSystem->settings().setString("gl_filter", "linear"); myImageDim.y = 0;
showMessage("Filtering: GL_LINEAR"); myImageDim.w = (Uint16) (myBaseDim.w * theZoomLevel * theAspectRatio);
} myImageDim.h = (Uint16) (myBaseDim.h * theZoomLevel);
else myScreenDim = myImageDim;
{
myFilterParam = GL_NEAREST;
myOSystem->settings().setString("gl_filter", "nearest");
showMessage("Filtering: GL_NEAREST");
}
glBindTexture(GL_TEXTURE_2D, myTextureID); myFSScaleFactor = 1.0f;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam);
for(uInt32 i = 0; i < 256; i++)
{
glBindTexture(GL_TEXTURE_2D, myFontTextureID[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, myFilterParam);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, myFilterParam);
}
// The filtering has changed, so redraw the entire screen
theRedrawEntireFrameIndicator = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferGL::viewport(uInt32* screenWidth, uInt32* screenHeight,
GLdouble* orthoWidth, GLdouble* orthoHeight)
{
// Determine if we're in fullscreen or windowed mode // Determine if we're in fullscreen or windowed mode
// In fullscreen mode, we clip the SDL screen to known resolutions // In fullscreen mode, we clip the SDL screen to known resolutions
// In windowed mode, we use the actual image resolution for the SDL screen // In windowed mode, we use the actual image resolution for the SDL screen
if(mySDLFlags & SDL_FULLSCREEN) if(mySDLFlags & SDL_FULLSCREEN)
{ {
Uint16 iwidth = (Uint16) (myWidth * theZoomLevel * theAspectRatio); float scaleX = 0.0f;
Uint16 iheight = (Uint16) (myHeight * theZoomLevel); float scaleY = 0.0f;
Uint16 swidth = 0;
Uint16 sheight = 0;
float scaleX = 0.0f;
float scaleY = 0.0f;
float scale = 1.0f;
/* cerr << "original image width = " << iwidth << endl
<< "original image height = " << iheight << endl
<< endl; */
uInt32 desktopWidth = this->screenWidth();
uInt32 desktopHeight = this->screenHeight();
if(myOSystem->settings().getBool("gl_fsmax") && if(myOSystem->settings().getBool("gl_fsmax") &&
desktopWidth != 0 && desktopHeight != 0) myDesktopDim.w != 0 && myDesktopDim.h != 0)
{ {
// Use the largest available screen size // Use the largest available screen size
swidth = desktopWidth; myScreenDim.w = myDesktopDim.w;
sheight = desktopHeight; myScreenDim.h = myDesktopDim.h;
scaleX = float(iwidth) / swidth; scaleX = float(myImageDim.w) / myScreenDim.w;
scaleY = float(iheight) / sheight; scaleY = float(myImageDim.h) / myScreenDim.h;
// Figure out which dimension is closest to the 10% mark, // Figure out which dimension is closest to the 10% mark,
// and calculate the scaling required to bring it to exactly 10% // and calculate the scaling required to bring it to exactly 10%
if(scaleX > scaleY) if(scaleX > scaleY)
scale = (swidth * 0.9) / iwidth; myFSScaleFactor = float(myScreenDim.w * 0.9) / myImageDim.w;
else else
scale = (sheight * 0.9) / iheight; myFSScaleFactor = float(myScreenDim.h * 0.9) / myImageDim.h;
iwidth = (Uint16) (scale * iwidth); myImageDim.w = (Uint16) (myFSScaleFactor * myImageDim.w);
iheight = (Uint16) (scale * iheight); myImageDim.h = (Uint16) (myFSScaleFactor * myImageDim.h);
} }
else if(myOSystem->settings().getBool("gl_fsmax") && else if(myOSystem->settings().getBool("gl_fsmax") &&
myScreenmode != (SDL_Rect**) -1) myScreenmode != (SDL_Rect**) -1)
{ {
// Use the largest available screen size // Use the largest available screen size
swidth = myScreenmode[0]->w; myScreenDim.w = myScreenmode[0]->w;
sheight = myScreenmode[0]->h; myScreenDim.h = myScreenmode[0]->h;
scaleX = float(iwidth) / swidth; scaleX = float(myImageDim.w) / myScreenDim.w;
scaleY = float(iheight) / sheight; scaleY = float(myImageDim.h) / myScreenDim.h;
// Figure out which dimension is closest to the 10% mark, // Figure out which dimension is closest to the 10% mark,
// and calculate the scaling required to bring it to exactly 10% // and calculate the scaling required to bring it to exactly 10%
if(scaleX > scaleY) if(scaleX > scaleY)
scale = (swidth * 0.9) / iwidth; myFSScaleFactor = (myScreenDim.w * 0.9) / myImageDim.w;
else else
scale = (sheight * 0.9) / iheight; myFSScaleFactor = (myScreenDim.h * 0.9) / myImageDim.h;
iwidth = (Uint16) (scale * iwidth); myImageDim.w = (Uint16) (myFSScaleFactor * myImageDim.w);
iheight = (Uint16) (scale * iheight); myImageDim.h = (Uint16) (myFSScaleFactor * myImageDim.h);
} }
else if(myScreenmode == (SDL_Rect**) -1) else if(myScreenmode == (SDL_Rect**) -1)
{ {
// All modes are available, so use the exact image resolution // All modes are available, so use the exact image resolution
swidth = iwidth; myScreenDim.w = myImageDim.w;
sheight = iheight; myScreenDim.h = myImageDim.h;
} }
else // otherwise, search for a valid screenmode else // otherwise, search for a valid screenmode
{ {
for(uInt32 i = myScreenmodeCount-1; i >= 0; i--) for(uInt32 i = myScreenmodeCount-1; i >= 0; i--)
{ {
if(iwidth <= myScreenmode[i]->w && iheight <= myScreenmode[i]->h) if(myImageDim.w <= myScreenmode[i]->w && myImageDim.h <= myScreenmode[i]->h)
{ {
swidth = myScreenmode[i]->w; myScreenDim.w = myScreenmode[i]->w;
sheight = myScreenmode[i]->h; myScreenDim.h = myScreenmode[i]->h;
break; break;
} }
} }
} }
/* cerr << "image width = " << iwidth << endl
<< "image height = " << iheight << endl
<< "screen width = " << swidth << endl
<< "screen height = " << sheight << endl
<< "scale factor = " << scale << endl
<< endl; */
// Now calculate the OpenGL coordinates // Now calculate the OpenGL coordinates
myDimensions.x = (swidth - iwidth) / 2; myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
myDimensions.y = (sheight - iheight) / 2; myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
myDimensions.w = iwidth;
myDimensions.h = iheight;
*screenWidth = swidth; *orthoWidth = (GLdouble) (myImageDim.w / (theZoomLevel * theAspectRatio * myFSScaleFactor));
*screenHeight = sheight; *orthoHeight = (GLdouble) (myImageDim.h / (theZoomLevel * myFSScaleFactor));
*orthoWidth = (GLdouble) (myDimensions.w / (theZoomLevel * theAspectRatio * scale));
*orthoHeight = (GLdouble) (myDimensions.h / (theZoomLevel * scale));
} }
else else
{ {
myDimensions.x = 0; *orthoWidth = (GLdouble) (myImageDim.w / (theZoomLevel * theAspectRatio));
myDimensions.y = 0; *orthoHeight = (GLdouble) (myImageDim.h / theZoomLevel);
myDimensions.w = (Uint16) (myWidth * theZoomLevel * theAspectRatio);
myDimensions.h = (Uint16) myHeight * theZoomLevel;
*screenWidth = myDimensions.w;
*screenHeight = myDimensions.h;
*orthoWidth = (GLdouble) (myDimensions.w / (theZoomLevel * theAspectRatio));
*orthoHeight = (GLdouble) (myDimensions.h / theZoomLevel);
} }
/*
cerr << "myImageDim.x = " << myImageDim.x << ", myImageDim.y = " << myImageDim.y << endl;
cerr << "myImageDim.w = " << myImageDim.w << ", myImageDim.h = " << myImageDim.h << endl;
cerr << "myScreenDim.w = " << myScreenDim.w << ", myScreenDim.h = " << myScreenDim.h << endl;
cerr << endl;
*/
} }

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBufferGL.hxx,v 1.8 2005-02-22 18:40:53 stephena Exp $ // $Id: FrameBufferGL.hxx,v 1.9 2005-03-28 00:04:53 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_GL_HXX #ifndef FRAMEBUFFER_GL_HXX
@ -33,7 +33,7 @@ class OSystem;
This class implements an SDL OpenGL framebuffer. This class implements an SDL OpenGL framebuffer.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBufferGL.hxx,v 1.8 2005-02-22 18:40:53 stephena Exp $ @version $Id: FrameBufferGL.hxx,v 1.9 2005-03-28 00:04:53 stephena Exp $
*/ */
class FrameBufferGL : public FrameBuffer class FrameBufferGL : public FrameBuffer
{ {
@ -63,16 +63,6 @@ class FrameBufferGL : public FrameBuffer
*/ */
virtual bool createScreen(); virtual bool createScreen();
/**
This routine is called to map a given r,g,b triple to the screen palette.
@param r The red component of the color.
@param g The green component of the color.
@param b The blue component of the color.
*/
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
{ return SDL_MapRGB(myScreen->format, r, g, b); }
/** /**
Switches between the two filtering options in OpenGL. Switches between the two filtering options in OpenGL.
Currently, these are GL_NEAREST and GL_LINEAR. Currently, these are GL_NEAREST and GL_LINEAR.
@ -85,35 +75,6 @@ class FrameBufferGL : public FrameBuffer
*/ */
virtual void drawMediaSource(); virtual void drawMediaSource();
/**
This routine should be called to draw a rectangular box with sides
at the specified coordinates.
@param x The x coordinate
@param y The y coordinate
@param w The width of the box
@param h The height of the box
*/
virtual void drawBoundedBox(uInt32 x, uInt32 y, uInt32 w, uInt32 h);
/**
This routine should be called to draw text at the specified coordinates.
@param x The x coordinate
@param y The y coordinate
@param message The message text
*/
virtual void drawText(uInt32 x, uInt32 y, const string& message);
/**
This routine should be called to draw character 'c' at the specified coordinates.
@param x The x coordinate
@param y The y coordinate
@param c The character to draw
*/
virtual void drawChar(uInt32 x, uInt32 y, uInt32 c);
/** /**
This routine is called before any drawing is done (per-frame). This routine is called before any drawing is done (per-frame).
*/ */
@ -132,11 +93,108 @@ class FrameBufferGL : public FrameBuffer
*/ */
virtual void scanline(uInt32 row, uInt8* data); virtual void scanline(uInt32 row, uInt8* data);
/**
This routine is called to map a given r,g,b triple to the screen palette.
@param r The red component of the color.
@param g The green component of the color.
@param b The blue component of the color.
*/
virtual Uint32 mapRGB(Uint8 r, Uint8 g, Uint8 b)
{ return SDL_MapRGB(myScreen->format, r, g, b); }
/**
This routine is called to draw a horizontal line.
@param x The first x coordinate
@param y The y coordinate
@param x2 The second x coordinate
@param color The color of the line
*/
virtual void hLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor color);
/**
This routine is called to draw a vertical line.
@param x The x coordinate
@param y The first y coordinate
@param y2 The second y coordinate
@param color The color of the line
*/
virtual void vLine(uInt32 x, uInt32 y, uInt32 y2, OverlayColor color);
/**
This routine is called to draw a blended rectangle.
@param x The x coordinate
@param y The y coordinate
@param w The width of the box
@param h The height of the box
@param color FIXME
@param level FIXME
*/
virtual void blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color, uInt32 level = 3);
/**
This routine is called to draw a filled rectangle.
@param x The x coordinate
@param y The y coordinate
@param w The width of the area
@param h The height of the area
@param color The color of the area
*/
virtual void fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color);
/**
This routine is called to draw a framed rectangle.
@param x The x coordinate
@param y The y coordinate
@param w The width of the area
@param h The height of the area
@param color The color of the surrounding frame
*/
virtual void frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color);
/**
This routine is called to draw the specified character.
@param c The character to draw
@param x The x coordinate
@param y The y coordinate
@param color The color of the character
*/
virtual void drawChar(uInt8 c, uInt32 x, uInt32 y, OverlayColor color);
/**
This routine is called to draw the bitmap image.
@param bitmap The data to draw
@param x The x coordinate
@param y The y coordinate
@param color The color of the character
@param h The height of the data image
*/
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, OverlayColor color,
Int32 h = 8);
/**
This routine translates the given coordinates to their
unzoomed/unscaled equivalents.
@param x X coordinate to translate
@param y Y coordinate to translate
*/
inline virtual void translateCoords(Int32* x, Int32* y);
private: private:
bool createTextures(); bool createTextures();
void viewport(uInt32* screenWidth, uInt32* screenHeight, void setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight);
GLdouble* orthoWidth, GLdouble* orthoHeight);
uInt32 power_of_two(uInt32 input) uInt32 power_of_two(uInt32 input)
{ {
@ -171,11 +229,18 @@ class FrameBufferGL : public FrameBuffer
// The OpenGL font texture handles (one for each character) // The OpenGL font texture handles (one for each character)
GLuint myFontTextureID[256]; GLuint myFontTextureID[256];
// GUI palette
GLfloat myGUIPalette[5][3];
// The texture filtering to use // The texture filtering to use
GLint myFilterParam; GLint myFilterParam;
// The name of the texture filtering to use // The name of the texture filtering to use
string myFilterParamName; string myFilterParamName;
// The scaling to use in fullscreen mode
// This is separate from both zoomlevel and aspect ratio
float myFSScaleFactor;
}; };
#endif #endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBufferSoft.cxx,v 1.13 2005-03-26 19:26:47 stephena Exp $ // $Id: FrameBufferSoft.cxx,v 1.14 2005-03-28 00:04:53 stephena Exp $
//============================================================================ //============================================================================
#include <SDL.h> #include <SDL.h>
@ -84,11 +84,14 @@ bool FrameBufferSoft::initSubsystem()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBufferSoft::createScreen() bool FrameBufferSoft::createScreen()
{ {
myDimensions.x = myDimensions.y = 0; myScreenDim.x = myScreenDim.y = 0;
myDimensions.w = myWidth * theZoomLevel; myScreenDim.w = myBaseDim.w * theZoomLevel;
myDimensions.h = myHeight * theZoomLevel; myScreenDim.h = myBaseDim.h * theZoomLevel;
myScreen = SDL_SetVideoMode(myDimensions.w, myDimensions.h, 0, mySDLFlags); // In software mode, the image and screen dimensions are always the same
myImageDim = myScreenDim;
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
if(myScreen == NULL) if(myScreen == NULL)
{ {
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl; cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
@ -99,12 +102,6 @@ bool FrameBufferSoft::createScreen()
return true; return true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::toggleFilter()
{
// No filter added yet ...
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::drawMediaSource() void FrameBufferSoft::drawMediaSource()
{ {
@ -324,6 +321,12 @@ void FrameBufferSoft::scanline(uInt32 row, uInt8* data)
SDL_UnlockSurface(myScreen); SDL_UnlockSurface(myScreen);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::toggleFilter()
{
// No filter added yet ...
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor color) void FrameBufferSoft::hLine(uInt32 x, uInt32 y, uInt32 x2, OverlayColor color)
{ {
@ -351,8 +354,8 @@ void FrameBufferSoft::vLine(uInt32 x, uInt32 y, uInt32 y2, OverlayColor color)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::blendRect(int x, int y, int w, int h, void FrameBufferSoft::blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color, int level) OverlayColor color, uInt32 level)
{ {
// FIXME - make this do alpha-blending // FIXME - make this do alpha-blending
SDL_Rect tmp; SDL_Rect tmp;
@ -362,6 +365,7 @@ void FrameBufferSoft::blendRect(int x, int y, int w, int h,
tmp.y = y * theZoomLevel; tmp.y = y * theZoomLevel;
tmp.w = w * theZoomLevel; tmp.w = w * theZoomLevel;
tmp.h = h * theZoomLevel; tmp.h = h * theZoomLevel;
myRectList->add(&tmp); myRectList->add(&tmp);
SDL_FillRect(myScreen, &tmp, myGUIPalette[color]); SDL_FillRect(myScreen, &tmp, myGUIPalette[color]);
} }
@ -456,6 +460,15 @@ void FrameBufferSoft::drawBitmap(uInt32* bitmap, Int32 xorig, Int32 yorig,
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::translateCoords(Int32* x, Int32* y)
{
// We don't bother checking offsets or aspect ratios, since
// they're not yet supported in software mode.
*x /= theZoomLevel;
*y /= theZoomLevel;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RectList::RectList(Uint32 size) RectList::RectList(Uint32 size)
{ {
@ -486,6 +499,9 @@ void RectList::add(SDL_Rect* newRect)
rectArray = temp; rectArray = temp;
} }
//cerr << "RectList::add(): "
// << "x=" << newRect->x << ", y=" << newRect->y << ", w=" << newRect->w << ", h=" << newRect->h << endl;
rectArray[currentRect].x = newRect->x; rectArray[currentRect].x = newRect->x;
rectArray[currentRect].y = newRect->y; rectArray[currentRect].y = newRect->y;
rectArray[currentRect].w = newRect->w; rectArray[currentRect].w = newRect->w;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBufferSoft.hxx,v 1.10 2005-03-26 19:26:47 stephena Exp $ // $Id: FrameBufferSoft.hxx,v 1.11 2005-03-28 00:04:53 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_SOFT_HXX #ifndef FRAMEBUFFER_SOFT_HXX
@ -34,7 +34,7 @@ class RectList;
This class implements an SDL software framebuffer. This class implements an SDL software framebuffer.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBufferSoft.hxx,v 1.10 2005-03-26 19:26:47 stephena Exp $ @version $Id: FrameBufferSoft.hxx,v 1.11 2005-03-28 00:04:53 stephena Exp $
*/ */
class FrameBufferSoft : public FrameBuffer class FrameBufferSoft : public FrameBuffer
{ {
@ -134,8 +134,8 @@ class FrameBufferSoft : public FrameBuffer
@param color FIXME @param color FIXME
@param level FIXME @param level FIXME
*/ */
virtual void blendRect(int x, int y, int w, int h, virtual void blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color, int level = 3); OverlayColor color, uInt32 level = 3);
/** /**
This routine is called to draw a filled rectangle. This routine is called to draw a filled rectangle.
@ -183,6 +183,15 @@ class FrameBufferSoft : public FrameBuffer
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, OverlayColor color, virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, OverlayColor color,
Int32 h = 8); Int32 h = 8);
/**
This routine translates the given coordinates to their
unzoomed/unscaled equivalents.
@param x X coordinate to translate
@param y Y coordinate to translate
*/
inline virtual void translateCoords(Int32* x, Int32* y);
private: private:
// Used in the dirty update of the SDL surface // Used in the dirty update of the SDL surface
RectList* myRectList; RectList* myRectList;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: EventHandler.cxx,v 1.38 2005-03-14 04:08:14 stephena Exp $ // $Id: EventHandler.cxx,v 1.39 2005-03-28 00:04:53 stephena Exp $
//============================================================================ //============================================================================
#include <algorithm> #include <algorithm>
@ -194,9 +194,9 @@ void EventHandler::handleMouseMotionEvent(SDL_Event& event)
case S_MENU: case S_MENU:
{ {
// Take window zooming into account // Take window zooming into account
Int32 x = event.motion.x / myOSystem->frameBuffer().zoomLevel(); Int32 x = event.motion.x, y = event.motion.y;
Int32 y = event.motion.y / myOSystem->frameBuffer().zoomLevel(); myOSystem->frameBuffer().translateCoords(&x, &y);
//cerr << "Motion: x = " << x << ", y = " << y << endl;
myOSystem->menu().handleMouseMotionEvent(x, y, 0); myOSystem->menu().handleMouseMotionEvent(x, y, 0);
break; break;
} }
@ -232,8 +232,10 @@ void EventHandler::handleMouseButtonEvent(SDL_Event& event, uInt8 state)
case S_MENU: case S_MENU:
{ {
// Take window zooming into account // Take window zooming into account
Int32 x = event.button.x / myOSystem->frameBuffer().zoomLevel(); Int32 x = event.button.x, y = event.button.y;
Int32 y = event.button.y / myOSystem->frameBuffer().zoomLevel(); //if (state) cerr << "B: x = " << x << ", y = " << y << endl;
myOSystem->frameBuffer().translateCoords(&x, &y);
//if (state) cerr << "A: x = " << x << ", y = " << y << endl << endl;
MouseButton button; MouseButton button;
if(state == 1) if(state == 1)

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBuffer.cxx,v 1.22 2005-03-26 19:26:47 stephena Exp $ // $Id: FrameBuffer.cxx,v 1.23 2005-03-28 00:04:54 stephena Exp $
//============================================================================ //============================================================================
#include <sstream> #include <sstream>
@ -34,34 +34,13 @@
#include "stella.xpm" // The Stella icon #include "stella.xpm" // The Stella icon
// Eventually, these may become variables
#define FONTWIDTH 8
#define FONTHEIGHT 8
#define LINEOFFSET 10 // FONTHEIGHT + 1 pixel on top and bottom
#define XBOXOFFSET 8 // 4 pixels to the left and right of text
#define YBOXOFFSET 8 // 4 pixels to the top and bottom of text
#define UPARROW 24 // Indicates more lines above
#define DOWNARROW 25 // Indicates more lines below
#define LEFTARROW 26 // Left arrow for indicating current line
#define RIGHTARROW 27 // Left arrow for indicating current line
#define LEFTMARKER 17 // Indicates item being remapped
#define RIGHTMARKER 16 // Indicates item being remapped
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::FrameBuffer(OSystem* osystem) FrameBuffer::FrameBuffer(OSystem* osystem)
: myOSystem(osystem), : myOSystem(osystem),
myWidth(0),
myHeight(0),
theRedrawEntireFrameIndicator(true), theRedrawEntireFrameIndicator(true),
myWMAvailable(false),
theZoomLevel(1), theZoomLevel(1),
theMaxZoomLevel(1), theMaxZoomLevel(1),
theAspectRatio(1.0), theAspectRatio(1.0),
myFrameRate(0), myFrameRate(0),
myPauseStatus(false), myPauseStatus(false),
theMenuChangedIndicator(false), theMenuChangedIndicator(false),
@ -102,6 +81,9 @@ val(0) // FIXME
sizeof(_font_bits)/sizeof(uInt16) sizeof(_font_bits)/sizeof(uInt16)
}; };
myFont = new StellaFont(this, desc); myFont = new StellaFont(this, desc);
myBaseDim.x = myBaseDim.y = myBaseDim.w = myBaseDim.h = 0;
myImageDim = myScreenDim = myDesktopDim = myBaseDim;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -116,8 +98,8 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
{ {
bool isAlreadyInitialized = (SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO) > 0; bool isAlreadyInitialized = (SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO) > 0;
myWidth = width; myBaseDim.w = (uInt16) width;
myHeight = height; myBaseDim.h = (uInt16) height;
myFrameRate = myOSystem->settings().getInt("framerate"); myFrameRate = myOSystem->settings().getInt("framerate");
// Now (re)initialize the SDL video system // Now (re)initialize the SDL video system
@ -128,11 +110,31 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
if(SDL_Init(initflags) < 0) if(SDL_Init(initflags) < 0)
return; return;
// Calculate the desktop size
myDesktopDim.w = myDesktopDim.h = 0;
// Get the system-specific WM information // Get the system-specific WM information
SDL_SysWMinfo myWMInfo;
SDL_VERSION(&myWMInfo.version); SDL_VERSION(&myWMInfo.version);
if(SDL_GetWMInfo(&myWMInfo) > 0) if(SDL_GetWMInfo(&myWMInfo) > 0)
myWMAvailable = true; {
#if defined(UNIX)
if(myWMInfo.subsystem == SDL_SYSWM_X11)
{
myWMInfo.info.x11.lock_func();
myDesktopDim.w = DisplayWidth(myWMInfo.info.x11.display,
DefaultScreen(myWMInfo.info.x11.display));
myDesktopDim.h = DisplayHeight(myWMInfo.info.x11.display,
DefaultScreen(myWMInfo.info.x11.display));
myWMInfo.info.x11.unlock_func();
}
#elif defined(WIN32)
myDesktopDim.w = (uInt16) GetSystemMetrics(SM_CXSCREEN);
myDesktopDim.h = (uInt16) GetSystemMetrics(SM_CYSCREEN);
#elif defined(MAC_OSX)
// FIXME - add OSX Desktop code here (I don't think SDL supports it yet)
#endif
}
setWindowIcon(); setWindowIcon();
} }
@ -146,52 +148,6 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
// Show or hide the cursor based on the current state // Show or hide the cursor based on the current state
setCursorState(); setCursorState();
/*
// Fill the properties info array with game information
ourPropertiesInfo[0] = myConsole->properties().get("Cartridge.Name");
ourPropertiesInfo[1] = "";
ourPropertiesInfo[2] = "Manufacturer: " + myConsole->properties().get("Cartridge.Manufacturer");
ourPropertiesInfo[3] = "Model: " + myConsole->properties().get("Cartridge.ModelNo");
ourPropertiesInfo[4] = "Rarity: " + myConsole->properties().get("Cartridge.Rarity");
ourPropertiesInfo[5] = "Type: " + myConsole->properties().get("Cartridge.Type");
ourPropertiesInfo[6] = "";
ourPropertiesInfo[7] = "MD5SUM:";
ourPropertiesInfo[8] = myConsole->properties().get("Cartridge.MD5");
// Get the arrays containing key and joystick mappings
myConsole->eventHandler().getKeymapArray(&myKeyTable, &myKeyTableSize);
myConsole->eventHandler().getJoymapArray(&myJoyTable, &myJoyTableSize);
// Determine the maximum number of characters that can be onscreen
myMaxColumns = myWidth / FONTWIDTH - 3;
myMaxRows = myHeight / LINEOFFSET - 2;
// Set up the correct bounds for the remap menu
myRemapMenuMaxLines = myRemapMenuItems > myMaxRows ? myMaxRows : myRemapMenuItems;
myRemapMenuLowIndex = 0;
myRemapMenuHighIndex = myRemapMenuMaxLines;
// Figure out the longest properties string,
// and cut any string that is wider than the display
for(uInt8 i = 0; i < 9; i++)
{
if(ourPropertiesInfo[i].length() > (uInt32) myInfoMenuWidth)
{
myInfoMenuWidth = ourPropertiesInfo[i].length();
if(myInfoMenuWidth > myMaxColumns)
{
myInfoMenuWidth = myMaxColumns;
string s = ourPropertiesInfo[i];
ourPropertiesInfo[i] = s.substr(0, myMaxColumns - 3) + "...";
}
}
}
// Finally, load the remap menu with strings,
// clipping any strings which are wider than the display
loadRemapMenu();
*/
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -221,8 +177,8 @@ void FrameBuffer::update()
{ {
uInt32 w = myFont->getStringWidth(myMessageText) + 10; uInt32 w = myFont->getStringWidth(myMessageText) + 10;
uInt32 h = myFont->getFontHeight() + 8; uInt32 h = myFont->getFontHeight() + 8;
uInt32 x = (myWidth >> 1) - (w >> 1); uInt32 x = (myBaseDim.w >> 1) - (w >> 1);
uInt32 y = myHeight - h - LINEOFFSET/2; uInt32 y = myBaseDim.h - h - 10/2;
// Draw the bounded box and text // Draw the bounded box and text
blendRect(x+1, y+2, w-2, h-4, kBGColor); blendRect(x+1, y+2, w-2, h-4, kBGColor);
@ -241,7 +197,7 @@ void FrameBuffer::update()
case EventHandler::S_MENU: case EventHandler::S_MENU:
{ {
// Only update the screen if it's been invalidated or the menus have changed // Only update the screen if it's been invalidated or the menus have changed
if(theRedrawEntireFrameIndicator) if(theRedrawEntireFrameIndicator || theMenuChangedIndicator)
{ {
drawMediaSource(); drawMediaSource();
@ -287,6 +243,284 @@ void FrameBuffer::showMessage(const string& message)
theRedrawEntireFrameIndicator = true; theRedrawEntireFrameIndicator = true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::pause(bool status)
{
myPauseStatus = status;
// Now notify the child object, in case it wants to do something
// special when pause is received
//FIXME pauseEvent(myPauseStatus);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setupPalette()
{
// Shade the palette to 75% normal value in pause mode
float shade = 1.0;
if(myPauseStatus)
shade = 0.75;
const uInt32* gamePalette = myOSystem->console().mediaSource().palette();
for(uInt32 i = 0; i < 256; ++i)
{
Uint8 r, g, b;
r = (Uint8) (((gamePalette[i] & 0x00ff0000) >> 16) * shade);
g = (Uint8) (((gamePalette[i] & 0x0000ff00) >> 8) * shade);
b = (Uint8) ((gamePalette[i] & 0x000000ff) * shade);
myPalette[i] = mapRGB(r, g, b);
}
theRedrawEntireFrameIndicator = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleFullscreen(bool given, bool toggle)
{
bool isFullscreen;
if(given)
{
if(myOSystem->settings().getBool("fullscreen") == toggle)
return;
isFullscreen = toggle;
}
else
isFullscreen = !myOSystem->settings().getBool("fullscreen");
// Update the settings
myOSystem->settings().setBool("fullscreen", isFullscreen);
if(isFullscreen)
mySDLFlags |= SDL_FULLSCREEN;
else
mySDLFlags &= ~SDL_FULLSCREEN;
if(!createScreen())
return;
setCursorState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::resize(Int8 mode, Int8 zoom)
{
// Use the specific zoom level if one is given
// Otherwise use 'mode' to pick the next zoom level
if(zoom != 0)
{
// if(myOSystem->settings().getBool("fullscreen"))
// return;
if(zoom < 1)
theZoomLevel = 1;
else if((uInt32)zoom > theMaxZoomLevel)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel = zoom;
}
else
{
// reset size to that given in properties
// this is a special case of allowing a resize while in fullscreen mode
if(mode == 0)
{
myScreenDim.w = myBaseDim.w;
myScreenDim.h = myBaseDim.h;
}
else if(mode == 1) // increase size
{
if(myOSystem->settings().getBool("fullscreen"))
return;
if(theZoomLevel == theMaxZoomLevel)
theZoomLevel = 1;
else
theZoomLevel++;
}
else if(mode == -1) // decrease size
{
if(myOSystem->settings().getBool("fullscreen"))
return;
if(theZoomLevel == 1)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel--;
}
}
if(!createScreen())
return;
// Update the settings
myOSystem->settings().setInt("zoom", theZoomLevel);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setCursorState()
{
bool isFullscreen = myOSystem->settings().getBool("fullscreen");
if(isFullscreen)
grabMouse(true);
switch(myOSystem->eventHandler().state())
{
case EventHandler::S_EMULATE:
if(isFullscreen)
showCursor(false);
else
{
// Keep mouse in game window if grabmouse is selected
grabMouse(myOSystem->settings().getBool("grabmouse"));
// Show or hide the cursor depending on the 'hidecursor' argument
showCursor(!myOSystem->settings().getBool("hidecursor"));
}
break;
default:
showCursor(true);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::showCursor(bool show)
{
if(show)
SDL_ShowCursor(SDL_ENABLE);
else
SDL_ShowCursor(SDL_DISABLE);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::grabMouse(bool grab)
{
if(grab)
SDL_WM_GrabInput(SDL_GRAB_ON);
else
SDL_WM_GrabInput(SDL_GRAB_OFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBuffer::fullScreen()
{
return myOSystem->settings().getBool("fullscreen");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::maxWindowSizeForScreen()
{
uInt32 sWidth = myDesktopDim.w;
uInt32 sHeight = myDesktopDim.h;
uInt32 multiplier = sWidth / myBaseDim.w;
// If screenwidth or height could not be found, use default zoom value
if(sWidth == 0 || sHeight == 0)
return 4;
bool found = false;
while(!found && (multiplier > 0))
{
// Figure out the desired size of the window
uInt32 width = myBaseDim.w * multiplier;
uInt32 height = myBaseDim.h * multiplier;
if((width < sWidth) && (height < sHeight))
found = true;
else
multiplier--;
}
if(found)
return multiplier;
else
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setWindowTitle(const string& title)
{
SDL_WM_SetCaption(title.c_str(), "stella");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setWindowIcon()
{
#ifndef MAC_OSX
// Set the window icon
uInt32 w, h, ncols, nbytes;
uInt32 rgba[256], icon[32 * 32];
uInt8 mask[32][4];
sscanf(stella_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes);
if((w != 32) || (h != 32) || (ncols > 255) || (nbytes > 1))
{
cerr << "ERROR: Couldn't load the icon.\n";
return;
}
for(uInt32 i = 0; i < ncols; i++)
{
unsigned char code;
char color[32];
uInt32 col;
sscanf(stella_icon[1 + i], "%c c %s", &code, color);
if(!strcmp(color, "None"))
col = 0x00000000;
else if(!strcmp(color, "black"))
col = 0xFF000000;
else if (color[0] == '#')
{
sscanf(color + 1, "%06x", &col);
col |= 0xFF000000;
}
else
{
cerr << "ERROR: Couldn't load the icon.\n";
return;
}
rgba[code] = col;
}
memset(mask, 0, sizeof(mask));
for(h = 0; h < 32; h++)
{
const char* line = stella_icon[1 + ncols + h];
for(w = 0; w < 32; w++)
{
icon[w + 32 * h] = rgba[(int)line[w]];
if(rgba[(int)line[w]] & 0xFF000000)
mask[h][w >> 3] |= 1 << (7 - (w & 0x07));
}
}
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32,
32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
SDL_WM_SetIcon(surface, (unsigned char *) mask);
SDL_FreeSurface(surface);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor colorA, OverlayColor colorB)
{
hLine(x + 1, y, x + w - 2, colorA);
hLine(x, y + 1, x + w - 1, colorA);
vLine(x, y + 1, y + h - 2, colorA);
vLine(x + 1, y, y + h - 1, colorA);
hLine(x + 1, y + h - 2, x + w - 1, colorB);
hLine(x + 1, y + h - 1, x + w - 2, colorB);
vLine(x + w - 1, y + 1, y + h - 2, colorB);
vLine(x + w - 2, y + 1, y + h - 1, colorB);
}
/* /*
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::showMenu(bool show) void FrameBuffer::showMenu(bool show)
@ -508,16 +742,6 @@ void FrameBuffer::sendJoyEvent(StellaEvent::JoyStick stick,
} }
*/ */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::pause(bool status)
{
myPauseStatus = status;
// Now notify the child object, in case it wants to do something
// special when pause is received
//FIXME pauseEvent(myPauseStatus);
}
/* /*
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameBuffer::Widget FrameBuffer::currentSelectedWidget() FrameBuffer::Widget FrameBuffer::currentSelectedWidget()
@ -854,320 +1078,3 @@ const char* FrameBuffer::ourEventName[StellaEvent::LastKCODE] = {
"F11", "F12", "F13", "F14", "F15", "F11", "F12", "F13", "F14", "F15",
}; };
#endif #endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setupPalette()
{
// Shade the palette to 75% normal value in pause mode
float shade = 1.0;
if(myPauseStatus)
shade = 0.75;
const uInt32* gamePalette = myOSystem->console().mediaSource().palette();
for(uInt32 i = 0; i < 256; ++i)
{
Uint8 r, g, b;
r = (Uint8) (((gamePalette[i] & 0x00ff0000) >> 16) * shade);
g = (Uint8) (((gamePalette[i] & 0x0000ff00) >> 8) * shade);
b = (Uint8) ((gamePalette[i] & 0x000000ff) * shade);
myPalette[i] = mapRGB(r, g, b);
}
theRedrawEntireFrameIndicator = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::toggleFullscreen(bool given, bool toggle)
{
bool isFullscreen;
if(given)
{
if(myOSystem->settings().getBool("fullscreen") == toggle)
return;
isFullscreen = toggle;
}
else
isFullscreen = !myOSystem->settings().getBool("fullscreen");
// Update the settings
myOSystem->settings().setBool("fullscreen", isFullscreen);
if(isFullscreen)
mySDLFlags |= SDL_FULLSCREEN;
else
mySDLFlags &= ~SDL_FULLSCREEN;
if(!createScreen())
return;
setCursorState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::resize(Int8 mode, Int8 zoom)
{
// Use the specific zoom level if one is given
// Otherwise use 'mode' to pick the next zoom level
if(zoom != 0)
{
// if(myOSystem->settings().getBool("fullscreen"))
// return;
if(zoom < 1)
theZoomLevel = 1;
else if((uInt32)zoom > theMaxZoomLevel)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel = zoom;
}
else
{
// reset size to that given in properties
// this is a special case of allowing a resize while in fullscreen mode
if(mode == 0)
{
myWidth = 1;//FIXME myMediaSource->width() << 1;
myHeight = 1;//FIXME myMediaSource->height();
}
else if(mode == 1) // increase size
{
if(myOSystem->settings().getBool("fullscreen"))
return;
if(theZoomLevel == theMaxZoomLevel)
theZoomLevel = 1;
else
theZoomLevel++;
}
else if(mode == -1) // decrease size
{
if(myOSystem->settings().getBool("fullscreen"))
return;
if(theZoomLevel == 1)
theZoomLevel = theMaxZoomLevel;
else
theZoomLevel--;
}
}
if(!createScreen())
return;
// Update the settings
myOSystem->settings().setInt("zoom", theZoomLevel);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setCursorState()
{
bool isFullscreen = myOSystem->settings().getBool("fullscreen");
if(isFullscreen)
grabMouse(true);
switch(myOSystem->eventHandler().state())
{
case EventHandler::S_EMULATE:
if(isFullscreen)
showCursor(false);
else
{
// Keep mouse in game window if grabmouse is selected
grabMouse(myOSystem->settings().getBool("grabmouse"));
// Show or hide the cursor depending on the 'hidecursor' argument
showCursor(!myOSystem->settings().getBool("hidecursor"));
}
break;
default:
showCursor(true);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::showCursor(bool show)
{
if(show)
SDL_ShowCursor(SDL_ENABLE);
else
SDL_ShowCursor(SDL_DISABLE);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::grabMouse(bool grab)
{
if(grab)
SDL_WM_GrabInput(SDL_GRAB_ON);
else
SDL_WM_GrabInput(SDL_GRAB_OFF);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool FrameBuffer::fullScreen()
{
return myOSystem->settings().getBool("fullscreen");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::maxWindowSizeForScreen()
{
uInt32 sWidth = screenWidth();
uInt32 sHeight = screenHeight();
uInt32 multiplier = sWidth / myWidth;
// If screenwidth or height could not be found, use default zoom value
if(sWidth == 0 || sHeight == 0)
return 4;
bool found = false;
while(!found && (multiplier > 0))
{
// Figure out the desired size of the window
uInt32 width = (uInt32) (myWidth * multiplier * theAspectRatio);
uInt32 height = myHeight * multiplier;
if((width < sWidth) && (height < sHeight))
found = true;
else
multiplier--;
}
if(found)
return multiplier;
else
return 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::screenWidth()
{
uInt32 width = 0;
if(myWMAvailable)
{
#if defined(UNIX)
if(myWMInfo.subsystem == SDL_SYSWM_X11)
{
myWMInfo.info.x11.lock_func();
width = DisplayWidth(myWMInfo.info.x11.display,
DefaultScreen(myWMInfo.info.x11.display));
myWMInfo.info.x11.unlock_func();
}
#elif defined(WIN32)
width = (uInt32) GetSystemMetrics(SM_CXSCREEN);
#elif defined(MAC_OSX)
// FIXME - add OSX Desktop code here (I don't think SDL supports it yet)
#endif
}
return width;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 FrameBuffer::screenHeight()
{
uInt32 height = 0;
if(myWMAvailable)
{
#if defined(UNIX)
if(myWMInfo.subsystem == SDL_SYSWM_X11)
{
myWMInfo.info.x11.lock_func();
height = DisplayHeight(myWMInfo.info.x11.display,
DefaultScreen(myWMInfo.info.x11.display));
myWMInfo.info.x11.unlock_func();
}
#elif defined(WIN32)
height = (uInt32) GetSystemMetrics(SM_CYSCREEN);
#elif defined(MAC_OSX)
// FIXME - add OSX Desktop code here (I don't think SDL supports it yet)
#endif
}
return height;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setWindowTitle(const string& title)
{
SDL_WM_SetCaption(title.c_str(), "stella");
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setWindowIcon()
{
#ifndef MAC_OSX
// Set the window icon
uInt32 w, h, ncols, nbytes;
uInt32 rgba[256], icon[32 * 32];
uInt8 mask[32][4];
sscanf(stella_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes);
if((w != 32) || (h != 32) || (ncols > 255) || (nbytes > 1))
{
cerr << "ERROR: Couldn't load the icon.\n";
return;
}
for(uInt32 i = 0; i < ncols; i++)
{
unsigned char code;
char color[32];
uInt32 col;
sscanf(stella_icon[1 + i], "%c c %s", &code, color);
if(!strcmp(color, "None"))
col = 0x00000000;
else if(!strcmp(color, "black"))
col = 0xFF000000;
else if (color[0] == '#')
{
sscanf(color + 1, "%06x", &col);
col |= 0xFF000000;
}
else
{
cerr << "ERROR: Couldn't load the icon.\n";
return;
}
rgba[code] = col;
}
memset(mask, 0, sizeof(mask));
for(h = 0; h < 32; h++)
{
const char* line = stella_icon[1 + ncols + h];
for(w = 0; w < 32; w++)
{
icon[w + 32 * h] = rgba[(int)line[w]];
if(rgba[(int)line[w]] & 0xFF000000)
mask[h][w >> 3] |= 1 << (7 - (w & 0x07));
}
}
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32,
32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
SDL_WM_SetIcon(surface, (unsigned char *) mask);
SDL_FreeSurface(surface);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor colorA, OverlayColor colorB)
{
hLine(x + 1, y, x + w - 2, colorA);
hLine(x, y + 1, x + w - 1, colorA);
vLine(x, y + 1, y + h - 2, colorA);
vLine(x + 1, y, y + h - 1, colorA);
hLine(x + 1, y + h - 2, x + w - 1, colorB);
hLine(x + 1, y + h - 1, x + w - 2, colorB);
vLine(x + w - 1, y + 1, y + h - 2, colorB);
vLine(x + w - 2, y + 1, y + h - 1, colorB);
}

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: FrameBuffer.hxx,v 1.22 2005-03-26 19:26:47 stephena Exp $ // $Id: FrameBuffer.hxx,v 1.23 2005-03-28 00:04:54 stephena Exp $
//============================================================================ //============================================================================
#ifndef FRAMEBUFFER_HXX #ifndef FRAMEBUFFER_HXX
@ -41,7 +41,7 @@ class OSystem;
All GUI elements (ala ScummVM) are drawn here as well. All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony @author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.22 2005-03-26 19:26:47 stephena Exp $ @version $Id: FrameBuffer.hxx,v 1.23 2005-03-28 00:04:54 stephena Exp $
*/ */
class FrameBuffer class FrameBuffer
{ {
@ -87,43 +87,34 @@ class FrameBuffer
void showMessage(const string& message); void showMessage(const string& message);
/** /**
Returns the current width of the framebuffer. Returns the current width of the framebuffer *before* any scaling.
@return The current unscaled width
*/
inline const uInt32 baseWidth() { return myBaseDim.w; }
/**
Returns the current height of the framebuffer *before* any scaling.
@return The current unscaled height
*/
inline const uInt32 baseHeight() { return myBaseDim.h; }
/**
Returns the current width of the framebuffer image.
Note that this will take into account the current scaling (if any). Note that this will take into account the current scaling (if any).
@return The current width @return The current width
*/ */
uInt32 width() { return myWidth; } // inline const uInt32 imageWidth() { return myImageDim.w; }
/** /**
Returns the current height of the framebuffer. Returns the current height of the framebuffer image.
Note that this will take into account the current scaling (if any). Note that this will take into account the current scaling (if any).
@return The current height @return The current height
*/ */
uInt32 height() { return myHeight; } // inline const uInt32 imageHeight() { return myImageDim.h; }
#if 0
FIXME
/**
This routine is called to get the width of the onscreen image.
*/
uInt32 imageWidth() { return myDimensions.w; }
/**
This routine is called to get the height of the onscreen image.
*/
uInt32 imageHeight() { return myDimensions.h; }
#endif
/**
This routine is called to get the width of the system desktop.
*/
uInt32 screenWidth();
/**
This routine is called to get the height of the system desktop.
*/
uInt32 screenHeight();
/** /**
Sets the pause status. While pause is selected, the Sets the pause status. While pause is selected, the
@ -191,9 +182,14 @@ FIXME
bool fullScreen(); bool fullScreen();
/** /**
Answers the current zoom level of the SDL window. Answers the current zoom level of the framebuffer image in the X axis.
*/ */
inline uInt32 zoomLevel() { return theZoomLevel; } inline const float zoomLevelX() { return theZoomLevel * theAspectRatio; }
/**
Answers the current zoom level of the framebuffer image in the X axis.
*/
inline const float zoomLevelY() { return (float) theZoomLevel; }
/** /**
Calculate the maximum window size that the current screen can hold. Calculate the maximum window size that the current screen can hold.
@ -315,8 +311,8 @@ FIXME
@param color FIXME @param color FIXME
@param level FIXME @param level FIXME
*/ */
virtual void blendRect(int x, int y, int w, int h, virtual void blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
OverlayColor color, int level = 3) = 0; OverlayColor color, uInt32 level = 3) = 0;
/** /**
This routine should be called to draw a filled rectangle. This routine should be called to draw a filled rectangle.
@ -364,6 +360,15 @@ FIXME
virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, OverlayColor color, virtual void drawBitmap(uInt32* bitmap, Int32 x, Int32 y, OverlayColor color,
Int32 h = 8) = 0; Int32 h = 8) = 0;
/**
This routine should be called to translate the given coordinates
to their unzoomed/unscaled equivalents.
@param x X coordinate to translate
@param y Y coordinate to translate
*/
virtual void translateCoords(Int32* x, Int32* y) = 0;
#if 0 #if 0
FIXME FIXME
/** /**
@ -380,8 +385,20 @@ FIXME
// The parent system for the framebuffer // The parent system for the framebuffer
OSystem* myOSystem; OSystem* myOSystem;
// Bounds for the window frame // Dimensions of the base image, before zooming.
uInt32 myWidth, myHeight; // All external GUI items should refer to these dimensions,
// since this is the *real* size of the image.
// The other sizes are simply scaled versions of these dimensions.
SDL_Rect myBaseDim;
// Dimensions of the actual image, after zooming
SDL_Rect myImageDim;
// Dimensions of the SDL window (not always the same as the image)
SDL_Rect myScreenDim;
// Dimensions of the desktop area
SDL_Rect myDesktopDim;
// Indicates if the entire frame should be redrawn // Indicates if the entire frame should be redrawn
bool theRedrawEntireFrameIndicator; bool theRedrawEntireFrameIndicator;
@ -398,16 +415,6 @@ FIXME
// Holds the palette for GUI elements // Holds the palette for GUI elements
uInt8 myGUIColors[5][3]; uInt8 myGUIColors[5][3];
// Used to get window-manager specifics
SDL_SysWMinfo myWMInfo;
// Indicates the width/height and origin x/y of the onscreen image
// (these may be different than the screen/window dimensions)
SDL_Rect myDimensions;
// Indicates if the system-specific WM information is available
bool myWMAvailable;
// Indicates the current zoom level of the SDL screen // Indicates the current zoom level of the SDL screen
uInt32 theZoomLevel; uInt32 theZoomLevel;
@ -426,6 +433,30 @@ FIXME
*/ */
void setWindowIcon(); void setWindowIcon();
private:
// Indicates the current framerate of the system
uInt32 myFrameRate;
// Indicates the current pause status
bool myPauseStatus;
// Indicates if the menus should be redrawn
bool theMenuChangedIndicator;
// Message timer
Int32 myMessageTime;
// Message text
string myMessageText;
// Number of times menu have been drawn
uInt32 myMenuRedraws;
int val; // FIXME - remove
};
#endif
/* /*
// Enumeration representing the different types of user interface widgets // Enumeration representing the different types of user interface widgets
enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU }; enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU };
@ -461,26 +492,7 @@ FIXME
// scan the mapping arrays and update the remap menu // scan the mapping arrays and update the remap menu
void loadRemapMenu(); void loadRemapMenu();
*/ */
private:
// Indicates the current framerate of the system
uInt32 myFrameRate;
// Indicates the current pause status
bool myPauseStatus;
// Indicates if the menus should be redrawn
bool theMenuChangedIndicator;
// Message timer
Int32 myMessageTime;
// Message text
string myMessageText;
// Number of times menu have been drawn
uInt32 myMenuRedraws;
int val;
/* /*
// Structure used for main menu items // Structure used for main menu items
struct MainMenuItem struct MainMenuItem
@ -549,6 +561,3 @@ int val;
// Holds the number of items in the joytable array // Holds the number of items in the joytable array
uInt32 myJoyTableSize; uInt32 myJoyTableSize;
*/ */
};
#endif

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: OptionsDialog.cxx,v 1.7 2005-03-27 03:07:34 stephena Exp $ // $Id: OptionsDialog.cxx,v 1.8 2005-03-28 00:04:54 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -53,8 +53,11 @@ enum {
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OptionsDialog::OptionsDialog(OSystem* osystem) OptionsDialog::OptionsDialog(OSystem* osystem)
: Dialog(osystem, (osystem->frameBuffer().width() - kMainMenuWidth) / 2, // FIXME - we have to initialize the video system at least once *before*
(osystem->frameBuffer().height() - kMainMenuHeight)/2, // creating a new console. For now, just use predefined values.
// Eventually, this subsystem will have to take into account screen size changes
: Dialog(osystem, (osystem->frameBuffer().baseWidth() - kMainMenuWidth) / 2,
(osystem->frameBuffer().baseHeight() - kMainMenuHeight)/2,
kMainMenuWidth, kMainMenuHeight), kMainMenuWidth, kMainMenuHeight),
myVideoDialog(NULL) myVideoDialog(NULL)
{ {
@ -69,8 +72,8 @@ OptionsDialog::OptionsDialog(OSystem* osystem)
addBigButton("Help", kHelpCmd, 'H'); addBigButton("Help", kHelpCmd, 'H');
// Set some sane values for the dialog boxes // Set some sane values for the dialog boxes
uInt32 fbWidth = osystem->frameBuffer().width(); uInt16 fbWidth = osystem->frameBuffer().baseWidth();
uInt32 fbHeight = osystem->frameBuffer().height(); uInt16 fbHeight = osystem->frameBuffer().baseHeight();
uInt16 x, y, w, h; uInt16 x, y, w, h;
// Now create all the dialogs attached to each menu button // Now create all the dialogs attached to each menu button
@ -107,7 +110,7 @@ OptionsDialog::~OptionsDialog()
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OptionsDialog::checkBounds(uInt32 width, uInt32 height, void OptionsDialog::checkBounds(uInt16 width, uInt16 height,
uInt16* x, uInt16* y, uInt16* w, uInt16* h) uInt16* x, uInt16* y, uInt16* w, uInt16* h)
{ {
if(*w > width) *w = width; if(*w > width) *w = width;

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: OptionsDialog.hxx,v 1.3 2005-03-27 03:07:34 stephena Exp $ // $Id: OptionsDialog.hxx,v 1.4 2005-03-28 00:04:54 stephena Exp $
// //
// Based on code from ScummVM - Scumm Interpreter // Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project // Copyright (C) 2002-2004 The ScummVM project
@ -54,7 +54,7 @@ class OptionsDialog : public Dialog
HelpDialog* myHelpDialog; HelpDialog* myHelpDialog;
private: private:
void checkBounds(uInt32 width, uInt32 height, void checkBounds(uInt16 width, uInt16 height,
uInt16* x, uInt16* y, uInt16* w, uInt16* h); uInt16* x, uInt16* y, uInt16* w, uInt16* h);
}; };