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 // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: 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 #ifndef MEDIASOURCE_HXX
#define MEDIASOURCE_HXX #define MEDIASOURCE_HXX
#include <string>
class MediaSource; class MediaSource;
#include "bspf.hxx" #include "bspf.hxx"
@ -27,7 +29,7 @@ class MediaSource;
This class provides an interface for accessing graphics data. This class provides an interface for accessing graphics data.
@author Bradford W. Mott @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 class MediaSource
{ {
@ -58,6 +60,12 @@ class MediaSource
*/ */
virtual bool pause(bool state) = 0; 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 Answers the current frame buffer

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: 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> #include <assert.h>
@ -34,6 +34,8 @@ TIA::TIA(const Console& console, Sound& sound)
: myConsole(console), : myConsole(console),
mySound(sound), mySound(sound),
myPauseState(false), myPauseState(false),
myMessageTime(0),
myMessageText(""),
myLastSoundUpdateCycle(0), myLastSoundUpdateCycle(0),
myColorLossEnabled(false), myColorLossEnabled(false),
myCOLUBK(myColor[0]), myCOLUBK(myColor[0]),
@ -337,6 +339,13 @@ void TIA::update()
// Compute the number of scanlines in the frame // Compute the number of scanlines in the frame
uInt32 totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted; uInt32 totalClocks = (mySystem->cycles() * 3) - myClockWhenFrameStarted;
myScanlineCountForLastFrame = totalClocks / 228; 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 const uInt32* TIA::palette() const
{ {
@ -2828,6 +2906,46 @@ const uInt32 TIA::ourPALPalette[256] = {
0xd2d2d2, 0xd2d2d2, 0xececec, 0xececec 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) TIA::TIA(const TIA& c)
: myConsole(c.myConsole), : myConsole(c.myConsole),

View File

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

View File

@ -13,7 +13,7 @@
// See the file "license" for information on usage and redistribution of // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: 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> #include <fstream>
@ -51,6 +51,7 @@
#endif #endif
#define HAVE_GETTIMEOFDAY 1 #define HAVE_GETTIMEOFDAY 1
#define MESSAGE_INTERVAL 2
// function prototypes // function prototypes
static bool setupDisplay(); static bool setupDisplay();
@ -78,6 +79,10 @@ static bool setupProperties(PropertiesSet& set);
static void handleRCFile(); static void handleRCFile();
static void usage(); static void usage();
static void loadState();
static void saveState();
static void changeState();
// Globals for the SDL stuff // Globals for the SDL stuff
static SDL_Surface* screen = (SDL_Surface*) NULL; static SDL_Surface* screen = (SDL_Surface*) NULL;
static Uint32 palette[256]; static Uint32 palette[256];
@ -101,69 +106,70 @@ struct Switches
{ {
SDLKey scanCode; SDLKey scanCode;
Event::Type eventCode; Event::Type eventCode;
string message;
}; };
static Switches list[] = { static Switches list[] = {
{ SDLK_1, Event::KeyboardZero1 }, { SDLK_1, Event::KeyboardZero1, "" },
{ SDLK_2, Event::KeyboardZero2 }, { SDLK_2, Event::KeyboardZero2, "" },
{ SDLK_3, Event::KeyboardZero3 }, { SDLK_3, Event::KeyboardZero3, "" },
{ SDLK_q, Event::KeyboardZero4 }, { SDLK_q, Event::KeyboardZero4, "" },
{ SDLK_w, Event::KeyboardZero5 }, { SDLK_w, Event::KeyboardZero5, "" },
{ SDLK_e, Event::KeyboardZero6 }, { SDLK_e, Event::KeyboardZero6, "" },
{ SDLK_a, Event::KeyboardZero7 }, { SDLK_a, Event::KeyboardZero7, "" },
{ SDLK_s, Event::KeyboardZero8 }, { SDLK_s, Event::KeyboardZero8, "" },
{ SDLK_d, Event::KeyboardZero9 }, { SDLK_d, Event::KeyboardZero9, "" },
{ SDLK_z, Event::KeyboardZeroStar }, { SDLK_z, Event::KeyboardZeroStar, "" },
{ SDLK_x, Event::KeyboardZero0 }, { SDLK_x, Event::KeyboardZero0, "" },
{ SDLK_c, Event::KeyboardZeroPound }, { SDLK_c, Event::KeyboardZeroPound, "" },
{ SDLK_8, Event::KeyboardOne1 }, { SDLK_8, Event::KeyboardOne1, "" },
{ SDLK_9, Event::KeyboardOne2 }, { SDLK_9, Event::KeyboardOne2, "" },
{ SDLK_0, Event::KeyboardOne3 }, { SDLK_0, Event::KeyboardOne3, "" },
{ SDLK_i, Event::KeyboardOne4 }, { SDLK_i, Event::KeyboardOne4, "" },
{ SDLK_o, Event::KeyboardOne5 }, { SDLK_o, Event::KeyboardOne5, "" },
{ SDLK_p, Event::KeyboardOne6 }, { SDLK_p, Event::KeyboardOne6, "" },
{ SDLK_k, Event::KeyboardOne7 }, { SDLK_k, Event::KeyboardOne7, "" },
{ SDLK_l, Event::KeyboardOne8 }, { SDLK_l, Event::KeyboardOne8, "" },
{ SDLK_SEMICOLON, Event::KeyboardOne9 }, { SDLK_SEMICOLON, Event::KeyboardOne9, "" },
{ SDLK_COMMA, Event::KeyboardOneStar }, { SDLK_COMMA, Event::KeyboardOneStar, "" },
{ SDLK_PERIOD, Event::KeyboardOne0 }, { SDLK_PERIOD, Event::KeyboardOne0, "" },
{ SDLK_SLASH, Event::KeyboardOnePound }, { SDLK_SLASH, Event::KeyboardOnePound, "" },
{ SDLK_UP, Event::JoystickZeroUp }, { SDLK_UP, Event::JoystickZeroUp, "" },
{ SDLK_DOWN, Event::JoystickZeroDown }, { SDLK_DOWN, Event::JoystickZeroDown, "" },
{ SDLK_LEFT, Event::JoystickZeroLeft }, { SDLK_LEFT, Event::JoystickZeroLeft, "" },
{ SDLK_RIGHT, Event::JoystickZeroRight }, { SDLK_RIGHT, Event::JoystickZeroRight, "" },
{ SDLK_SPACE, Event::JoystickZeroFire }, { SDLK_SPACE, Event::JoystickZeroFire, "" },
{ SDLK_RETURN, Event::JoystickZeroFire }, { SDLK_RETURN, Event::JoystickZeroFire, "" },
{ SDLK_LCTRL, Event::JoystickZeroFire }, { SDLK_LCTRL, Event::JoystickZeroFire, "" },
{ SDLK_z, Event::BoosterGripZeroTrigger }, { SDLK_z, Event::BoosterGripZeroTrigger, "" },
{ SDLK_x, Event::BoosterGripZeroBooster }, { SDLK_x, Event::BoosterGripZeroBooster, "" },
{ SDLK_w, Event::JoystickZeroUp }, { SDLK_w, Event::JoystickZeroUp, "" },
{ SDLK_s, Event::JoystickZeroDown }, { SDLK_s, Event::JoystickZeroDown, "" },
{ SDLK_a, Event::JoystickZeroLeft }, { SDLK_a, Event::JoystickZeroLeft, "" },
{ SDLK_d, Event::JoystickZeroRight }, { SDLK_d, Event::JoystickZeroRight, "" },
{ SDLK_TAB, Event::JoystickZeroFire }, { SDLK_TAB, Event::JoystickZeroFire, "" },
{ SDLK_1, Event::BoosterGripZeroTrigger }, { SDLK_1, Event::BoosterGripZeroTrigger, "" },
{ SDLK_2, Event::BoosterGripZeroBooster }, { SDLK_2, Event::BoosterGripZeroBooster, "" },
{ SDLK_o, Event::JoystickOneUp }, { SDLK_o, Event::JoystickOneUp, "" },
{ SDLK_l, Event::JoystickOneDown }, { SDLK_l, Event::JoystickOneDown, "" },
{ SDLK_k, Event::JoystickOneLeft }, { SDLK_k, Event::JoystickOneLeft, "" },
{ SDLK_SEMICOLON, Event::JoystickOneRight }, { SDLK_SEMICOLON, Event::JoystickOneRight, "" },
{ SDLK_j, Event::JoystickOneFire }, { SDLK_j, Event::JoystickOneFire, "" },
{ SDLK_n, Event::BoosterGripOneTrigger }, { SDLK_n, Event::BoosterGripOneTrigger, "" },
{ SDLK_m, Event::BoosterGripOneBooster }, { SDLK_m, Event::BoosterGripOneBooster, "" },
{ SDLK_F1, Event::ConsoleSelect }, { SDLK_F1, Event::ConsoleSelect, "" },
{ SDLK_F2, Event::ConsoleReset }, { SDLK_F2, Event::ConsoleReset, "" },
{ SDLK_F3, Event::ConsoleColor }, { SDLK_F3, Event::ConsoleColor, "Color Mode" },
{ SDLK_F4, Event::ConsoleBlackWhite }, { SDLK_F4, Event::ConsoleBlackWhite, "BW Mode" },
{ SDLK_F5, Event::ConsoleLeftDifficultyA }, { SDLK_F5, Event::ConsoleLeftDifficultyA, "Left Difficulty A" },
{ SDLK_F6, Event::ConsoleLeftDifficultyB }, { SDLK_F6, Event::ConsoleLeftDifficultyB, "Left Difficulty B" },
{ SDLK_F7, Event::ConsoleRightDifficultyA }, { SDLK_F7, Event::ConsoleRightDifficultyA, "Right Difficulty A" },
{ SDLK_F8, Event::ConsoleRightDifficultyB } { SDLK_F8, Event::ConsoleRightDifficultyB, "Right Difficulty B" }
}; };
// Event objects to use // Event objects to use
@ -191,6 +197,10 @@ static bool isFullscreen = false;
// Indicates whether the window is currently centered // Indicates whether the window is currently centered
static bool isCentered = false; 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 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 This routine should be called anytime the display needs to be updated
*/ */
@ -809,6 +890,18 @@ void handleEvents()
{ {
toggleFullscreen(); toggleFullscreen();
} }
else if(key == SDLK_F9)
{
saveState();
}
else if(key == SDLK_F10)
{
changeState();
}
else if(key == SDLK_F11)
{
loadState();
}
else if(key == SDLK_F12) else if(key == SDLK_F12)
{ {
takeSnapshot(); takeSnapshot();
@ -843,6 +936,9 @@ void handleEvents()
{ {
theEvent.set(list[i].eventCode, 1); theEvent.set(list[i].eventCode, 1);
keyboardEvent.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 // See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES. // this file, and for a DISCLAIMER OF ALL WARRANTIES.
// //
// $Id: 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> #include <fstream>
@ -52,6 +52,7 @@
#endif #endif
#define HAVE_GETTIMEOFDAY 1 #define HAVE_GETTIMEOFDAY 1
#define MESSAGE_INTERVAL 2
// A graphic context for each of the 2600's colors // A graphic context for each of the 2600's colors
static GC theGCTable[256]; static GC theGCTable[256];
@ -81,6 +82,10 @@ static bool setupProperties(PropertiesSet& set);
static void handleRCFile(); static void handleRCFile();
static void usage(); static void usage();
static void loadState();
static void saveState();
static void changeState();
// Globals for X windows stuff // Globals for X windows stuff
static Display* theDisplay = (Display*) NULL; static Display* theDisplay = (Display*) NULL;
static string theDisplayName = ""; static string theDisplayName = "";
@ -108,69 +113,70 @@ struct Switches
{ {
KeySym scanCode; KeySym scanCode;
Event::Type eventCode; Event::Type eventCode;
string message;
}; };
static Switches list[] = { static Switches list[] = {
{ XK_1, Event::KeyboardZero1 }, { XK_1, Event::KeyboardZero1, "" },
{ XK_2, Event::KeyboardZero2 }, { XK_2, Event::KeyboardZero2, "" },
{ XK_3, Event::KeyboardZero3 }, { XK_3, Event::KeyboardZero3, "" },
{ XK_q, Event::KeyboardZero4 }, { XK_q, Event::KeyboardZero4, "" },
{ XK_w, Event::KeyboardZero5 }, { XK_w, Event::KeyboardZero5, "" },
{ XK_e, Event::KeyboardZero6 }, { XK_e, Event::KeyboardZero6, "" },
{ XK_a, Event::KeyboardZero7 }, { XK_a, Event::KeyboardZero7, "" },
{ XK_s, Event::KeyboardZero8 }, { XK_s, Event::KeyboardZero8, "" },
{ XK_d, Event::KeyboardZero9 }, { XK_d, Event::KeyboardZero9, "" },
{ XK_z, Event::KeyboardZeroStar }, { XK_z, Event::KeyboardZeroStar, "" },
{ XK_x, Event::KeyboardZero0 }, { XK_x, Event::KeyboardZero0, "" },
{ XK_c, Event::KeyboardZeroPound }, { XK_c, Event::KeyboardZeroPound, "" },
{ XK_8, Event::KeyboardOne1 }, { XK_8, Event::KeyboardOne1, "" },
{ XK_9, Event::KeyboardOne2 }, { XK_9, Event::KeyboardOne2, "" },
{ XK_0, Event::KeyboardOne3 }, { XK_0, Event::KeyboardOne3, "" },
{ XK_i, Event::KeyboardOne4 }, { XK_i, Event::KeyboardOne4, "" },
{ XK_o, Event::KeyboardOne5 }, { XK_o, Event::KeyboardOne5, "" },
{ XK_p, Event::KeyboardOne6 }, { XK_p, Event::KeyboardOne6, "" },
{ XK_k, Event::KeyboardOne7 }, { XK_k, Event::KeyboardOne7, "" },
{ XK_l, Event::KeyboardOne8 }, { XK_l, Event::KeyboardOne8, "" },
{ XK_semicolon, Event::KeyboardOne9 }, { XK_semicolon, Event::KeyboardOne9, "" },
{ XK_comma, Event::KeyboardOneStar }, { XK_comma, Event::KeyboardOneStar, "" },
{ XK_period, Event::KeyboardOne0 }, { XK_period, Event::KeyboardOne0, "" },
{ XK_slash, Event::KeyboardOnePound }, { XK_slash, Event::KeyboardOnePound, "" },
{ XK_Down, Event::JoystickZeroDown }, { XK_Down, Event::JoystickZeroDown, "" },
{ XK_Up, Event::JoystickZeroUp }, { XK_Up, Event::JoystickZeroUp, "" },
{ XK_Left, Event::JoystickZeroLeft }, { XK_Left, Event::JoystickZeroLeft, "" },
{ XK_Right, Event::JoystickZeroRight }, { XK_Right, Event::JoystickZeroRight, "" },
{ XK_space, Event::JoystickZeroFire }, { XK_space, Event::JoystickZeroFire, "" },
{ XK_Return, Event::JoystickZeroFire }, { XK_Return, Event::JoystickZeroFire, "" },
{ XK_Control_L, Event::JoystickZeroFire }, { XK_Control_L, Event::JoystickZeroFire, "" },
{ XK_z, Event::BoosterGripZeroTrigger }, { XK_z, Event::BoosterGripZeroTrigger, "" },
{ XK_x, Event::BoosterGripZeroBooster }, { XK_x, Event::BoosterGripZeroBooster, "" },
{ XK_w, Event::JoystickZeroUp }, { XK_w, Event::JoystickZeroUp, "" },
{ XK_s, Event::JoystickZeroDown }, { XK_s, Event::JoystickZeroDown, "" },
{ XK_a, Event::JoystickZeroLeft }, { XK_a, Event::JoystickZeroLeft, "" },
{ XK_d, Event::JoystickZeroRight }, { XK_d, Event::JoystickZeroRight, "" },
{ XK_Tab, Event::JoystickZeroFire }, { XK_Tab, Event::JoystickZeroFire, "" },
{ XK_1, Event::BoosterGripZeroTrigger }, { XK_1, Event::BoosterGripZeroTrigger, "" },
{ XK_2, Event::BoosterGripZeroBooster }, { XK_2, Event::BoosterGripZeroBooster, "" },
{ XK_l, Event::JoystickOneDown }, { XK_l, Event::JoystickOneDown, "" },
{ XK_o, Event::JoystickOneUp }, { XK_o, Event::JoystickOneUp, "" },
{ XK_k, Event::JoystickOneLeft }, { XK_k, Event::JoystickOneLeft, "" },
{ XK_semicolon, Event::JoystickOneRight }, { XK_semicolon, Event::JoystickOneRight, "" },
{ XK_j, Event::JoystickOneFire }, { XK_j, Event::JoystickOneFire, "" },
{ XK_n, Event::BoosterGripOneTrigger }, { XK_n, Event::BoosterGripOneTrigger, "" },
{ XK_m, Event::BoosterGripOneBooster }, { XK_m, Event::BoosterGripOneBooster, "" },
{ XK_F1, Event::ConsoleSelect }, { XK_F1, Event::ConsoleSelect, "" },
{ XK_F2, Event::ConsoleReset }, { XK_F2, Event::ConsoleReset, "" },
{ XK_F3, Event::ConsoleColor }, { XK_F3, Event::ConsoleColor, "Color Mode" },
{ XK_F4, Event::ConsoleBlackWhite }, { XK_F4, Event::ConsoleBlackWhite, "BW Mode" },
{ XK_F5, Event::ConsoleLeftDifficultyA }, { XK_F5, Event::ConsoleLeftDifficultyA, "Left Difficulty A" },
{ XK_F6, Event::ConsoleLeftDifficultyB }, { XK_F6, Event::ConsoleLeftDifficultyB, "Left Difficulty B" },
{ XK_F7, Event::ConsoleRightDifficultyA }, { XK_F7, Event::ConsoleRightDifficultyA, "Right Difficulty A" },
{ XK_F8, Event::ConsoleRightDifficultyB } { XK_F8, Event::ConsoleRightDifficultyB, "Right Difficulty B" }
}; };
// Event objects to use // Event objects to use
@ -198,6 +204,9 @@ static bool isFullscreen = false;
// Indicates whether the window is currently centered // Indicates whether the window is currently centered
static bool isCentered = false; 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 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 the X11 connection and open a window for us to use. Return false if any
@ -573,6 +582,18 @@ void handleEvents()
{ {
resizeWindow(0); 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)) else if((key == XK_F12) && (event.type == KeyPress))
{ {
takeSnapshot(); takeSnapshot();
@ -609,6 +630,10 @@ void handleEvents()
(event.type == KeyPress) ? 1 : 0); (event.type == KeyPress) ? 1 : 0);
keyboardEvent.set(list[i].eventCode, keyboardEvent.set(list[i].eventCode,
(event.type == KeyPress) ? 1 : 0); (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; 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. Shows or hides the cursor based on the given boolean value.
*/ */