Re-add support for displaying text in FrameBufferSoft. I've only

tested 32-bit mode for now; more testing to come.

Made changes in OSystem so creating a framebuffer is only ever done
once.  This means that switching between software and OpenGL mode is
no longer dynamic (ie, it can no longer be done while Stella is running).
With the forthcoming changes to VideoDialog, you'll be able to set the
mode to change the next time Stella runs.  It just adds too much
complexity to support dynamic switching, especially when I don't think
many people do it too often.

Updated CommandDialog to be font-resizable (ie, take advantage of the
new UI fonts).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1574 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-12-26 20:05:17 +00:00
parent 92b22e3ad7
commit 5147356c96
8 changed files with 146 additions and 187 deletions

View File

@ -57,6 +57,8 @@ X (4) Reload current listing (possibly tied to a RMB context menu).
* Research lockups in Stay Frosty ROM. Test out sample state file in
AtariAge email.
* Fix issue with paddle support in Activision Bridge ROM.
* More support for copy and paste.
* Fix PropSet to properly delete entries when 'Default' is pressed in

View File

@ -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.83 2008-12-25 23:05:16 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.84 2008-12-26 20:05:16 stephena Exp $
//============================================================================
#include <sstream>
@ -557,7 +557,7 @@ void FBSurfaceSoft::fillRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h, int color)
void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
uInt32 tx, uInt32 ty, int color)
{
#if 0
// TODO - test this in 16-bit, and re-write 24-bit
const FontDesc& desc = font->desc();
// If this character is not included in the font, use the default char.
@ -566,11 +566,26 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
if (chr == ' ') return;
chr = desc.defaultchar;
}
const Int32 w = font->getCharWidth(chr);
const Int32 h = font->getFontHeight();
chr -= desc.firstchar;
const uInt32* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * h));
// Get the bounding box of the character
int bbw, bbh, bbx, bby;
if(!desc.bbx)
{
bbw = desc.fbbw;
bbh = desc.fbbh;
bbx = desc.fbbx;
bby = desc.fbby;
}
else
{
bbw = desc.bbx[chr].w;
bbh = desc.bbx[chr].h;
bbx = desc.bbx[chr].x;
bby = desc.bbx[chr].y;
}
const uInt16* tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
SDL_LockSurface(mySurface);
@ -579,18 +594,20 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
case 2:
{
// Get buffer position where upper-left pixel of the character will be drawn
uInt16* buffer = (uInt16*) mySurface->pixels + myBaseOffset + ty * myPitch + tx;
for(int y = 0; y < h; ++y)
uInt16* buffer = (uInt16*) mySurface->pixels +
(ty + desc.ascent - bby - bbh) * myPitch +
tx + bbx;
for(int y = 0; y < bbh; y++)
{
const uInt32 ptr = *tmp++;
if(ptr)
{
uInt32 mask = 0x80000000;
for(int x = 0; x < w; ++x, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt16) myFB.myDefPalette[color];
}
buffer += myFB.myPitch;
const uInt16 ptr = *tmp++;
uInt16 mask = 0x8000;
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt16) myFB.myDefPalette[color];
buffer += myPitch;
}
break;
}
@ -637,17 +654,19 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
case 4:
{
// Get buffer position where upper-left pixel of the character will be drawn
uInt32* buffer = (uInt32*) mySurface->pixels + myBaseOffset + ty * myPitch + tx;
for(int y = 0; y < h; ++y)
uInt32* buffer = (uInt32*) mySurface->pixels +
(ty + desc.ascent - bby - bbh) * myPitch +
tx + bbx;
for(int y = 0; y < bbh; y++)
{
const uInt32 ptr = *tmp++;
if(ptr)
{
uInt32 mask = 0x80000000;
for(int x = 0; x < w; ++x, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt32) myFB.myDefPalette[color];
}
uInt32 mask = 0x8000;
for(int x = 0; x < bbw; x++, mask >>= 1)
if(ptr & mask)
buffer[x] = (uInt32) myFB.myDefPalette[color];
buffer += myPitch;
}
break;
@ -656,7 +675,6 @@ void FBSurfaceSoft::drawChar(const GUI::Font* font, uInt8 chr,
break;
}
SDL_UnlockSurface(mySurface);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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: OSystem.cxx,v 1.133 2008-12-14 21:44:06 stephena Exp $
// $Id: OSystem.cxx,v 1.134 2008-12-26 20:05:17 stephena Exp $
//============================================================================
#include <cassert>
@ -294,25 +294,19 @@ void OSystem::setFramerate(float framerate)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool OSystem::createFrameBuffer(bool showmessage)
bool OSystem::createFrameBuffer()
{
// Check if we can re-use the current framebuffer
bool changeBuffer = (myFrameBuffer == NULL);
if(!changeBuffer)
{
if((mySettings->getString("video") == "soft" &&
myFrameBuffer->type() != kSoftBuffer) ||
(mySettings->getString("video") == "gl" &&
myFrameBuffer->type() != kGLBuffer))
changeBuffer = true;
}
// There is only ever one FrameBuffer created per run of Stella
// Due to the multi-surface nature of the FrameBuffer, repeatedly
// creating and destroying framebuffer objects causes crashes which
// are far too invasive to fix right now
// Besides, how often does one really switch between software and
// OpenGL rendering modes, and even when they do, does it really
// need to be dynamic?
// Now we only create when absolutely necessary
if(changeBuffer)
{
delete myFrameBuffer;
bool firstTime = (myFrameBuffer == NULL);
if(firstTime)
myFrameBuffer = MediaFactory::createVideo(this);
}
// Re-initialize the framebuffer to current settings
switch(myEventHandler->state())
@ -341,55 +335,23 @@ bool OSystem::createFrameBuffer(bool showmessage)
break;
}
// Setup the SDL joysticks (must be done after FrameBuffer is created)
if(changeBuffer) myEventHandler->setupJoysticks();
// Let the system know that we've possibly resized the display
if(changeBuffer) myEventHandler->handleResizeEvent();
// Update the UI palette
setUIPalette();
if(showmessage)
// The following only need to be done once
if(firstTime)
{
switch(myFrameBuffer->type())
{
case kSoftBuffer:
myFrameBuffer->showMessage("Software mode");
break;
case kGLBuffer:
myFrameBuffer->showMessage("OpenGL mode");
break;
}
// Setup the SDL joysticks (must be done after FrameBuffer is created)
myEventHandler->setupJoysticks();
// FIXME - this next line can probably be removed
// Let the system know that we've possibly resized the display
myEventHandler->handleResizeEvent();
// Update the UI palette
setUIPalette();
}
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::toggleFrameBuffer()
{
#ifdef DISPLAY_OPENGL
// First figure out which mode to switch to
string video = mySettings->getString("video");
if(video == "soft")
video = "gl";
else if(video == "gl")
video = "soft";
else // a driver that doesn't exist was requested, so use software mode
video = "soft";
// Update the settings and create the framebuffer
mySettings->setString("video", video);
createFrameBuffer(true); // show onscreen message, re-initialize framebuffer
// The palette and phosphor info for the framebuffer will be lost
// when a new framebuffer is created; we must restore it
if(myConsole)
myConsole->initializeVideo(false);
#endif
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void OSystem::createSound()
{
@ -438,7 +400,7 @@ bool OSystem::createConsole(const string& romfile, const string& md5sum)
myCheatManager->loadCheats(md5);
#endif
myEventHandler->reset(EventHandler::S_EMULATE);
if(!createFrameBuffer(false)) // Takes care of initializeVideo()
if(!createFrameBuffer()) // Takes care of initializeVideo()
{
cerr << "ERROR: Couldn't create framebuffer for console" << endl;
return false;
@ -508,7 +470,7 @@ void OSystem::deleteConsole()
bool OSystem::createLauncher()
{
myEventHandler->reset(EventHandler::S_LAUNCHER);
if(!createFrameBuffer(false))
if(!createFrameBuffer())
{
cerr << "ERROR: Couldn't create launcher" << endl;
return false;

View File

@ -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: OSystem.hxx,v 1.67 2008-05-30 19:07:55 stephena Exp $
// $Id: OSystem.hxx,v 1.68 2008-12-26 20:05:17 stephena Exp $
//============================================================================
#ifndef OSYSTEM_HXX
@ -56,7 +56,7 @@ typedef Common::Array<Resolution> ResolutionList;
other objects belong.
@author Stephen Anthony
@version $Id: OSystem.hxx,v 1.67 2008-05-30 19:07:55 stephena Exp $
@version $Id: OSystem.hxx,v 1.68 2008-12-26 20:05:17 stephena Exp $
*/
class OSystem
{
@ -294,11 +294,6 @@ class OSystem
*/
const string& romFile() const { return myRomFile; }
/**
Switches between software and OpenGL framebuffer modes.
*/
void toggleFrameBuffer();
/**
Creates a new game console from the specified romfile.
@ -542,11 +537,12 @@ class OSystem
private:
/**
Creates the various framebuffers/renderers available in this system
(for now, that means either 'software' or 'opengl').
(for now, that means either 'software' or 'opengl'). Note that
it will only create one type per run of Stella.
@return Success or failure of the framebuffer creation
*/
bool createFrameBuffer(bool showmessage = false);
bool createFrameBuffer();
/**
Creates the various sound devices available in this system

View File

@ -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: CommandDialog.cxx,v 1.20 2008-06-13 13:14:51 stephena Exp $
// $Id: CommandDialog.cxx,v 1.21 2008-12-26 20:05:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -28,93 +28,79 @@
#include "Widget.hxx"
#include "CommandDialog.hxx"
#define addCDButton(label, cmd) \
new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight, label, cmd); xoffset += buttonWidth + 6
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CommandDialog::CommandDialog(OSystem* osystem, DialogContainer* parent)
: Dialog(osystem, parent, 0, 0, 16, 16),
mySelectedItem(0)
{
const GUI::Font& font = osystem->font();
int buttonWidth = 65,
buttonHeight = 18,
xoffset = 5,
yoffset = 5,
lwidth = buttonWidth + 5;
const GUI::Font& font = instance().font();
const int buttonWidth = font.getStringWidth("Right Diff B") + 20,
buttonHeight = font.getLineHeight() + 6,
rowHeight = font.getLineHeight() + 10;
// Set real dimensions
_w = 4 * (lwidth) + 5;
_h = 4 * (buttonHeight+3) + 7;
_w = 4 * (buttonWidth + 5) + 20;
_h = 4 * rowHeight + 15;
int xoffset = 10, yoffset = 10;
WidgetArray wid;
ButtonWidget* b;
ButtonWidget* b = NULL;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Select", kSelectCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Reset", kResetCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Color TV", kColorCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"B/W TV", kBWCmd);
b = addCDButton("Select", kSelectCmd);
wid.push_back(b);
xoffset = 5; yoffset += buttonHeight + 3;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Left Diff A", kLeftDiffACmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Left Diff B", kLeftDiffBCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Right Diff A", kRightDiffACmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Right Diff B", kRightDiffBCmd);
b = addCDButton("Reset", kResetCmd);
wid.push_back(b);
xoffset = 5; yoffset += buttonHeight + 3;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Save State", kSaveStateCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"State Slot", kStateSlotCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Load State", kLoadStateCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Snapshot", kSnapshotCmd);
b = addCDButton("Color TV", kColorCmd);
wid.push_back(b);
xoffset = 5; yoffset += buttonHeight + 3;
b = addCDButton("B/W TV", kBWCmd);
wid.push_back(b);
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"NTSC/PAL", kFormatCmd);
xoffset = 10; yoffset += buttonHeight + 3;
b = addCDButton("Left Diff A", kLeftDiffACmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Palette", kPaletteCmd);
b = addCDButton("Left Diff B", kLeftDiffBCmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Reload ROM", kReloadRomCmd);
b = addCDButton("Right Diff A", kRightDiffACmd);
wid.push_back(b);
xoffset += lwidth;
b = new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight,
"Exit Game", kExitCmd);
b = addCDButton("Right Diff B", kRightDiffBCmd);
wid.push_back(b);
xoffset = 10; yoffset += buttonHeight + 3;
b = addCDButton("Save State", kSaveStateCmd);
wid.push_back(b);
b = addCDButton("State Slot", kStateSlotCmd);
wid.push_back(b);
b = addCDButton("Load State", kLoadStateCmd);
wid.push_back(b);
b = addCDButton("Snapshot", kSnapshotCmd);
wid.push_back(b);
xoffset = 10; yoffset += buttonHeight + 3;
b = addCDButton("NTSC/PAL", kFormatCmd);
wid.push_back(b);
b = addCDButton("Palette", kPaletteCmd);
wid.push_back(b);
b = addCDButton("Reload ROM", kReloadRomCmd);
wid.push_back(b);
b = addCDButton("Exit Game", kExitCmd);
wid.push_back(b);
addToFocusList(wid);

View File

@ -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: Dialog.cxx,v 1.69 2008-12-25 23:05:16 stephena Exp $
// $Id: Dialog.cxx,v 1.70 2008-12-26 20:05:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -87,7 +87,6 @@ void Dialog::open()
}
center();
loadConfig();
// (Re)-build the focus list to use for the widgets which are currently

View File

@ -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.72 2008-12-25 23:05:16 stephena Exp $
// $Id: OptionsDialog.cxx,v 1.73 2008-12-26 20:05:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -42,7 +42,7 @@
#include "bspf.hxx"
#define addBigButton(label, cmd) \
#define addODButton(label, cmd) \
new ButtonWidget(this, font, xoffset, yoffset, buttonWidth, buttonHeight, label, cmd); yoffset += rowHeight
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -72,46 +72,46 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent,
WidgetArray wid;
ButtonWidget* b = NULL;
myVideoSettingsButton = addBigButton("Video Settings", kVidCmd);
myVideoSettingsButton = addODButton("Video Settings", kVidCmd);
wid.push_back(myVideoSettingsButton);
myAudioSettingsButton = addBigButton("Audio Settings", kAudCmd);
myAudioSettingsButton = addODButton("Audio Settings", kAudCmd);
#ifndef SOUND_SUPPORT
myAudioSettingsButton->clearFlags(WIDGET_ENABLED);
#endif
wid.push_back(myAudioSettingsButton);
b = addBigButton("Input Settings", kInptCmd);
b = addODButton("Input Settings", kInptCmd);
wid.push_back(b);
myUIButton = addBigButton("UI Settings", kUsrIfaceCmd);
myUIButton = addODButton("UI Settings", kUsrIfaceCmd);
wid.push_back(myUIButton);
myFileSnapButton = addBigButton("Config Files", kFileSnapCmd);
myFileSnapButton = addODButton("Config Files", kFileSnapCmd);
wid.push_back(myFileSnapButton);
myRomAuditButton = addBigButton("Audit ROMs", kAuditCmd);
myRomAuditButton = addODButton("Audit ROMs", kAuditCmd);
wid.push_back(myRomAuditButton);
// Move to second column
xoffset += buttonWidth + 10; yoffset = 10;
myGameInfoButton = addBigButton("Game Properties", kInfoCmd);
myGameInfoButton = addODButton("Game Properties", kInfoCmd);
wid.push_back(myGameInfoButton);
myCheatCodeButton = addBigButton("Cheat Code", kCheatCmd);
myCheatCodeButton = addODButton("Cheat Code", kCheatCmd);
#ifndef CHEATCODE_SUPPORT
myCheatCodeButton->clearFlags(WIDGET_ENABLED);
#endif
wid.push_back(myCheatCodeButton);
myHelpButton = addBigButton("Help", kHelpCmd);
myHelpButton = addODButton("Help", kHelpCmd);
wid.push_back(myHelpButton);
myAboutButton = addBigButton("About", kAboutCmd);
myAboutButton = addODButton("About", kAboutCmd);
wid.push_back(myAboutButton);
b = addBigButton("Exit Menu", kExitCmd);
b = addODButton("Exit Menu", kExitCmd);
wid.push_back(b);
addCancelWidget(b);

View File

@ -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: VideoDialog.cxx,v 1.55 2008-12-25 23:05:16 stephena Exp $
// $Id: VideoDialog.cxx,v 1.56 2008-12-26 20:05:17 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -51,10 +51,6 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
WidgetArray wid;
StringMap items;
// Set real dimensions
// _w = 46 * fontWidth + 10;
// _h = 11 * (lineHeight + 4) + 10;
xpos = 5; ypos = 10;
// Video renderer
@ -305,7 +301,7 @@ void VideoDialog::saveConfig()
instance().settings().setBool("center", myCenterCheckbox->getState());
// Finally, issue a complete framebuffer re-initialization
instance().createFrameBuffer(false);
instance().createFrameBuffer();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -