mirror of https://github.com/stella-emu/stella.git
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:
parent
b5fb1d277d
commit
8d67d0c760
|
@ -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: 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 $
|
||||
##============================================================================
|
||||
|
||||
##============================================================================
|
||||
|
|
|
@ -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.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>
|
||||
|
@ -26,6 +26,8 @@
|
|||
#include "MediaSrc.hxx"
|
||||
#include "Settings.hxx"
|
||||
#include "OSystem.hxx"
|
||||
#include "StellaFont.hxx"
|
||||
#include "GuiUtils.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
FrameBufferGL::FrameBufferGL(OSystem* osystem)
|
||||
|
@ -34,7 +36,8 @@ FrameBufferGL::FrameBufferGL(OSystem* osystem)
|
|||
myScreenmode(0),
|
||||
myScreenmodeCount(0),
|
||||
myFilterParam(GL_NEAREST),
|
||||
myFilterParamName("GL_NEAREST")
|
||||
myFilterParamName("GL_NEAREST"),
|
||||
myFSScaleFactor(1.0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -155,6 +158,12 @@ bool FrameBufferGL::initSubsystem()
|
|||
<< 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;
|
||||
}
|
||||
|
||||
|
@ -167,15 +176,12 @@ bool FrameBufferGL::createScreen()
|
|||
SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, myRGB[3] );
|
||||
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
|
||||
|
||||
uInt32 screenWidth = 0;
|
||||
uInt32 screenHeight = 0;
|
||||
// Set the screen coordinates
|
||||
GLdouble orthoWidth = 0.0;
|
||||
GLdouble orthoHeight = 0.0;
|
||||
setDimensions(&orthoWidth, &orthoHeight);
|
||||
|
||||
// Get the screen coordinates
|
||||
viewport(&screenWidth, &screenHeight, &orthoWidth, &orthoHeight);
|
||||
|
||||
myScreen = SDL_SetVideoMode(screenWidth, screenHeight, 0, mySDLFlags);
|
||||
myScreen = SDL_SetVideoMode(myScreenDim.w, myScreenDim.h, 0, mySDLFlags);
|
||||
if(myScreen == NULL)
|
||||
{
|
||||
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
|
||||
|
@ -184,8 +190,8 @@ bool FrameBufferGL::createScreen()
|
|||
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
|
||||
// Center the screen horizontally and vertically
|
||||
glViewport(myDimensions.x, myDimensions.y, myDimensions.w, myDimensions.h);
|
||||
// Center the image horizontally and vertically
|
||||
glViewport(myImageDim.x, myImageDim.y, myImageDim.w, myImageDim.h);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
@ -254,58 +260,18 @@ void FrameBufferGL::drawMediaSource()
|
|||
GL_RGB, GL_UNSIGNED_SHORT_5_6_5, myTexture->pixels);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
|
||||
|
||||
uInt32 w = myBaseDim.w, h = myBaseDim.h;
|
||||
glBegin(GL_QUADS);
|
||||
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[1]); glVertex2i(0, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[1]); glVertex2i(w, 0);
|
||||
glTexCoord2f(myTexCoord[2], myTexCoord[3]); glVertex2i(w, h);
|
||||
glTexCoord2f(myTexCoord[0], myTexCoord[3]); glVertex2i(0, h);
|
||||
glEnd();
|
||||
|
||||
// The frame doesn't need to be completely redrawn anymore
|
||||
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()
|
||||
{
|
||||
|
@ -323,12 +289,205 @@ void FrameBufferGL::scanline(uInt32 row, uInt8* data)
|
|||
{
|
||||
// Invert the row, since OpenGL rows start at the bottom
|
||||
// of the framebuffer
|
||||
row = myDimensions.h + myDimensions.y - row - 1;
|
||||
row = myImageDim.h + myImageDim.y - row - 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()
|
||||
{
|
||||
|
@ -338,13 +497,13 @@ bool FrameBufferGL::createTextures()
|
|||
glDeleteTextures(1, &myTextureID);
|
||||
glDeleteTextures(256, myFontTextureID);
|
||||
|
||||
uInt32 w = power_of_two(myWidth);
|
||||
uInt32 h = power_of_two(myHeight);
|
||||
uInt32 w = power_of_two(myBaseDim.w);
|
||||
uInt32 h = power_of_two(myBaseDim.h);
|
||||
|
||||
myTexCoord[0] = 0.0f;
|
||||
myTexCoord[1] = 0.0f;
|
||||
myTexCoord[2] = (GLfloat) myWidth / w;
|
||||
myTexCoord[3] = (GLfloat) myHeight / h;
|
||||
myTexCoord[2] = (GLfloat) myBaseDim.w / w;
|
||||
myTexCoord[3] = (GLfloat) myBaseDim.h / h;
|
||||
|
||||
myTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16,
|
||||
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,
|
||||
myTexture->pixels);
|
||||
|
||||
/*
|
||||
// Now create the font textures. There are 256 fonts of 8x8 pixels.
|
||||
// These will be stored in 256 textures of size 8x8.
|
||||
SDL_Surface* fontTexture = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, 32,
|
||||
|
@ -423,6 +583,7 @@ bool FrameBufferGL::createTextures()
|
|||
}
|
||||
|
||||
SDL_FreeSurface(fontTexture);
|
||||
*/
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
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)
|
||||
{
|
||||
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");
|
||||
}
|
||||
// We always know the initial image width and height
|
||||
// We have to determine final image dimensions as well as screen dimensions
|
||||
myImageDim.x = 0;
|
||||
myImageDim.y = 0;
|
||||
myImageDim.w = (Uint16) (myBaseDim.w * theZoomLevel * theAspectRatio);
|
||||
myImageDim.h = (Uint16) (myBaseDim.h * theZoomLevel);
|
||||
myScreenDim = myImageDim;
|
||||
|
||||
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);
|
||||
myFSScaleFactor = 1.0f;
|
||||
|
||||
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
|
||||
// In fullscreen mode, we clip the SDL screen to known resolutions
|
||||
// In windowed mode, we use the actual image resolution for the SDL screen
|
||||
if(mySDLFlags & SDL_FULLSCREEN)
|
||||
{
|
||||
Uint16 iwidth = (Uint16) (myWidth * theZoomLevel * theAspectRatio);
|
||||
Uint16 iheight = (Uint16) (myHeight * theZoomLevel);
|
||||
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();
|
||||
float scaleX = 0.0f;
|
||||
float scaleY = 0.0f;
|
||||
|
||||
if(myOSystem->settings().getBool("gl_fsmax") &&
|
||||
desktopWidth != 0 && desktopHeight != 0)
|
||||
myDesktopDim.w != 0 && myDesktopDim.h != 0)
|
||||
{
|
||||
// Use the largest available screen size
|
||||
swidth = desktopWidth;
|
||||
sheight = desktopHeight;
|
||||
myScreenDim.w = myDesktopDim.w;
|
||||
myScreenDim.h = myDesktopDim.h;
|
||||
|
||||
scaleX = float(iwidth) / swidth;
|
||||
scaleY = float(iheight) / sheight;
|
||||
scaleX = float(myImageDim.w) / myScreenDim.w;
|
||||
scaleY = float(myImageDim.h) / myScreenDim.h;
|
||||
|
||||
// Figure out which dimension is closest to the 10% mark,
|
||||
// and calculate the scaling required to bring it to exactly 10%
|
||||
if(scaleX > scaleY)
|
||||
scale = (swidth * 0.9) / iwidth;
|
||||
myFSScaleFactor = float(myScreenDim.w * 0.9) / myImageDim.w;
|
||||
else
|
||||
scale = (sheight * 0.9) / iheight;
|
||||
myFSScaleFactor = float(myScreenDim.h * 0.9) / myImageDim.h;
|
||||
|
||||
iwidth = (Uint16) (scale * iwidth);
|
||||
iheight = (Uint16) (scale * iheight);
|
||||
myImageDim.w = (Uint16) (myFSScaleFactor * myImageDim.w);
|
||||
myImageDim.h = (Uint16) (myFSScaleFactor * myImageDim.h);
|
||||
}
|
||||
else if(myOSystem->settings().getBool("gl_fsmax") &&
|
||||
myScreenmode != (SDL_Rect**) -1)
|
||||
{
|
||||
// Use the largest available screen size
|
||||
swidth = myScreenmode[0]->w;
|
||||
sheight = myScreenmode[0]->h;
|
||||
myScreenDim.w = myScreenmode[0]->w;
|
||||
myScreenDim.h = myScreenmode[0]->h;
|
||||
|
||||
scaleX = float(iwidth) / swidth;
|
||||
scaleY = float(iheight) / sheight;
|
||||
scaleX = float(myImageDim.w) / myScreenDim.w;
|
||||
scaleY = float(myImageDim.h) / myScreenDim.h;
|
||||
|
||||
// Figure out which dimension is closest to the 10% mark,
|
||||
// and calculate the scaling required to bring it to exactly 10%
|
||||
if(scaleX > scaleY)
|
||||
scale = (swidth * 0.9) / iwidth;
|
||||
myFSScaleFactor = (myScreenDim.w * 0.9) / myImageDim.w;
|
||||
else
|
||||
scale = (sheight * 0.9) / iheight;
|
||||
myFSScaleFactor = (myScreenDim.h * 0.9) / myImageDim.h;
|
||||
|
||||
iwidth = (Uint16) (scale * iwidth);
|
||||
iheight = (Uint16) (scale * iheight);
|
||||
myImageDim.w = (Uint16) (myFSScaleFactor * myImageDim.w);
|
||||
myImageDim.h = (Uint16) (myFSScaleFactor * myImageDim.h);
|
||||
}
|
||||
else if(myScreenmode == (SDL_Rect**) -1)
|
||||
{
|
||||
// All modes are available, so use the exact image resolution
|
||||
swidth = iwidth;
|
||||
sheight = iheight;
|
||||
myScreenDim.w = myImageDim.w;
|
||||
myScreenDim.h = myImageDim.h;
|
||||
}
|
||||
else // otherwise, search for a valid screenmode
|
||||
{
|
||||
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;
|
||||
sheight = myScreenmode[i]->h;
|
||||
myScreenDim.w = myScreenmode[i]->w;
|
||||
myScreenDim.h = myScreenmode[i]->h;
|
||||
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
|
||||
myDimensions.x = (swidth - iwidth) / 2;
|
||||
myDimensions.y = (sheight - iheight) / 2;
|
||||
myDimensions.w = iwidth;
|
||||
myDimensions.h = iheight;
|
||||
myImageDim.x = (myScreenDim.w - myImageDim.w) / 2;
|
||||
myImageDim.y = (myScreenDim.h - myImageDim.h) / 2;
|
||||
|
||||
*screenWidth = swidth;
|
||||
*screenHeight = sheight;
|
||||
*orthoWidth = (GLdouble) (myDimensions.w / (theZoomLevel * theAspectRatio * scale));
|
||||
*orthoHeight = (GLdouble) (myDimensions.h / (theZoomLevel * scale));
|
||||
*orthoWidth = (GLdouble) (myImageDim.w / (theZoomLevel * theAspectRatio * myFSScaleFactor));
|
||||
*orthoHeight = (GLdouble) (myImageDim.h / (theZoomLevel * myFSScaleFactor));
|
||||
}
|
||||
else
|
||||
{
|
||||
myDimensions.x = 0;
|
||||
myDimensions.y = 0;
|
||||
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);
|
||||
*orthoWidth = (GLdouble) (myImageDim.w / (theZoomLevel * theAspectRatio));
|
||||
*orthoHeight = (GLdouble) (myImageDim.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;
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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.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
|
||||
|
@ -33,7 +33,7 @@ class OSystem;
|
|||
This class implements an SDL OpenGL framebuffer.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -63,16 +63,6 @@ class FrameBufferGL : public FrameBuffer
|
|||
*/
|
||||
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.
|
||||
Currently, these are GL_NEAREST and GL_LINEAR.
|
||||
|
@ -85,35 +75,6 @@ class FrameBufferGL : public FrameBuffer
|
|||
*/
|
||||
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).
|
||||
*/
|
||||
|
@ -132,11 +93,108 @@ class FrameBufferGL : public FrameBuffer
|
|||
*/
|
||||
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:
|
||||
bool createTextures();
|
||||
|
||||
void viewport(uInt32* screenWidth, uInt32* screenHeight,
|
||||
GLdouble* orthoWidth, GLdouble* orthoHeight);
|
||||
void setDimensions(GLdouble* orthoWidth, GLdouble* orthoHeight);
|
||||
|
||||
uInt32 power_of_two(uInt32 input)
|
||||
{
|
||||
|
@ -171,11 +229,18 @@ class FrameBufferGL : public FrameBuffer
|
|||
// The OpenGL font texture handles (one for each character)
|
||||
GLuint myFontTextureID[256];
|
||||
|
||||
// GUI palette
|
||||
GLfloat myGUIPalette[5][3];
|
||||
|
||||
// The texture filtering to use
|
||||
GLint myFilterParam;
|
||||
|
||||
// The name of the texture filtering to use
|
||||
string myFilterParamName;
|
||||
|
||||
// The scaling to use in fullscreen mode
|
||||
// This is separate from both zoomlevel and aspect ratio
|
||||
float myFSScaleFactor;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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.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>
|
||||
|
@ -84,11 +84,14 @@ bool FrameBufferSoft::initSubsystem()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool FrameBufferSoft::createScreen()
|
||||
{
|
||||
myDimensions.x = myDimensions.y = 0;
|
||||
myDimensions.w = myWidth * theZoomLevel;
|
||||
myDimensions.h = myHeight * theZoomLevel;
|
||||
myScreenDim.x = myScreenDim.y = 0;
|
||||
myScreenDim.w = myBaseDim.w * 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)
|
||||
{
|
||||
cerr << "ERROR: Unable to open SDL window: " << SDL_GetError() << endl;
|
||||
|
@ -99,12 +102,6 @@ bool FrameBufferSoft::createScreen()
|
|||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::toggleFilter()
|
||||
{
|
||||
// No filter added yet ...
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::drawMediaSource()
|
||||
{
|
||||
|
@ -324,6 +321,12 @@ void FrameBufferSoft::scanline(uInt32 row, uInt8* data)
|
|||
SDL_UnlockSurface(myScreen);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBufferSoft::toggleFilter()
|
||||
{
|
||||
// No filter added yet ...
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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,
|
||||
OverlayColor color, int level)
|
||||
void FrameBufferSoft::blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
OverlayColor color, uInt32 level)
|
||||
{
|
||||
// FIXME - make this do alpha-blending
|
||||
SDL_Rect tmp;
|
||||
|
@ -362,6 +365,7 @@ void FrameBufferSoft::blendRect(int x, int y, int w, int h,
|
|||
tmp.y = y * theZoomLevel;
|
||||
tmp.w = w * theZoomLevel;
|
||||
tmp.h = h * theZoomLevel;
|
||||
|
||||
myRectList->add(&tmp);
|
||||
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)
|
||||
{
|
||||
|
@ -486,6 +499,9 @@ void RectList::add(SDL_Rect* newRect)
|
|||
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].y = newRect->y;
|
||||
rectArray[currentRect].w = newRect->w;
|
||||
|
|
|
@ -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.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
|
||||
|
@ -34,7 +34,7 @@ class RectList;
|
|||
This class implements an SDL software framebuffer.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -134,8 +134,8 @@ class FrameBufferSoft : public FrameBuffer
|
|||
@param color FIXME
|
||||
@param level FIXME
|
||||
*/
|
||||
virtual void blendRect(int x, int y, int w, int h,
|
||||
OverlayColor color, int level = 3);
|
||||
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.
|
||||
|
@ -183,6 +183,15 @@ class FrameBufferSoft : public FrameBuffer
|
|||
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:
|
||||
// Used in the dirty update of the SDL surface
|
||||
RectList* myRectList;
|
||||
|
|
|
@ -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: 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>
|
||||
|
@ -194,9 +194,9 @@ void EventHandler::handleMouseMotionEvent(SDL_Event& event)
|
|||
case S_MENU:
|
||||
{
|
||||
// Take window zooming into account
|
||||
Int32 x = event.motion.x / myOSystem->frameBuffer().zoomLevel();
|
||||
Int32 y = event.motion.y / myOSystem->frameBuffer().zoomLevel();
|
||||
|
||||
Int32 x = event.motion.x, y = event.motion.y;
|
||||
myOSystem->frameBuffer().translateCoords(&x, &y);
|
||||
//cerr << "Motion: x = " << x << ", y = " << y << endl;
|
||||
myOSystem->menu().handleMouseMotionEvent(x, y, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -232,8 +232,10 @@ void EventHandler::handleMouseButtonEvent(SDL_Event& event, uInt8 state)
|
|||
case S_MENU:
|
||||
{
|
||||
// Take window zooming into account
|
||||
Int32 x = event.button.x / myOSystem->frameBuffer().zoomLevel();
|
||||
Int32 y = event.button.y / myOSystem->frameBuffer().zoomLevel();
|
||||
Int32 x = event.button.x, y = event.button.y;
|
||||
//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;
|
||||
|
||||
if(state == 1)
|
||||
|
|
|
@ -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.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>
|
||||
|
@ -34,34 +34,13 @@
|
|||
|
||||
#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)
|
||||
: myOSystem(osystem),
|
||||
myWidth(0),
|
||||
myHeight(0),
|
||||
theRedrawEntireFrameIndicator(true),
|
||||
|
||||
myWMAvailable(false),
|
||||
theZoomLevel(1),
|
||||
theMaxZoomLevel(1),
|
||||
theAspectRatio(1.0),
|
||||
|
||||
myFrameRate(0),
|
||||
myPauseStatus(false),
|
||||
theMenuChangedIndicator(false),
|
||||
|
@ -102,6 +81,9 @@ val(0) // FIXME
|
|||
sizeof(_font_bits)/sizeof(uInt16)
|
||||
};
|
||||
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;
|
||||
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
myBaseDim.w = (uInt16) width;
|
||||
myBaseDim.h = (uInt16) height;
|
||||
myFrameRate = myOSystem->settings().getInt("framerate");
|
||||
|
||||
// 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)
|
||||
return;
|
||||
|
||||
// Calculate the desktop size
|
||||
myDesktopDim.w = myDesktopDim.h = 0;
|
||||
|
||||
// Get the system-specific WM information
|
||||
SDL_SysWMinfo myWMInfo;
|
||||
SDL_VERSION(&myWMInfo.version);
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -146,52 +148,6 @@ void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height)
|
|||
|
||||
// Show or hide the cursor based on the current state
|
||||
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 h = myFont->getFontHeight() + 8;
|
||||
uInt32 x = (myWidth >> 1) - (w >> 1);
|
||||
uInt32 y = myHeight - h - LINEOFFSET/2;
|
||||
uInt32 x = (myBaseDim.w >> 1) - (w >> 1);
|
||||
uInt32 y = myBaseDim.h - h - 10/2;
|
||||
|
||||
// Draw the bounded box and text
|
||||
blendRect(x+1, y+2, w-2, h-4, kBGColor);
|
||||
|
@ -241,7 +197,7 @@ void FrameBuffer::update()
|
|||
case EventHandler::S_MENU:
|
||||
{
|
||||
// Only update the screen if it's been invalidated or the menus have changed
|
||||
if(theRedrawEntireFrameIndicator)
|
||||
if(theRedrawEntireFrameIndicator || theMenuChangedIndicator)
|
||||
{
|
||||
drawMediaSource();
|
||||
|
||||
|
@ -287,6 +243,284 @@ void FrameBuffer::showMessage(const string& message)
|
|||
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)
|
||||
|
@ -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()
|
||||
|
@ -854,320 +1078,3 @@ const char* FrameBuffer::ourEventName[StellaEvent::LastKCODE] = {
|
|||
"F11", "F12", "F13", "F14", "F15",
|
||||
};
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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.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
|
||||
|
@ -41,7 +41,7 @@ class OSystem;
|
|||
All GUI elements (ala ScummVM) are drawn here as well.
|
||||
|
||||
@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
|
||||
{
|
||||
|
@ -87,43 +87,34 @@ class FrameBuffer
|
|||
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).
|
||||
|
||||
@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).
|
||||
|
||||
@return The current height
|
||||
*/
|
||||
uInt32 height() { return myHeight; }
|
||||
|
||||
#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();
|
||||
// inline const uInt32 imageHeight() { return myImageDim.h; }
|
||||
|
||||
/**
|
||||
Sets the pause status. While pause is selected, the
|
||||
|
@ -191,9 +182,14 @@ FIXME
|
|||
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.
|
||||
|
@ -315,8 +311,8 @@ FIXME
|
|||
@param color FIXME
|
||||
@param level FIXME
|
||||
*/
|
||||
virtual void blendRect(int x, int y, int w, int h,
|
||||
OverlayColor color, int level = 3) = 0;
|
||||
virtual void blendRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
||||
OverlayColor color, uInt32 level = 3) = 0;
|
||||
|
||||
/**
|
||||
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,
|
||||
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
|
||||
FIXME
|
||||
/**
|
||||
|
@ -380,8 +385,20 @@ FIXME
|
|||
// The parent system for the framebuffer
|
||||
OSystem* myOSystem;
|
||||
|
||||
// Bounds for the window frame
|
||||
uInt32 myWidth, myHeight;
|
||||
// Dimensions of the base image, before zooming.
|
||||
// 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
|
||||
bool theRedrawEntireFrameIndicator;
|
||||
|
@ -398,16 +415,6 @@ FIXME
|
|||
// Holds the palette for GUI elements
|
||||
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
|
||||
uInt32 theZoomLevel;
|
||||
|
||||
|
@ -426,6 +433,30 @@ FIXME
|
|||
*/
|
||||
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
|
||||
enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU };
|
||||
|
@ -461,26 +492,7 @@ FIXME
|
|||
// scan the mapping arrays and update the remap menu
|
||||
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
|
||||
struct MainMenuItem
|
||||
|
@ -549,6 +561,3 @@ int val;
|
|||
// Holds the number of items in the joytable array
|
||||
uInt32 myJoyTableSize;
|
||||
*/
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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: 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
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -53,8 +53,11 @@ enum {
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
OptionsDialog::OptionsDialog(OSystem* osystem)
|
||||
: Dialog(osystem, (osystem->frameBuffer().width() - kMainMenuWidth) / 2,
|
||||
(osystem->frameBuffer().height() - kMainMenuHeight)/2,
|
||||
// FIXME - we have to initialize the video system at least once *before*
|
||||
// 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),
|
||||
myVideoDialog(NULL)
|
||||
{
|
||||
|
@ -69,8 +72,8 @@ OptionsDialog::OptionsDialog(OSystem* osystem)
|
|||
addBigButton("Help", kHelpCmd, 'H');
|
||||
|
||||
// Set some sane values for the dialog boxes
|
||||
uInt32 fbWidth = osystem->frameBuffer().width();
|
||||
uInt32 fbHeight = osystem->frameBuffer().height();
|
||||
uInt16 fbWidth = osystem->frameBuffer().baseWidth();
|
||||
uInt16 fbHeight = osystem->frameBuffer().baseHeight();
|
||||
uInt16 x, y, w, h;
|
||||
|
||||
// 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)
|
||||
{
|
||||
if(*w > width) *w = width;
|
||||
|
|
|
@ -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: 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
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -54,7 +54,7 @@ class OptionsDialog : public Dialog
|
|||
HelpDialog* myHelpDialog;
|
||||
|
||||
private:
|
||||
void checkBounds(uInt32 width, uInt32 height,
|
||||
void checkBounds(uInt16 width, uInt16 height,
|
||||
uInt16* x, uInt16* y, uInt16* w, uInt16* h);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue