Added basic message code to the TIA. Can be called with

MediaSource.showMessage(string& message uInt32 duration), where duration is the
number of frames to display the message.

All messages are converted to upper case, since the fonts are very limited.
Fonts exist for A..Z and 0..9 only.  Some fonts are not the clearest, but its
the best I can do with only 4-pixel widths :)  Besides, they have an 'Atari'
look.

Updated the SDL and X11 versions to print messages under the following
conditions:

1) switching color modes (BW or color)
2) setting left and right difficulty for controllers
3) state loading/saving/changing (see below for this one)

Added methods that form the beginning of state loading and saving.  This
functionality is NOT currently present, and won't be for the 1.2 release.  The
methods added are for state saving, state slot changing, and state loading, and
are tied to function keys F9, F10, F11, respectively.  For now, they don't
actually do anything :)


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@71 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2002-04-18 17:18:48 +00:00
parent 916abf9394
commit 227b2178a7
5 changed files with 452 additions and 117 deletions

View File

@ -13,12 +13,14 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: MediaSrc.hxx,v 1.2 2002-03-17 19:37:00 stephena Exp $
// $Id: MediaSrc.hxx,v 1.3 2002-04-18 17:18:48 stephena Exp $
//============================================================================
#ifndef MEDIASOURCE_HXX
#define MEDIASOURCE_HXX
#include <string>
class MediaSource;
#include "bspf.hxx"
@ -27,7 +29,7 @@ class MediaSource;
This class provides an interface for accessing graphics data.
@author Bradford W. Mott
@version $Id: MediaSrc.hxx,v 1.2 2002-03-17 19:37:00 stephena Exp $
@version $Id: MediaSrc.hxx,v 1.3 2002-04-18 17:18:48 stephena Exp $
*/
class MediaSource
{
@ -58,6 +60,12 @@ class MediaSource
*/
virtual bool pause(bool state) = 0;
/**
Inserts the given message into the framebuffer for the given
number of frames.
*/
virtual void showMessage(string& message, Int32 duration) = 0;
/**
Answers the current frame buffer

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: TIA.cxx,v 1.11 2002-04-13 05:14:51 bwmott Exp $
// $Id: TIA.cxx,v 1.12 2002-04-18 17:18:48 stephena Exp $
//============================================================================
#include <assert.h>
@ -34,6 +34,8 @@ TIA::TIA(const Console& console, Sound& sound)
: myConsole(console),
mySound(sound),
myPauseState(false),
myMessageTime(0),
myMessageText(""),
myLastSoundUpdateCycle(0),
myColorLossEnabled(false),
myCOLUBK(myColor[0]),
@ -337,6 +339,13 @@ void TIA::update()
// Compute the number of scanlines in the frame
uInt32 totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
myScanlineCountForLastFrame = totalClocks / 228;
// Draw any pending messages to the framebuffer
if(myMessageTime > 0)
{
drawMessageText();
--myMessageTime;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -358,6 +367,75 @@ bool TIA::pause(bool state)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::drawMessageText()
{
// Set up the correct coordinates to print the message
uInt32 xOffSet = 10 + myFrameXStart;
uInt32 yOffSet = myFrameHeight - 30;
// Used to indicate the current x/y position of a pixel
uInt32 xPos, yPos;
// The actual font data for a letter
uInt32 data;
// The index into the palette to color the current text
uInt8 fontColor = 68;
// Clip the length if its wider than the screen
uInt8 length = myMessageText.length();
if(((length * 5) + xOffSet) >= myFrameWidth)
length = (myFrameWidth - xOffSet) / 5;
for(uInt8 x = 0; x < length; ++x)
{
char letter = myMessageText[x];
if((letter >= 'A') && (letter <= 'Z'))
data = ourFontData[(int)letter - 65];
else if((letter >= '0') && (letter <= '9'))
data = ourFontData[(int)letter - 48 + 26];
else // unknown character or space
{
xOffSet += 3;
continue;
}
// start scanning the font data from the bottom up
yPos = 7;
for(uInt8 y = 0; y < 32; ++y)
{
// determine the correct scanline
xPos = y % 4;
if(xPos == 0)
--yPos;
if((data >> y) & 1)
{
uInt32 position = (yPos + yOffSet) * myFrameWidth + (4 - xPos) + xOffSet;
myCurrentFrameBuffer[position] = fontColor;
}
}
// move left to the next character
xOffSet += 5;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::showMessage(string& message, Int32 duration)
{
myMessageText = message;
myMessageTime = duration;
// Make message uppercase, since there are no lowercase fonts defined
uInt32 length = myMessageText.length();
for(uInt32 i = 0; i < length; ++i)
myMessageText[i] = toupper(myMessageText[i]);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt32* TIA::palette() const
{
@ -2828,6 +2906,46 @@ const uInt32 TIA::ourPALPalette[256] = {
0xd2d2d2, 0xd2d2d2, 0xececec, 0xececec
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const uInt32 TIA::ourFontData[36] = {
0x699f999, // A
0xe99e99e, // B
0x6988896, // C
0xe99999e, // D
0xf88e88f, // E
0xf88e888, // F
0x698b996, // G
0x999f999, // H
0x7222227, // I
0x72222a4, // J
0x9accaa9, // K
0x888888f, // L
0x9ff9999, // M
0x9ddbb99, // N
0x6999996, // O
0xe99e888, // P
0x69999b7, // Q
0xe99ea99, // R
0x6986196, // S
0x7222222, // T
0x9999996, // U
0x9999966, // V
0x9999ff9, // W
0x99fff99, // X
0x9996244, // Y
0xf12488f, // Z
0x69bd996, // 0
0x2622227, // 1
0x691248f, // 2
0x6916196, // 3
0xaaaf222, // 4
0xf88e11e, // 5
0x698e996, // 6
0xf112244, // 7
0x6996996, // 8
0x6997196 // 9
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TIA::TIA(const TIA& c)
: myConsole(c.myConsole),

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: TIA.hxx,v 1.4 2002-03-28 05:10:17 bwmott Exp $
// $Id: TIA.hxx,v 1.5 2002-04-18 17:18:48 stephena Exp $
//============================================================================
#ifndef TIA_HXX
@ -22,6 +22,8 @@
class Console;
class System;
#include <string>
#include "bspf.hxx"
#include "Device.hxx"
#include "MediaSrc.hxx"
@ -38,7 +40,7 @@ class System;
be displayed on screen.
@author Bradford W. Mott
@version $Id: TIA.hxx,v 1.4 2002-03-28 05:10:17 bwmott Exp $
@version $Id: TIA.hxx,v 1.5 2002-04-18 17:18:48 stephena Exp $
*/
class TIA : public Device , public MediaSource
{
@ -115,6 +117,12 @@ class TIA : public Device , public MediaSource
*/
virtual bool pause(bool state);
/**
Inserts the given message into the framebuffer for the given
number of frames.
*/
virtual void showMessage(string& message, Int32 duration);
/**
Answers the current frame buffer
@ -190,6 +198,9 @@ class TIA : public Device , public MediaSource
// Waste cycles until the current scanline is finished
void waitHorizontalSync();
// Draw message to framebuffer
void drawMessageText();
private:
// Console the TIA is associated with
const Console& myConsole;
@ -200,6 +211,12 @@ class TIA : public Device , public MediaSource
// Indicates whether the emulation is paused or not
bool myPauseState;
// message timer
Int32 myMessageTime;
// message text
string myMessageText;
private:
// Indicates the CPU cycle when a TIA sound register was last updated
Int32 myLastSoundUpdateCycle;
@ -434,6 +451,9 @@ class TIA : public Device , public MediaSource
// the PAL color loss effect.
static const uInt32 ourPALPalette[256];
// Table of bitmapped fonts. Holds A..Z and 0..9.
static const uInt32 ourFontData[36];
private:
// Copy constructor isn't supported by this class so make it private
TIA(const TIA&);

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: mainSDL.cxx,v 1.21 2002-04-10 23:51:18 stephena Exp $
// $Id: mainSDL.cxx,v 1.22 2002-04-18 17:18:48 stephena Exp $
//============================================================================
#include <fstream>
@ -51,6 +51,7 @@
#endif
#define HAVE_GETTIMEOFDAY 1
#define MESSAGE_INTERVAL 2
// function prototypes
static bool setupDisplay();
@ -78,6 +79,10 @@ static bool setupProperties(PropertiesSet& set);
static void handleRCFile();
static void usage();
static void loadState();
static void saveState();
static void changeState();
// Globals for the SDL stuff
static SDL_Surface* screen = (SDL_Surface*) NULL;
static Uint32 palette[256];
@ -101,69 +106,70 @@ struct Switches
{
SDLKey scanCode;
Event::Type eventCode;
string message;
};
static Switches list[] = {
{ SDLK_1, Event::KeyboardZero1 },
{ SDLK_2, Event::KeyboardZero2 },
{ SDLK_3, Event::KeyboardZero3 },
{ SDLK_q, Event::KeyboardZero4 },
{ SDLK_w, Event::KeyboardZero5 },
{ SDLK_e, Event::KeyboardZero6 },
{ SDLK_a, Event::KeyboardZero7 },
{ SDLK_s, Event::KeyboardZero8 },
{ SDLK_d, Event::KeyboardZero9 },
{ SDLK_z, Event::KeyboardZeroStar },
{ SDLK_x, Event::KeyboardZero0 },
{ SDLK_c, Event::KeyboardZeroPound },
{ SDLK_1, Event::KeyboardZero1, "" },
{ SDLK_2, Event::KeyboardZero2, "" },
{ SDLK_3, Event::KeyboardZero3, "" },
{ SDLK_q, Event::KeyboardZero4, "" },
{ SDLK_w, Event::KeyboardZero5, "" },
{ SDLK_e, Event::KeyboardZero6, "" },
{ SDLK_a, Event::KeyboardZero7, "" },
{ SDLK_s, Event::KeyboardZero8, "" },
{ SDLK_d, Event::KeyboardZero9, "" },
{ SDLK_z, Event::KeyboardZeroStar, "" },
{ SDLK_x, Event::KeyboardZero0, "" },
{ SDLK_c, Event::KeyboardZeroPound, "" },
{ SDLK_8, Event::KeyboardOne1 },
{ SDLK_9, Event::KeyboardOne2 },
{ SDLK_0, Event::KeyboardOne3 },
{ SDLK_i, Event::KeyboardOne4 },
{ SDLK_o, Event::KeyboardOne5 },
{ SDLK_p, Event::KeyboardOne6 },
{ SDLK_k, Event::KeyboardOne7 },
{ SDLK_l, Event::KeyboardOne8 },
{ SDLK_SEMICOLON, Event::KeyboardOne9 },
{ SDLK_COMMA, Event::KeyboardOneStar },
{ SDLK_PERIOD, Event::KeyboardOne0 },
{ SDLK_SLASH, Event::KeyboardOnePound },
{ SDLK_8, Event::KeyboardOne1, "" },
{ SDLK_9, Event::KeyboardOne2, "" },
{ SDLK_0, Event::KeyboardOne3, "" },
{ SDLK_i, Event::KeyboardOne4, "" },
{ SDLK_o, Event::KeyboardOne5, "" },
{ SDLK_p, Event::KeyboardOne6, "" },
{ SDLK_k, Event::KeyboardOne7, "" },
{ SDLK_l, Event::KeyboardOne8, "" },
{ SDLK_SEMICOLON, Event::KeyboardOne9, "" },
{ SDLK_COMMA, Event::KeyboardOneStar, "" },
{ SDLK_PERIOD, Event::KeyboardOne0, "" },
{ SDLK_SLASH, Event::KeyboardOnePound, "" },
{ SDLK_UP, Event::JoystickZeroUp },
{ SDLK_DOWN, Event::JoystickZeroDown },
{ SDLK_LEFT, Event::JoystickZeroLeft },
{ SDLK_RIGHT, Event::JoystickZeroRight },
{ SDLK_SPACE, Event::JoystickZeroFire },
{ SDLK_RETURN, Event::JoystickZeroFire },
{ SDLK_LCTRL, Event::JoystickZeroFire },
{ SDLK_z, Event::BoosterGripZeroTrigger },
{ SDLK_x, Event::BoosterGripZeroBooster },
{ SDLK_UP, Event::JoystickZeroUp, "" },
{ SDLK_DOWN, Event::JoystickZeroDown, "" },
{ SDLK_LEFT, Event::JoystickZeroLeft, "" },
{ SDLK_RIGHT, Event::JoystickZeroRight, "" },
{ SDLK_SPACE, Event::JoystickZeroFire, "" },
{ SDLK_RETURN, Event::JoystickZeroFire, "" },
{ SDLK_LCTRL, Event::JoystickZeroFire, "" },
{ SDLK_z, Event::BoosterGripZeroTrigger, "" },
{ SDLK_x, Event::BoosterGripZeroBooster, "" },
{ SDLK_w, Event::JoystickZeroUp },
{ SDLK_s, Event::JoystickZeroDown },
{ SDLK_a, Event::JoystickZeroLeft },
{ SDLK_d, Event::JoystickZeroRight },
{ SDLK_TAB, Event::JoystickZeroFire },
{ SDLK_1, Event::BoosterGripZeroTrigger },
{ SDLK_2, Event::BoosterGripZeroBooster },
{ SDLK_w, Event::JoystickZeroUp, "" },
{ SDLK_s, Event::JoystickZeroDown, "" },
{ SDLK_a, Event::JoystickZeroLeft, "" },
{ SDLK_d, Event::JoystickZeroRight, "" },
{ SDLK_TAB, Event::JoystickZeroFire, "" },
{ SDLK_1, Event::BoosterGripZeroTrigger, "" },
{ SDLK_2, Event::BoosterGripZeroBooster, "" },
{ SDLK_o, Event::JoystickOneUp },
{ SDLK_l, Event::JoystickOneDown },
{ SDLK_k, Event::JoystickOneLeft },
{ SDLK_SEMICOLON, Event::JoystickOneRight },
{ SDLK_j, Event::JoystickOneFire },
{ SDLK_n, Event::BoosterGripOneTrigger },
{ SDLK_m, Event::BoosterGripOneBooster },
{ SDLK_o, Event::JoystickOneUp, "" },
{ SDLK_l, Event::JoystickOneDown, "" },
{ SDLK_k, Event::JoystickOneLeft, "" },
{ SDLK_SEMICOLON, Event::JoystickOneRight, "" },
{ SDLK_j, Event::JoystickOneFire, "" },
{ SDLK_n, Event::BoosterGripOneTrigger, "" },
{ SDLK_m, Event::BoosterGripOneBooster, "" },
{ SDLK_F1, Event::ConsoleSelect },
{ SDLK_F2, Event::ConsoleReset },
{ SDLK_F3, Event::ConsoleColor },
{ SDLK_F4, Event::ConsoleBlackWhite },
{ SDLK_F5, Event::ConsoleLeftDifficultyA },
{ SDLK_F6, Event::ConsoleLeftDifficultyB },
{ SDLK_F7, Event::ConsoleRightDifficultyA },
{ SDLK_F8, Event::ConsoleRightDifficultyB }
{ SDLK_F1, Event::ConsoleSelect, "" },
{ SDLK_F2, Event::ConsoleReset, "" },
{ SDLK_F3, Event::ConsoleColor, "Color Mode" },
{ SDLK_F4, Event::ConsoleBlackWhite, "BW Mode" },
{ SDLK_F5, Event::ConsoleLeftDifficultyA, "Left Difficulty A" },
{ SDLK_F6, Event::ConsoleLeftDifficultyB, "Left Difficulty B" },
{ SDLK_F7, Event::ConsoleRightDifficultyA, "Right Difficulty A" },
{ SDLK_F8, Event::ConsoleRightDifficultyB, "Right Difficulty B" }
};
// Event objects to use
@ -191,6 +197,10 @@ static bool isFullscreen = false;
// Indicates whether the window is currently centered
static bool isCentered = false;
// Indicates the current state to use for state saving
static uInt32 currentState = 0;
/**
This routine should be called once the console is created to setup
@ -607,6 +617,77 @@ void grabMouse(bool grab)
}
/**
Saves state of the current game in the current slot.
*/
void saveState()
{
#if 0
// Do a state save using the MediaSource
// ...
// Print appropriate message
char buf[40];
if(true) // if the state saved correctly
snprintf(buf, 39, "State %d saved", currentState);
else
snprintf(buf, 39, "Error saving state %d", currentState);
string message = buf;
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
settings->theDesiredFrameRate);
#else
cerr << "State saving not yet implemented\n";
#endif
}
/**
Changes the current state slot.
*/
void changeState()
{
if(currentState == 9)
currentState = 0;
else
++currentState;
#if 0
// Print appropriate message
char buf[40];
snprintf(buf, 39, "Changed to state slot %d", currentState);
string message = buf;
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
settings->theDesiredFrameRate);
#endif
}
/**
Loads state from the current slot for the current game.
*/
void loadState()
{
#if 0
// Do a state load using the MediaSource
// ...
// Print appropriate message
char buf[40];
if(true) // if the state loaded correctly
snprintf(buf, 39, "State %d loaded", currentState);
else
snprintf(buf, 39, "Error loading state %d", currentState);
string message = buf;
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
settings->theDesiredFrameRate);
#else
cerr << "State loading not yet implemented\n";
#endif
}
/**
This routine should be called anytime the display needs to be updated
*/
@ -809,6 +890,18 @@ void handleEvents()
{
toggleFullscreen();
}
else if(key == SDLK_F9)
{
saveState();
}
else if(key == SDLK_F10)
{
changeState();
}
else if(key == SDLK_F11)
{
loadState();
}
else if(key == SDLK_F12)
{
takeSnapshot();
@ -843,6 +936,9 @@ void handleEvents()
{
theEvent.set(list[i].eventCode, 1);
keyboardEvent.set(list[i].eventCode, 1);
if(list[i].message != "")
theConsole->mediaSource().showMessage(list[i].message,
MESSAGE_INTERVAL * settings->theDesiredFrameRate);
}
}
}

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: mainX11.cxx,v 1.22 2002-04-10 23:51:18 stephena Exp $
// $Id: mainX11.cxx,v 1.23 2002-04-18 17:18:48 stephena Exp $
//============================================================================
#include <fstream>
@ -52,6 +52,7 @@
#endif
#define HAVE_GETTIMEOFDAY 1
#define MESSAGE_INTERVAL 2
// A graphic context for each of the 2600's colors
static GC theGCTable[256];
@ -81,6 +82,10 @@ static bool setupProperties(PropertiesSet& set);
static void handleRCFile();
static void usage();
static void loadState();
static void saveState();
static void changeState();
// Globals for X windows stuff
static Display* theDisplay = (Display*) NULL;
static string theDisplayName = "";
@ -108,69 +113,70 @@ struct Switches
{
KeySym scanCode;
Event::Type eventCode;
string message;
};
static Switches list[] = {
{ XK_1, Event::KeyboardZero1 },
{ XK_2, Event::KeyboardZero2 },
{ XK_3, Event::KeyboardZero3 },
{ XK_q, Event::KeyboardZero4 },
{ XK_w, Event::KeyboardZero5 },
{ XK_e, Event::KeyboardZero6 },
{ XK_a, Event::KeyboardZero7 },
{ XK_s, Event::KeyboardZero8 },
{ XK_d, Event::KeyboardZero9 },
{ XK_z, Event::KeyboardZeroStar },
{ XK_x, Event::KeyboardZero0 },
{ XK_c, Event::KeyboardZeroPound },
{ XK_1, Event::KeyboardZero1, "" },
{ XK_2, Event::KeyboardZero2, "" },
{ XK_3, Event::KeyboardZero3, "" },
{ XK_q, Event::KeyboardZero4, "" },
{ XK_w, Event::KeyboardZero5, "" },
{ XK_e, Event::KeyboardZero6, "" },
{ XK_a, Event::KeyboardZero7, "" },
{ XK_s, Event::KeyboardZero8, "" },
{ XK_d, Event::KeyboardZero9, "" },
{ XK_z, Event::KeyboardZeroStar, "" },
{ XK_x, Event::KeyboardZero0, "" },
{ XK_c, Event::KeyboardZeroPound, "" },
{ XK_8, Event::KeyboardOne1 },
{ XK_9, Event::KeyboardOne2 },
{ XK_0, Event::KeyboardOne3 },
{ XK_i, Event::KeyboardOne4 },
{ XK_o, Event::KeyboardOne5 },
{ XK_p, Event::KeyboardOne6 },
{ XK_k, Event::KeyboardOne7 },
{ XK_l, Event::KeyboardOne8 },
{ XK_semicolon, Event::KeyboardOne9 },
{ XK_comma, Event::KeyboardOneStar },
{ XK_period, Event::KeyboardOne0 },
{ XK_slash, Event::KeyboardOnePound },
{ XK_8, Event::KeyboardOne1, "" },
{ XK_9, Event::KeyboardOne2, "" },
{ XK_0, Event::KeyboardOne3, "" },
{ XK_i, Event::KeyboardOne4, "" },
{ XK_o, Event::KeyboardOne5, "" },
{ XK_p, Event::KeyboardOne6, "" },
{ XK_k, Event::KeyboardOne7, "" },
{ XK_l, Event::KeyboardOne8, "" },
{ XK_semicolon, Event::KeyboardOne9, "" },
{ XK_comma, Event::KeyboardOneStar, "" },
{ XK_period, Event::KeyboardOne0, "" },
{ XK_slash, Event::KeyboardOnePound, "" },
{ XK_Down, Event::JoystickZeroDown },
{ XK_Up, Event::JoystickZeroUp },
{ XK_Left, Event::JoystickZeroLeft },
{ XK_Right, Event::JoystickZeroRight },
{ XK_space, Event::JoystickZeroFire },
{ XK_Return, Event::JoystickZeroFire },
{ XK_Control_L, Event::JoystickZeroFire },
{ XK_z, Event::BoosterGripZeroTrigger },
{ XK_x, Event::BoosterGripZeroBooster },
{ XK_Down, Event::JoystickZeroDown, "" },
{ XK_Up, Event::JoystickZeroUp, "" },
{ XK_Left, Event::JoystickZeroLeft, "" },
{ XK_Right, Event::JoystickZeroRight, "" },
{ XK_space, Event::JoystickZeroFire, "" },
{ XK_Return, Event::JoystickZeroFire, "" },
{ XK_Control_L, Event::JoystickZeroFire, "" },
{ XK_z, Event::BoosterGripZeroTrigger, "" },
{ XK_x, Event::BoosterGripZeroBooster, "" },
{ XK_w, Event::JoystickZeroUp },
{ XK_s, Event::JoystickZeroDown },
{ XK_a, Event::JoystickZeroLeft },
{ XK_d, Event::JoystickZeroRight },
{ XK_Tab, Event::JoystickZeroFire },
{ XK_1, Event::BoosterGripZeroTrigger },
{ XK_2, Event::BoosterGripZeroBooster },
{ XK_w, Event::JoystickZeroUp, "" },
{ XK_s, Event::JoystickZeroDown, "" },
{ XK_a, Event::JoystickZeroLeft, "" },
{ XK_d, Event::JoystickZeroRight, "" },
{ XK_Tab, Event::JoystickZeroFire, "" },
{ XK_1, Event::BoosterGripZeroTrigger, "" },
{ XK_2, Event::BoosterGripZeroBooster, "" },
{ XK_l, Event::JoystickOneDown },
{ XK_o, Event::JoystickOneUp },
{ XK_k, Event::JoystickOneLeft },
{ XK_semicolon, Event::JoystickOneRight },
{ XK_j, Event::JoystickOneFire },
{ XK_n, Event::BoosterGripOneTrigger },
{ XK_m, Event::BoosterGripOneBooster },
{ XK_l, Event::JoystickOneDown, "" },
{ XK_o, Event::JoystickOneUp, "" },
{ XK_k, Event::JoystickOneLeft, "" },
{ XK_semicolon, Event::JoystickOneRight, "" },
{ XK_j, Event::JoystickOneFire, "" },
{ XK_n, Event::BoosterGripOneTrigger, "" },
{ XK_m, Event::BoosterGripOneBooster, "" },
{ XK_F1, Event::ConsoleSelect },
{ XK_F2, Event::ConsoleReset },
{ XK_F3, Event::ConsoleColor },
{ XK_F4, Event::ConsoleBlackWhite },
{ XK_F5, Event::ConsoleLeftDifficultyA },
{ XK_F6, Event::ConsoleLeftDifficultyB },
{ XK_F7, Event::ConsoleRightDifficultyA },
{ XK_F8, Event::ConsoleRightDifficultyB }
{ XK_F1, Event::ConsoleSelect, "" },
{ XK_F2, Event::ConsoleReset, "" },
{ XK_F3, Event::ConsoleColor, "Color Mode" },
{ XK_F4, Event::ConsoleBlackWhite, "BW Mode" },
{ XK_F5, Event::ConsoleLeftDifficultyA, "Left Difficulty A" },
{ XK_F6, Event::ConsoleLeftDifficultyB, "Left Difficulty B" },
{ XK_F7, Event::ConsoleRightDifficultyA, "Right Difficulty A" },
{ XK_F8, Event::ConsoleRightDifficultyB, "Right Difficulty B" }
};
// Event objects to use
@ -198,6 +204,9 @@ static bool isFullscreen = false;
// Indicates whether the window is currently centered
static bool isCentered = false;
// Indicates the current state to use for state saving
static uInt32 currentState = 0;
/**
This routine should be called once the console is created to setup
the X11 connection and open a window for us to use. Return false if any
@ -573,6 +582,18 @@ void handleEvents()
{
resizeWindow(0);
}
else if((key == XK_F9) && (event.type == KeyPress))
{
saveState();
}
else if((key == XK_F10) && (event.type == KeyPress))
{
changeState();
}
else if((key == XK_F11) && (event.type == KeyPress))
{
loadState();
}
else if((key == XK_F12) && (event.type == KeyPress))
{
takeSnapshot();
@ -609,6 +630,10 @@ void handleEvents()
(event.type == KeyPress) ? 1 : 0);
keyboardEvent.set(list[i].eventCode,
(event.type == KeyPress) ? 1 : 0);
if((event.type == KeyPress) && (list[i].message != ""))
theConsole->mediaSource().showMessage(list[i].message,
MESSAGE_INTERVAL * settings->theDesiredFrameRate);
}
}
}
@ -913,6 +938,74 @@ void togglePause()
theRedrawEntireFrameIndicator = true;
}
/**
Saves state of the current game in the current slot.
*/
void saveState()
{
#if 0
// Do a state save using the MediaSource
// ...
// Print appropriate message
char buf[40];
if(true) // if the state saved correctly
snprintf(buf, 39, "State %d saved", currentState);
else
snprintf(buf, 39, "Error saving state %d", currentState);
string message = buf;
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
settings->theDesiredFrameRate);
#else
cerr << "State saving not yet implemented\n";
#endif
}
/**
Changes the current state slot.
*/
void changeState()
{
if(currentState == 9)
currentState = 0;
else
++currentState;
#if 0
// Print appropriate message
char buf[40];
snprintf(buf, 39, "Changed to state slot %d", currentState);
string message = buf;
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
settings->theDesiredFrameRate);
#endif
}
/**
Loads state from the current slot for the current game.
*/
void loadState()
{
#if 0
// Do a state load using the MediaSource
// ...
// Print appropriate message
char buf[40];
if(true) // if the state loaded correctly
snprintf(buf, 39, "State %d loaded", currentState);
else
snprintf(buf, 39, "Error loading state %d", currentState);
string message = buf;
theConsole->mediaSource().showMessage(message, MESSAGE_INTERVAL *
settings->theDesiredFrameRate);
#else
cerr << "State loading not yet implemented\n";
#endif
}
/**
Shows or hides the cursor based on the given boolean value.
*/