More code changes and reorganization for key remapping. The SDL version

now uses the EventHandler class and doesn't directly handle events itself.

All thats left for key remapping is to create load/save methods for the
event arrays.  Of course, to actually change events from within the
emulator will require a GUI, which I haven't even started yet :)  The GUI
will have to wait until the graphics rewrite, where we go to a full
320x200 framebuffer (versus the 160x200 one we have now).

In the meantime, remapping will be configurable from the rcfile only.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@177 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2003-09-06 21:17:48 +00:00
parent 06a673592f
commit 21eb45ddf1
11 changed files with 575 additions and 463 deletions

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: makefile,v 1.32 2003-09-05 18:02:58 stephena Exp $
## $Id: makefile,v 1.33 2003-09-06 21:17:48 stephena Exp $
##============================================================================
##============================================================================
@ -30,8 +30,8 @@ OPTIMIZATIONS = $(CXXFLAGS) -Wall -Wno-unused
### SDL sound not yet supported in the X11 version
### comment out all lines to completely disable sound
###
#SOUND_ALSA = 1
SOUND_OSS = 1
SOUND_ALSA = 1
#SOUND_OSS = 1
#SOUND_SDL = 1
### if your C++ compiler doesn't support the bool type
@ -89,7 +89,7 @@ SRC = ..
CORE = $(SRC)/emucore
UI = $(SRC)/ui
INCLUDES = -I. -I$(CORE) -I$(CORE)/m6502/src -I$(CORE)/m6502/src/bspf/src -I$(UI)/common
INCLUDES = -I. -I$(CORE) -I$(CORE)/m6502/src -I$(CORE)/m6502/src/bspf/src -I$(UI)/common -I$(UI)/frontend
FLAGS = $(OPTIMIZATIONS) $(INCLUDES) $(SYS_INCLUDES)
@ -199,7 +199,7 @@ unix-x:
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o"
OBJS="mainX11.o FrontendUNIX.o"
OBJS+="$(OBJS.X11)"
linux-x:
@ -212,7 +212,7 @@ linux-x:
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o" \
OBJS="mainX11.o FrontendUNIX.o" \
OBJS+="$(OBJS.X11)"
linux-sdl:
@ -225,7 +225,7 @@ linux-sdl:
LDFLAGS+="$(CFLAGS.SDL)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.SDL)" \
OBJS="mainSDL.o RectList.o" \
OBJS="mainSDL.o RectList.o FrontendUNIX.o" \
OBJS+="$(OBJS.SDL)"
bsdi-x:
@ -238,7 +238,7 @@ bsdi-x:
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o"
OBJS="mainX11.o FrontendUNIX.o"
OBJS+="$(OBJS.X11)"
solaris-x:
@ -251,7 +251,7 @@ solaris-x:
LDFLAGS+="$(CFLAGS.X11)" \
LDLIBS="-lX11 -lXext" \
LDLIBS+="$(LIBS.X11)" \
OBJS="mainX11.o"
OBJS="mainX11.o FrontendUNIX.o"
OBJS+="$(OBJS.X11)"
###############################################################################
@ -457,6 +457,9 @@ SoundOSS.o: $(UI)/sound/SoundOSS.cxx $(UI)/sound/SoundOSS.hxx
SoundSDL.o: $(UI)/sound/SoundSDL.cxx $(UI)/sound/SoundSDL.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(UI)/sound/SoundSDL.cxx
FrontendUNIX.o: $(UI)/frontend/FrontendUNIX.cxx $(UI)/frontend/FrontendUNIX.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(UI)/frontend/FrontendUNIX.cxx
TermX11.o: $(UI)/x11/TermX11.cxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(UI)/x11/TermX11.cxx

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: Console.cxx,v 1.11 2003-09-04 16:50:48 stephena Exp $
// $Id: Console.cxx,v 1.12 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#include <assert.h>
@ -28,6 +28,7 @@
#include "Driving.hxx"
#include "Event.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "Joystick.hxx"
#include "Keyboard.hxx"
#include "M6502Low.hxx"
@ -45,10 +46,11 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const uInt8* image, uInt32 size, const char* filename,
Settings& rcsettings, PropertiesSet& propertiesSet, uInt32 sampleRate,
const Properties* userDefinedProperties)
Settings& rcsettings, PropertiesSet& propertiesSet, Frontend& frontend,
uInt32 sampleRate, const Properties* userDefinedProperties)
: mySettings(rcsettings),
myPropSet(propertiesSet)
myPropSet(propertiesSet),
myFrontend(frontend)
{
myControllers[0] = 0;
myControllers[1] = 0;
@ -60,6 +62,9 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
// Inform the settings object about the console
mySettings.setConsole(this);
// Inform the frontend object about the console
myFrontend.setConsole(this);
// Create an event handler which will collect and dispatch events
myEventHandler = new EventHandler(this);
myEvent = myEventHandler->event();
@ -169,7 +174,8 @@ Console::Console(const uInt8* image, uInt32 size, const char* filename,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Console::Console(const Console& console)
: mySettings(console.mySettings),
myPropSet(console.myPropSet)
myPropSet(console.myPropSet),
myFrontend(console.myFrontend)
{
// TODO: Write this method
assert(false);
@ -185,6 +191,12 @@ Console::~Console()
delete myEventHandler;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Frontend& Console::frontend() const
{
return myFrontend;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Properties& Console::properties() const
{

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: Console.hxx,v 1.7 2003-09-04 16:50:48 stephena Exp $
// $Id: Console.hxx,v 1.8 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -23,6 +23,7 @@ class Console;
class Controller;
class Event;
class EventHandler;
class Frontend;
class MediaSource;
class PropertiesSet;
class Settings;
@ -38,7 +39,7 @@ class System;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.7 2003-09-04 16:50:48 stephena Exp $
@version $Id: Console.hxx,v 1.8 2003-09-06 21:17:48 stephena Exp $
*/
class Console
{
@ -56,8 +57,8 @@ class Console
@param userDefinedProperties User properties that should override the defaults
*/
Console(const uInt8* image, uInt32 size, const char* filename,
Settings& rcsettings, PropertiesSet& propertiesSet, uInt32 sampleRate,
const Properties* userDefinedProperties = 0);
Settings& rcsettings, PropertiesSet& propertiesSet, Frontend& frontend,
uInt32 sampleRate, const Properties* userDefinedProperties = 0);
/**
Create a new console object by copying another one
@ -92,6 +93,13 @@ class Console
return *myMediaSource;
}
/**
Get the frontend used by the console
@return The frontend used by the console
*/
Frontend& frontend() const;
/**
Get the properties being used by the game
@ -225,6 +233,9 @@ class Console
// Reference to the PropertiesSet object
PropertiesSet& myPropSet;
// Reference to the Frontend object
Frontend& myFrontend;
// Pointer to the EventHandler object
EventHandler* myEventHandler;

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: Event.hxx,v 1.2 2003-09-04 23:23:06 stephena Exp $
// $Id: Event.hxx,v 1.3 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef EVENT_HXX
@ -25,7 +25,7 @@ class Event;
/**
@author Bradford W. Mott
@version $Id: Event.hxx,v 1.2 2003-09-04 23:23:06 stephena Exp $
@version $Id: Event.hxx,v 1.3 2003-09-06 21:17:48 stephena Exp $
*/
class Event
{
@ -66,7 +66,7 @@ class Event
DrivingZeroClockwise, DrivingZeroCounterClockwise, DrivingZeroFire,
DrivingOneClockwise, DrivingOneCounterClockwise, DrivingOneFire,
ChangeState, LoadState, SaveState, TakeSnapshot,
ChangeState, LoadState, SaveState, TakeSnapshot, Pause, Quit,
LastType
};

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: EventHandler.cxx,v 1.3 2003-09-04 23:23:06 stephena Exp $
// $Id: EventHandler.cxx,v 1.4 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#include <sstream>
@ -21,6 +21,7 @@
#include "Console.hxx"
#include "Event.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "MediaSrc.hxx"
#include "StellaEvent.hxx"
#include "System.hxx"
@ -37,10 +38,24 @@ EventHandler::EventHandler(Console* console)
// Erase the KeyEvent array
for(Int32 i = 0; i < StellaEvent::LastKCODE; ++i)
{
keyTable[i].type = Event::LastType;
keyTable[i].message = "";
}
myKeyTable[i] = Event::LastType;
// Erase the JoyEvent array
for(Int32 i = 0; i < StellaEvent::LastJSTICK; ++i)
for(Int32 j = 0; j < StellaEvent::LastJCODE; ++j)
myJoyTable[i][j] = Event::LastType;
// Erase the Message array
for(Int32 i = 0; i < Event::LastType; ++i)
myMessageTable[i] = "";
// Set unchanging messages
myMessageTable[Event::ConsoleColor] = "Color Mode";
myMessageTable[Event::ConsoleBlackWhite] = "BW Mode";
myMessageTable[Event::ConsoleLeftDifficultyA] = "Left Difficulty A";
myMessageTable[Event::ConsoleLeftDifficultyB] = "Left Difficulty B";
myMessageTable[Event::ConsoleRightDifficultyA] = "Right Difficulty A";
myMessageTable[Event::ConsoleRightDifficultyB] = "Right Difficulty B";
setDefaultKeymap();
setDefaultJoymap();
@ -66,107 +81,176 @@ void EventHandler::setMediaSource(MediaSource* mediaSource)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::sendKeyEvent(StellaEvent::KeyCode key,
StellaEvent::KeyState state)
void EventHandler::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
{
// Ignore unmapped keys
if(keyTable[key].type == Event::LastType)
Event::Type event = myKeyTable[key];
// Ignore unmapped events
if(event == Event::LastType)
return;
// Take care of special events that aren't technically part of
// the emulation core
if(state == StellaEvent::KSTATE_PRESSED)
if(state == 1)
{
if(keyTable[key].type == Event::SaveState)
if(event == Event::SaveState)
{
saveState();
return;
}
else if(keyTable[key].type == Event::ChangeState)
else if(event == Event::ChangeState)
{
changeState();
return;
}
else if(keyTable[key].type == Event::LoadState)
else if(event == Event::LoadState)
{
loadState();
return;
}
// else if(keyTable[key].type == Event::TakeSnapshot)
// cerr << "Event::TakeSnapshot received\n";
// else if(event == Event::TakeSnapshot)
// {
// FIXME ... make a call to takeSnapshot()
// return;
// }
else if(event == Event::Pause)
{
myConsole->frontend().setPauseEvent();
return;
}
else if(event == Event::Quit)
{
myConsole->frontend().setQuitEvent();
return;
}
if(keyTable[key].message != "")
myMediaSource->showMessage(keyTable[key].message, 120);
if(myMessageTable[event] != "")
myMediaSource->showMessage(myMessageTable[event], 120);
}
// Otherwise, pass it to the emulation core
myEvent->set(keyTable[key].type, state);
myEvent->set(event, state);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::sendJoyEvent(StellaEvent::JoyStick stick,
StellaEvent::JoyCode code, Int32 state)
{
Event::Type event = myJoyTable[stick][code];
// Ignore unmapped events
if(event == Event::LastType)
return;
// Take care of special events that aren't technically part of
// the emulation core
if(state == 1)
{
if(event == Event::SaveState)
{
saveState();
return;
}
else if(event == Event::ChangeState)
{
changeState();
return;
}
else if(event == Event::LoadState)
{
loadState();
return;
}
// else if(event == Event::TakeSnapshot)
// {
// FIXME ... make a call to takeSnapshot()
// return;
// }
else if(event == Event::Pause)
{
myConsole->frontend().setPauseEvent();
return;
}
else if(event == Event::Quit)
{
myConsole->frontend().setQuitEvent();
return;
}
if(myMessageTable[event] != "")
myMediaSource->showMessage(myMessageTable[event], 120);
}
// Otherwise, pass it to the emulation core
myEvent->set(event, state);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::sendEvent(Event::Type type, Int32 value)
{
myEvent->set(type, value);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setDefaultKeymap()
{
keyTable[StellaEvent::KCODE_1].type = Event::KeyboardZero1;
keyTable[StellaEvent::KCODE_2].type = Event::KeyboardZero2;
keyTable[StellaEvent::KCODE_3].type = Event::KeyboardZero3;
keyTable[StellaEvent::KCODE_q].type = Event::KeyboardZero4;
keyTable[StellaEvent::KCODE_w].type = Event::KeyboardZero5;
keyTable[StellaEvent::KCODE_e].type = Event::KeyboardZero6;
keyTable[StellaEvent::KCODE_a].type = Event::KeyboardZero7;
keyTable[StellaEvent::KCODE_s].type = Event::KeyboardZero8;
keyTable[StellaEvent::KCODE_d].type = Event::KeyboardZero9;
keyTable[StellaEvent::KCODE_z].type = Event::KeyboardZeroStar;
keyTable[StellaEvent::KCODE_x].type = Event::KeyboardZero0;
keyTable[StellaEvent::KCODE_c].type = Event::KeyboardZeroPound;
myKeyTable[StellaEvent::KCODE_1] = Event::KeyboardZero1;
myKeyTable[StellaEvent::KCODE_2] = Event::KeyboardZero2;
myKeyTable[StellaEvent::KCODE_3] = Event::KeyboardZero3;
myKeyTable[StellaEvent::KCODE_q] = Event::KeyboardZero4;
myKeyTable[StellaEvent::KCODE_w] = Event::KeyboardZero5;
myKeyTable[StellaEvent::KCODE_e] = Event::KeyboardZero6;
myKeyTable[StellaEvent::KCODE_a] = Event::KeyboardZero7;
myKeyTable[StellaEvent::KCODE_s] = Event::KeyboardZero8;
myKeyTable[StellaEvent::KCODE_d] = Event::KeyboardZero9;
myKeyTable[StellaEvent::KCODE_z] = Event::KeyboardZeroStar;
myKeyTable[StellaEvent::KCODE_x] = Event::KeyboardZero0;
myKeyTable[StellaEvent::KCODE_c] = Event::KeyboardZeroPound;
keyTable[StellaEvent::KCODE_8].type = Event::KeyboardOne1;
keyTable[StellaEvent::KCODE_9].type = Event::KeyboardOne2;
keyTable[StellaEvent::KCODE_0].type = Event::KeyboardOne3;
keyTable[StellaEvent::KCODE_i].type = Event::KeyboardOne4;
keyTable[StellaEvent::KCODE_o].type = Event::KeyboardOne5;
keyTable[StellaEvent::KCODE_p].type = Event::KeyboardOne6;
keyTable[StellaEvent::KCODE_k].type = Event::KeyboardOne7;
keyTable[StellaEvent::KCODE_l].type = Event::KeyboardOne8;
keyTable[StellaEvent::KCODE_SEMICOLON].type = Event::KeyboardOne9;
keyTable[StellaEvent::KCODE_COMMA].type = Event::KeyboardOneStar;
keyTable[StellaEvent::KCODE_PERIOD].type = Event::KeyboardOne0;
keyTable[StellaEvent::KCODE_SLASH].type = Event::KeyboardOnePound;
myKeyTable[StellaEvent::KCODE_8] = Event::KeyboardOne1;
myKeyTable[StellaEvent::KCODE_9] = Event::KeyboardOne2;
myKeyTable[StellaEvent::KCODE_0] = Event::KeyboardOne3;
myKeyTable[StellaEvent::KCODE_i] = Event::KeyboardOne4;
myKeyTable[StellaEvent::KCODE_o] = Event::KeyboardOne5;
myKeyTable[StellaEvent::KCODE_p] = Event::KeyboardOne6;
myKeyTable[StellaEvent::KCODE_k] = Event::KeyboardOne7;
myKeyTable[StellaEvent::KCODE_l] = Event::KeyboardOne8;
myKeyTable[StellaEvent::KCODE_SEMICOLON] = Event::KeyboardOne9;
myKeyTable[StellaEvent::KCODE_COMMA] = Event::KeyboardOneStar;
myKeyTable[StellaEvent::KCODE_PERIOD] = Event::KeyboardOne0;
myKeyTable[StellaEvent::KCODE_SLASH] = Event::KeyboardOnePound;
keyTable[StellaEvent::KCODE_UP].type = Event::JoystickZeroUp;
keyTable[StellaEvent::KCODE_DOWN].type = Event::JoystickZeroDown;
keyTable[StellaEvent::KCODE_LEFT].type = Event::JoystickZeroLeft;
keyTable[StellaEvent::KCODE_RIGHT].type = Event::JoystickZeroRight;
keyTable[StellaEvent::KCODE_SPACE].type = Event::JoystickZeroFire;
// keyTable[StellaEvent::KCODE_].type = Event::BoosterGripZeroTrigger;
// keyTable[StellaEvent::KCODE_].type = Event::BoosterGripZeroBooster;
myKeyTable[StellaEvent::KCODE_UP] = Event::JoystickZeroUp;
myKeyTable[StellaEvent::KCODE_DOWN] = Event::JoystickZeroDown;
myKeyTable[StellaEvent::KCODE_LEFT] = Event::JoystickZeroLeft;
myKeyTable[StellaEvent::KCODE_RIGHT] = Event::JoystickZeroRight;
myKeyTable[StellaEvent::KCODE_SPACE] = Event::JoystickZeroFire;
// myKeyTable[StellaEvent::KCODE_] = Event::BoosterGripZeroTrigger;
// myKeyTable[StellaEvent::KCODE_] = Event::BoosterGripZeroBooster;
keyTable[StellaEvent::KCODE_y].type = Event::JoystickOneUp;
keyTable[StellaEvent::KCODE_h].type = Event::JoystickOneDown;
keyTable[StellaEvent::KCODE_g].type = Event::JoystickOneLeft;
keyTable[StellaEvent::KCODE_j].type = Event::JoystickOneRight;
keyTable[StellaEvent::KCODE_f].type = Event::JoystickOneFire;
// keyTable[StellaEvent::KCODE_].type = Event::BoosterGripOneTrigger;
// keyTable[StellaEvent::KCODE_].type = Event::BoosterGripOneBooster;
myKeyTable[StellaEvent::KCODE_y] = Event::JoystickOneUp;
myKeyTable[StellaEvent::KCODE_h] = Event::JoystickOneDown;
myKeyTable[StellaEvent::KCODE_g] = Event::JoystickOneLeft;
myKeyTable[StellaEvent::KCODE_j] = Event::JoystickOneRight;
myKeyTable[StellaEvent::KCODE_f] = Event::JoystickOneFire;
// myKeyTable[StellaEvent::KCODE_] = Event::BoosterGripOneTrigger;
// myKeyTable[StellaEvent::KCODE_] = Event::BoosterGripOneBooster;
keyTable[StellaEvent::KCODE_F1].type = Event::ConsoleSelect;
keyTable[StellaEvent::KCODE_F2].type = Event::ConsoleReset;
keyTable[StellaEvent::KCODE_F3].type = Event::ConsoleColor;
keyTable[StellaEvent::KCODE_F4].type = Event::ConsoleBlackWhite;
keyTable[StellaEvent::KCODE_F5].type = Event::ConsoleLeftDifficultyA;
keyTable[StellaEvent::KCODE_F6].type = Event::ConsoleLeftDifficultyB;
keyTable[StellaEvent::KCODE_F7].type = Event::ConsoleRightDifficultyA;
keyTable[StellaEvent::KCODE_F8].type = Event::ConsoleRightDifficultyB;
keyTable[StellaEvent::KCODE_F9].type = Event::SaveState;
keyTable[StellaEvent::KCODE_F10].type = Event::ChangeState;
keyTable[StellaEvent::KCODE_F11].type = Event::LoadState;
keyTable[StellaEvent::KCODE_F12].type = Event::TakeSnapshot;
myKeyTable[StellaEvent::KCODE_F1] = Event::ConsoleSelect;
myKeyTable[StellaEvent::KCODE_F2] = Event::ConsoleReset;
myKeyTable[StellaEvent::KCODE_F3] = Event::ConsoleColor;
myKeyTable[StellaEvent::KCODE_F4] = Event::ConsoleBlackWhite;
myKeyTable[StellaEvent::KCODE_F5] = Event::ConsoleLeftDifficultyA;
myKeyTable[StellaEvent::KCODE_F6] = Event::ConsoleLeftDifficultyB;
myKeyTable[StellaEvent::KCODE_F7] = Event::ConsoleRightDifficultyA;
myKeyTable[StellaEvent::KCODE_F8] = Event::ConsoleRightDifficultyB;
myKeyTable[StellaEvent::KCODE_F9] = Event::SaveState;
myKeyTable[StellaEvent::KCODE_F10] = Event::ChangeState;
myKeyTable[StellaEvent::KCODE_F11] = Event::LoadState;
myKeyTable[StellaEvent::KCODE_F12] = Event::TakeSnapshot;
keyTable[StellaEvent::KCODE_F3].message = "Color Mode";
keyTable[StellaEvent::KCODE_F4].message = "BW Mode";
keyTable[StellaEvent::KCODE_F5].message = "Left Difficulty A";
keyTable[StellaEvent::KCODE_F6].message = "Left Difficulty B";
keyTable[StellaEvent::KCODE_F7].message = "Right Difficulty A";
keyTable[StellaEvent::KCODE_F8].message = "Right Difficulty B";
myKeyTable[StellaEvent::KCODE_PAUSE] = Event::Pause;
myKeyTable[StellaEvent::KCODE_ESCAPE] = Event::Quit;
#if 0
DrivingZeroClockwise, DrivingZeroCounterClockwise, DrivingZeroFire,
@ -177,23 +261,30 @@ void EventHandler::setDefaultKeymap()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::setDefaultJoymap()
{
// Left joystick
myJoyTable[StellaEvent::JSTICK_0][StellaEvent::JAXIS_UP] = Event::JoystickZeroUp;
myJoyTable[StellaEvent::JSTICK_0][StellaEvent::JAXIS_DOWN] = Event::JoystickZeroDown;
myJoyTable[StellaEvent::JSTICK_0][StellaEvent::JAXIS_LEFT] = Event::JoystickZeroLeft;
myJoyTable[StellaEvent::JSTICK_0][StellaEvent::JAXIS_RIGHT] = Event::JoystickZeroRight;
myJoyTable[StellaEvent::JSTICK_0][StellaEvent::JBUTTON_0] = Event::JoystickZeroFire;
// Right joystick
myJoyTable[StellaEvent::JSTICK_1][StellaEvent::JAXIS_UP] = Event::JoystickOneUp;
myJoyTable[StellaEvent::JSTICK_1][StellaEvent::JAXIS_DOWN] = Event::JoystickOneDown;
myJoyTable[StellaEvent::JSTICK_1][StellaEvent::JAXIS_LEFT] = Event::JoystickOneLeft;
myJoyTable[StellaEvent::JSTICK_1][StellaEvent::JAXIS_RIGHT] = Event::JoystickOneRight;
myJoyTable[StellaEvent::JSTICK_1][StellaEvent::JBUTTON_0] = Event::JoystickOneFire;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::saveState()
{
ostringstream buf;
string md5 = myConsole->properties().get("Cartridge.MD5");
// string filename = frontend->stateFilename(md5, myCurrentState);
// FIXME !!! This MUST be changed to reflect the frontend/OS being used
string stateDir = "/home/stephena/.stella/state/";
buf << stateDir << md5 << ".st" << myCurrentState;
string filename = buf.str();
/////////////////////////////////////////////////////////
// Do a state save using the System
int result = myConsole->system().saveState(filename, md5);
string md5 = myConsole->properties().get("Cartridge.MD5");
string filename = myConsole->frontend().stateFilename(md5, myCurrentState);
int result = myConsole->system().saveState(filename, md5);
// Print appropriate message
buf.str("");
@ -227,20 +318,12 @@ void EventHandler::changeState()
void EventHandler::loadState()
{
ostringstream buf;
string md5 = myConsole->properties().get("Cartridge.MD5");
// string filename = frontend->stateFilename(md5, myCurrentState);
// FIXME !!! This MUST be changed to reflect the frontend/OS being used
string stateDir = "/home/stephena/.stella/state/";
buf << stateDir << md5 << ".st" << myCurrentState;
string filename = buf.str();
/////////////////////////////////////////////////////////
// Do a state save using the System
int result = myConsole->system().loadState(filename, md5);
string md5 = myConsole->properties().get("Cartridge.MD5");
string filename = myConsole->frontend().stateFilename(md5, myCurrentState);
int result = myConsole->system().loadState(filename, md5);
// Print appropriate message
buf.str("");
if(result == 1)
buf << "State " << myCurrentState << " loaded";
else if(result == 2)

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: EventHandler.hxx,v 1.3 2003-09-04 23:23:06 stephena Exp $
// $Id: EventHandler.hxx,v 1.4 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -40,7 +40,7 @@ class MediaSource;
unchanged to the remap class, where key remapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.3 2003-09-04 23:23:06 stephena Exp $
@version $Id: EventHandler.hxx,v 1.4 2003-09-06 21:17:48 stephena Exp $
*/
class EventHandler
{
@ -65,11 +65,30 @@ class EventHandler
/**
Send a keyboard event to the handler.
@param key The StellaEvent key
@param state The StellaEvent state (pressed or released)
@param code The StellaEvent code
@param state The StellaEvent state
*/
void sendKeyEvent(StellaEvent::KeyCode key, StellaEvent::KeyState state);
void sendKeyEvent(StellaEvent::KeyCode code, Int32 state);
/**
Send a joystick button event to the handler.
@param stick The joystick activated
@param code The StellaEvent joystick code
@param state The StellaEvent state
*/
void sendJoyEvent(StellaEvent::JoyStick stick, StellaEvent::JoyCode code,
Int32 state);
/**
Send an event directly to the event handler.
These events cannot be remapped.
@param type The event
@param value The value for the event
*/
void sendEvent(Event::Type type, Int32 value);
/**
Set the mediasource.
@ -101,14 +120,14 @@ class EventHandler
void loadState();
private:
struct KeyEvent
{
Event::Type type;
string message;
};
// Array of key events
KeyEvent keyTable[StellaEvent::LastKCODE];
Event::Type myKeyTable[StellaEvent::LastKCODE];
// Array of joystick events
Event::Type myJoyTable[StellaEvent::LastJSTICK][StellaEvent::LastJCODE];
// Array of messages for each Event
string myMessageTable[Event::LastType];
// Global Console object
Console* myConsole;
@ -121,6 +140,9 @@ class EventHandler
// Indicates the current state to use for state loading/saving
uInt32 myCurrentState;
// Indicates the current pause status
bool myPauseStatus;
};
#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: Frontend.hxx,v 1.1 2003-09-05 18:02:58 stephena Exp $
// $Id: Frontend.hxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef FRONTEND_HXX
@ -27,7 +27,7 @@ class Console;
This class provides an interface for accessing frontend specific data.
@author Stephen Anthony
@version $Id: Frontend.hxx,v 1.1 2003-09-05 18:02:58 stephena Exp $
@version $Id: Frontend.hxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
*/
class Frontend
{
@ -53,13 +53,27 @@ class Frontend
This method should be called when the emulation core receives
a QUIT event.
*/
virtual void quit() = 0;
virtual void setQuitEvent() = 0;
/**
This method determines whether the QUIT event has been received.
@return Boolean representing whether a QUIT event has been received
*/
virtual bool quit() = 0;
/**
This method should be called at when the emulation core receives
a PAUSE event.
*/
virtual void pause(bool status) = 0;
virtual void setPauseEvent() = 0;
/**
This method determines whether the PAUSE event has been received.
@return Boolean representing whether a PAUSE event has been received
*/
virtual bool pause() = 0;
/**
This method should be called to get the filename of a state file
@ -67,7 +81,7 @@ class Frontend
@return String representing the full path of the state filename.
*/
virtual string& stateFilename(string& md5, uInt32 state) = 0;
virtual string stateFilename(string& md5, uInt32 state) = 0;
/**
This method should be called to get the filename of a snapshot
@ -75,7 +89,7 @@ class Frontend
@return String representing the full path of the snapshot filename.
*/
virtual string& snapshotFilename(string& md5, uInt32 state) = 0;
virtual string snapshotFilename(string& md5, uInt32 state) = 0;
/**
This method should be called to get the filename of the users
@ -83,7 +97,7 @@ class Frontend
@return String representing the full path of the user properties filename.
*/
virtual string& userPropertiesFilename() = 0;
virtual string userPropertiesFilename() = 0;
/**
This method should be called to get the filename of the system
@ -91,7 +105,7 @@ class Frontend
@return String representing the full path of the system properties filename.
*/
virtual string& systemPropertiesFilename() = 0;
virtual string systemPropertiesFilename() = 0;
/**
This method should be called to get the filename of the users
@ -99,7 +113,7 @@ class Frontend
@return String representing the full path of the users config filename.
*/
virtual string& userConfigFilename() = 0;
virtual string userConfigFilename() = 0;
/**
This method should be called to get the filename of the system
@ -107,7 +121,7 @@ class Frontend
@return String representing the full path of the system config filename.
*/
virtual string& systemConfigFilename() = 0;
virtual string systemConfigFilename() = 0;
private:

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: StellaEvent.hxx,v 1.1 2003-09-03 20:10:58 stephena Exp $
// $Id: StellaEvent.hxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef STELLAEVENT_HXX
@ -28,13 +28,13 @@
by the frontends directly.
@author Stephen Anthony
@version $Id: StellaEvent.hxx,v 1.1 2003-09-03 20:10:58 stephena Exp $
@version $Id: StellaEvent.hxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
*/
class StellaEvent
{
public:
/**
Enumeration of keyboard keycodes and states
Enumeration of keyboard keycodes
*/
enum KeyCode
{
@ -64,10 +64,21 @@ class StellaEvent
LastKCODE
};
enum KeyState
/**
Enumeration of joystick codes and states
*/
enum JoyStick
{
KSTATE_RELEASED, KSTATE_PRESSED,
LastKSTATE
JSTICK_0, JSTICK_1, JSTICK_2, JSTICK_3,
LastJSTICK
};
enum JoyCode
{
JAXIS_UP, JAXIS_DOWN, JAXIS_LEFT, JAXIS_RIGHT,
JBUTTON_0, JBUTTON_1, JBUTTON_2, JBUTTON_3, JBUTTON_4,
JBUTTON_5, JBUTTON_6, JBUTTON_7, JBUTTON_8, JBUTTON_9,
LastJCODE
};
};

View File

@ -13,11 +13,15 @@
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: FrontendUNIX.cxx,v 1.1 2003-09-05 18:02:58 stephena Exp $
// $Id: FrontendUNIX.cxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef FRONTEND_UNIX_HXX
#define FRONTEND_UNIX_HXX
#include <cstdlib>
#include <sstream>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "bspf.hxx"
#include "Console.hxx"
@ -25,9 +29,11 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrontendUNIX::FrontendUNIX()
: myPauseIndicator(false),
myQuitIndicator(false)
{
myHomeDir = getenv("HOME");
string path = homeDir + "/.stella";
string path = myHomeDir + "/.stella";
if(access(path.c_str(), R_OK|W_OK|X_OK) != 0 )
mkdir(path.c_str(), 0777);
@ -41,8 +47,8 @@ FrontendUNIX::FrontendUNIX()
myHomeRCFile = myHomeDir + "/.stella/stellarc";
mySystemRCFile = "/etc/stellarc";
mySnapshotFilename = "";
myStateFilename = "";
mySnapshotFile = "";
myStateFile = "";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -57,47 +63,65 @@ void FrontendUNIX::setConsole(Console* console)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrontendUNIX::quit()
void FrontendUNIX::setQuitEvent()
{
theQuitIndicator = true;
myQuitIndicator = true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrontendUNIX::pause(bool status)
bool FrontendUNIX::quit()
{
thePauseIndicator = status;
return myQuitIndicator;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string& FrontendUNIX::stateFilename(string& md5, uInt32 state)
void FrontendUNIX::setPauseEvent()
{
myPauseIndicator = !myPauseIndicator;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string& FrontendUNIX::snapshotFilename(string& md5, uInt32 state)
bool FrontendUNIX::pause()
{
return myPauseIndicator;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string& FrontendUNIX::userPropertiesFilename()
string FrontendUNIX::stateFilename(string& md5, uInt32 state)
{
ostringstream buf;
buf << myStateDir << md5 << ".st" << state;
myStateFile = buf.str();
return myStateFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrontendUNIX::snapshotFilename(string& md5, uInt32 state)
{
return mySnapshotFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string FrontendUNIX::userPropertiesFilename()
{
return myHomePropertiesFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string& FrontendUNIX::systemPropertiesFilename()
string FrontendUNIX::systemPropertiesFilename()
{
return mySystemPropertiesFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string& FrontendUNIX::userConfigFilename()
string FrontendUNIX::userConfigFilename()
{
return myHomeRCFile;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
string& FrontendUNIX::systemConfigFilename()
string FrontendUNIX::systemConfigFilename()
{
return mySystemRCFile;
}

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: FrontendUNIX.hxx,v 1.1 2003-09-05 18:02:58 stephena Exp $
// $Id: FrontendUNIX.hxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#ifndef FRONTEND_UNIX_HXX
@ -29,16 +29,13 @@ class Console;
and events.
@author Stephen Anthony
@version $Id: FrontendUNIX.hxx,v 1.1 2003-09-05 18:02:58 stephena Exp $
@version $Id: FrontendUNIX.hxx,v 1.2 2003-09-06 21:17:48 stephena Exp $
*/
class FrontendUNIX : public Frontend
{
public:
/**
Create a new UNIX frontend
// @param console The console the TIA is associated with
// @param sampleRate The sample rate to create audio samples at
*/
FrontendUNIX();
@ -56,12 +53,22 @@ class FrontendUNIX : public Frontend
/**
Called when the emulation core receives a QUIT event.
*/
virtual void quit();
virtual void setQuitEvent();
/**
Check whether a QUIT event has been received.
*/
virtual bool quit();
/**
Called when the emulation core receives a PAUSE event.
*/
virtual void pause(bool status);
virtual void setPauseEvent();
/**
Check whether a PAUSE event has been received.
*/
virtual bool pause();
/**
Returns the UNIX filename representing a state file.
@ -70,7 +77,7 @@ class FrontendUNIX : public Frontend
@param state The state number to use as part of the filename.
@return The full path and filename of the state file.
*/
virtual string& stateFilename(string& md5, uInt32 state);
virtual string stateFilename(string& md5, uInt32 state);
/**
Returns the UNIX filename representing a state file.
@ -79,41 +86,47 @@ class FrontendUNIX : public Frontend
@param state The state number to use as part of the filename.
@return The full path and filename of the snapshot file.
*/
virtual string& snapshotFilename(string& md5, uInt32 state);
virtual string snapshotFilename(string& md5, uInt32 state);
/**
Returns the UNIX filename representing a users properties file.
@return The full path and filename of the user properties file.
*/
virtual string& userPropertiesFilename();
virtual string userPropertiesFilename();
/**
Returns the UNIX filename representing a system properties file.
@return The full path and filename of the system properties file.
*/
virtual string& systemPropertiesFilename();
virtual string systemPropertiesFilename();
/**
Returns the UNIX filename representing a users config file.
@return The full path and filename of the user config file.
*/
virtual string& userConfigFilename();
virtual string userConfigFilename();
/**
Returns the UNIX filename representing a system config file.
@return The full path and filename of the system config file.
*/
virtual string& systemConfigFilename();
virtual string systemConfigFilename();
public:
bool theQuitIndicator;
bool thePauseIndicator
/**
Returns the UNIX filename representing a system config file.
@return The full path and filename of the system config file.
*/
string userHomeDir() { return myHomeDir; }
private:
bool myPauseIndicator;
bool myQuitIndicator;
string myHomeDir;
string myStateDir;

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.44 2003-09-04 23:23:06 stephena Exp $
// $Id: mainSDL.cxx,v 1.45 2003-09-06 21:17:48 stephena Exp $
//============================================================================
#include <fstream>
@ -22,11 +22,8 @@
#include <string>
#include <algorithm>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <SDL.h>
#include <SDL_syswm.h>
@ -36,11 +33,12 @@
#include "Event.hxx"
#include "StellaEvent.hxx"
#include "EventHandler.hxx"
#include "Frontend.hxx"
#include "MediaSrc.hxx"
#include "PropsSet.hxx"
#include "Sound.hxx"
#include "RectList.hxx"
#include "Settings.hxx"
#include "RectList.hxx"
#ifdef SOUND_ALSA
#include "SoundALSA.hxx"
@ -58,6 +56,10 @@
#include "Snapshot.hxx"
#endif
//#ifdef UNIX
#include "FrontendUNIX.hxx"
//#endif
// Hack for SDL < 1.2.0
#ifndef SDL_ENABLE
#define SDL_ENABLE 1
@ -66,34 +68,20 @@
#define SDL_DISABLE 0
#endif
#define MESSAGE_INTERVAL 2
// function prototypes
// FIXME the following will be placed in a Display class eventually ...
static bool setupDisplay();
static bool setupJoystick();
static bool createScreen();
static void recalculate8BitPalette();
static void setupPalette();
static void cleanup();
static bool setupDirs();
static void updateDisplay(MediaSource& mediaSource);
static void handleEvents();
static void doQuit();
static void resizeWindow(int mode);
static void centerWindow();
static void showCursor(bool show);
static void grabMouse(bool grab);
static void toggleFullscreen();
static void takeSnapshot();
static void togglePause();
static uInt32 maxWindowSizeForScreen();
static uInt32 getTicks();
static bool setupProperties(PropertiesSet& set);
static void handleRCFile();
static void usage();
// Globals for the SDL stuff
static SDL_Surface* screen = (SDL_Surface*) NULL;
@ -108,6 +96,19 @@ static SDL_SysWMinfo info;
static int sdlflags;
static RectList* rectList = (RectList*) NULL;
static uInt32 theWidth, theHeight, theMaxWindowSize, theWindowSize;
////////////////////////////////////////////
static void cleanup();
static bool setupJoystick();
static void handleEvents();
static void takeSnapshot();
static uInt32 getTicks();
static bool setupProperties(PropertiesSet& set);
static void handleRCFile();
static void usage();
static string theSnapShotDir, theSnapShotName;
#ifdef HAVE_JOYSTICK
@ -119,6 +120,39 @@ static string theSnapShotDir, theSnapShotName;
static Snapshot* snapshot;
#endif
// FIXME - these are going to disappear
//static Event theEvent;
// Pointer to the console object or the null pointer
static Console* theConsole = (Console*) NULL;
// Pointer to the sound object or the null pointer
static Sound* sound = (Sound*) NULL;
// Pointer to the frontend object or the null pointer
static Frontend* frontend = (Frontend*) NULL;
// Indicates if the user wants to quit
//static bool theQuitIndicator = false;
// Indicates if the emulator should be paused
//static bool thePauseIndicator = false;
// Indicates if the mouse should be grabbed
static bool theGrabMouseIndicator = false;
// Indicates if the mouse cursor should be hidden
static bool theHideCursorIndicator = false;
// Indicates if the entire frame should be redrawn
static bool theRedrawEntireFrameIndicator = true;
// Indicates whether the game is currently in fullscreen
static bool isFullscreen = false;
// Indicates whether the window is currently centered
static bool isCentered = false;
struct Switches
{
SDLKey scanCode;
@ -126,7 +160,7 @@ struct Switches
};
// Place the most used keys first to speed up access
static Switches list[] = {
static Switches keyList[] = {
{ SDLK_F1, StellaEvent::KCODE_F1 },
{ SDLK_F2, StellaEvent::KCODE_F2 },
{ SDLK_F3, StellaEvent::KCODE_F3 },
@ -222,43 +256,18 @@ static Switches list[] = {
{ SDLK_RIGHTBRACKET,StellaEvent::KCODE_RIGHTBRACKET}
};
static Event theEvent;
static Event keyboardEvent;
// Lookup table for joystick numbers and events
StellaEvent::JoyStick joyList[StellaEvent::LastJSTICK] = {
StellaEvent::JSTICK_0, StellaEvent::JSTICK_1,
StellaEvent::JSTICK_2, StellaEvent::JSTICK_3
};
// Pointer to the console object or the null pointer
static Console* theConsole = (Console*) NULL;
// Pointer to the sound object or the null pointer
static Sound* sound = (Sound*) NULL;
// Indicates if the user wants to quit
static bool theQuitIndicator = false;
// Indicates if the emulator should be paused
static bool thePauseIndicator = false;
// Indicates if the mouse should be grabbed
static bool theGrabMouseIndicator = false;
// Indicates if the mouse cursor should be hidden
static bool theHideCursorIndicator = false;
// Indicates if the entire frame should be redrawn
static bool theRedrawEntireFrameIndicator = true;
// Indicates whether the game is currently in fullscreen
static bool isFullscreen = false;
// Indicates whether the window is currently centered
static bool isCentered = false;
// The locations for various required files
static string homeDir;
static string stateDir;
static string homePropertiesFile;
static string systemPropertiesFile;
static string homeRCFile;
static string systemRCFile;
StellaEvent::JoyCode joyButtonList[StellaEvent::LastJCODE] = {
StellaEvent::JBUTTON_0, StellaEvent::JBUTTON_1, StellaEvent::JBUTTON_2,
StellaEvent::JBUTTON_3, StellaEvent::JBUTTON_4, StellaEvent::JBUTTON_5,
StellaEvent::JBUTTON_6, StellaEvent::JBUTTON_7, StellaEvent::JBUTTON_8,
StellaEvent::JBUTTON_9
};
/**
@ -312,7 +321,8 @@ bool setupDisplay()
theWindowSize = 2;
}
#ifdef HAVE_PNG
#if 0
//#ifdef HAVE_PNG
// Take care of the snapshot stuff.
snapshot = new Snapshot();
@ -498,7 +508,7 @@ void setupPalette()
// Make the palette be 75% as bright if pause is selected
float shade = 1.0;
if(thePauseIndicator)
if(frontend->pause())
shade = 0.75;
const uInt32* gamePalette = theConsole->mediaSource().palette();
@ -531,15 +541,6 @@ void setupPalette()
}
/**
This routine is called when the program is about to quit.
*/
void doQuit()
{
theQuitIndicator = true;
}
/**
This routine is called when the user wants to resize the window.
A '1' argument indicates that the window should increase in size, while '0'
@ -657,28 +658,6 @@ void toggleFullscreen()
}
/**
Toggles pausing of the emulator
*/
void togglePause()
{
if(thePauseIndicator) // emulator is already paused so continue
{
thePauseIndicator = false;
}
else // we want to pause the game
{
thePauseIndicator = true;
}
// Pause the console
theConsole->mediaSource().pause(thePauseIndicator);
// Show a different palette depending on pause state
setupPalette();
}
/**
Shows or hides the cursor based on the given boolean value.
*/
@ -871,11 +850,8 @@ void updateDisplay(MediaSource& mediaSource)
void handleEvents()
{
SDL_Event event;
Uint8 axis;
Uint8 button;
Sint16 value;
Uint8 type;
Uint8 state;
SDLKey key;
SDLMod mod;
@ -889,11 +865,7 @@ void handleEvents()
mod = event.key.keysym.mod;
type = event.type;
if(key == SDLK_ESCAPE)
{
doQuit();
}
else if(key == SDLK_EQUALS)
if(key == SDLK_EQUALS)
{
resizeWindow(1);
}
@ -901,7 +873,7 @@ void handleEvents()
{
resizeWindow(0);
}
else if(key == SDLK_RETURN && mod & KMOD_ALT)
else if((mod & KMOD_ALT) && key == SDLK_RETURN)
{
toggleFullscreen();
}
@ -909,11 +881,7 @@ void handleEvents()
{
takeSnapshot();
}
else if(key == SDLK_PAUSE)
{
togglePause();
}
else if(key == SDLK_g)
else if((mod & KMOD_CTRL) && key == SDLK_g)
{
// don't change grabmouse in fullscreen mode
if(!isFullscreen)
@ -922,7 +890,7 @@ void handleEvents()
grabMouse(theGrabMouseIndicator);
}
}
else if(key == SDLK_h)
else if((mod & KMOD_CTRL) && key == SDLK_h)
{
// don't change hidecursor in fullscreen mode
if(!isFullscreen)
@ -932,15 +900,12 @@ void handleEvents()
}
}
#ifdef DEVELOPER_SUPPORT
if(key == SDLK_f) // Alt-f switches between NTSC and PAL
else if((mod & KMOD_ALT) && key == SDLK_f) // Alt-f switches between NTSC and PAL
{
if(mod & KMOD_ALT)
{
theConsole->toggleFormat();
theConsole->toggleFormat();
// update the palette
setupPalette();
}
// update the palette
setupPalette();
}
else if(key == SDLK_END) // End decreases XStart
@ -983,55 +948,47 @@ void handleEvents()
// Make sure changes to the properties are reflected onscreen
resizeWindow(-1);
}
else if(key == SDLK_s) // Alt-s saves properties to a file
else if((mod & KMOD_ALT) && key == SDLK_s) // Alt-s saves properties to a file
{
if(mod & KMOD_ALT)
if(theConsole->settings().theMergePropertiesFlag) // Attempt to merge with propertiesSet
{
if(theConsole->settings().theMergePropertiesFlag) // Attempt to merge with propertiesSet
{
theConsole->saveProperties(homePropertiesFile, true);
}
else // Save to file in home directory
{
string newPropertiesFile = homeDir + "/" + \
theConsole->properties().get("Cartridge.Name") + ".pro";
replace(newPropertiesFile.begin(), newPropertiesFile.end(), ' ', '_');
theConsole->saveProperties(newPropertiesFile);
}
theConsole->saveProperties(homePropertiesFile, true);
}
else // Save to file in home directory
{
string newPropertiesFile = homeDir + "/" + \
theConsole->properties().get("Cartridge.Name") + ".pro";
replace(newPropertiesFile.begin(), newPropertiesFile.end(), ' ', '_');
theConsole->saveProperties(newPropertiesFile);
}
}
#endif
else // check all the other keys
{
for(unsigned int i = 0; i < sizeof(list) / sizeof(Switches); ++i)
for(unsigned int i = 0; i < sizeof(keyList) / sizeof(Switches); ++i)
{
if(list[i].scanCode == key)
{
theConsole->eventHandler().sendKeyEvent(list[i].keyCode,
StellaEvent::KSTATE_PRESSED);
}
if(keyList[i].scanCode == key)
theConsole->eventHandler().sendKeyEvent(keyList[i].keyCode, 1);
}
}
}
else if(event.type == SDL_KEYUP)
{
key = event.key.keysym.sym;
key = event.key.keysym.sym;
type = event.type;
for(unsigned int i = 0; i < sizeof(list) / sizeof(Switches); ++i)
for(unsigned int i = 0; i < sizeof(keyList) / sizeof(Switches); ++i)
{
if(list[i].scanCode == key)
{
theConsole->eventHandler().sendKeyEvent(list[i].keyCode,
StellaEvent::KSTATE_RELEASED);
}
if(keyList[i].scanCode == key)
theConsole->eventHandler().sendKeyEvent(keyList[i].keyCode, 0);
}
}
else if(event.type == SDL_MOUSEMOTION)
{
int resistance = 0, x = 0;
float fudgeFactor = 1000000.0;
Int32 resistance = 0, x = 0;
Int32 width = theWidth * theWindowSize * 2;
Event::Type type;
// Grabmouse and hidecursor introduce some lag into the mouse movement,
// so we need to fudge the numbers a bit
@ -1056,117 +1013,114 @@ void handleEvents()
// Now, set the event of the correct paddle to the calculated resistance
if(theConsole->settings().thePaddleMode == 0)
theEvent.set(Event::PaddleZeroResistance, resistance);
type = Event::PaddleZeroResistance;
else if(theConsole->settings().thePaddleMode == 1)
theEvent.set(Event::PaddleOneResistance, resistance);
type = Event::PaddleOneResistance;
else if(theConsole->settings().thePaddleMode == 2)
theEvent.set(Event::PaddleTwoResistance, resistance);
type = Event::PaddleTwoResistance;
else if(theConsole->settings().thePaddleMode == 3)
theEvent.set(Event::PaddleThreeResistance, resistance);
type = Event::PaddleThreeResistance;
theConsole->eventHandler().sendEvent(type, resistance);
}
else if(event.type == SDL_MOUSEBUTTONDOWN)
else if(event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP)
{
Event::Type type;
Int32 value;
if(event.type == SDL_MOUSEBUTTONDOWN)
value = 1;
else
value = 0;
if(theConsole->settings().thePaddleMode == 0)
theEvent.set(Event::PaddleZeroFire, 1);
type = Event::PaddleZeroFire;
else if(theConsole->settings().thePaddleMode == 1)
theEvent.set(Event::PaddleOneFire, 1);
type = Event::PaddleOneFire;
else if(theConsole->settings().thePaddleMode == 2)
theEvent.set(Event::PaddleTwoFire, 1);
type = Event::PaddleTwoFire;
else if(theConsole->settings().thePaddleMode == 3)
theEvent.set(Event::PaddleThreeFire, 1);
}
else if(event.type == SDL_MOUSEBUTTONUP)
{
if(theConsole->settings().thePaddleMode == 0)
theEvent.set(Event::PaddleZeroFire, 0);
else if(theConsole->settings().thePaddleMode == 1)
theEvent.set(Event::PaddleOneFire, 0);
else if(theConsole->settings().thePaddleMode == 2)
theEvent.set(Event::PaddleTwoFire, 0);
else if(theConsole->settings().thePaddleMode == 3)
theEvent.set(Event::PaddleThreeFire, 0);
type = Event::PaddleThreeFire;
theConsole->eventHandler().sendEvent(type, value);
}
else if(event.type == SDL_ACTIVEEVENT)
{
if((event.active.state & SDL_APPACTIVE) && (event.active.gain == 0))
{
if(!thePauseIndicator)
if(!frontend->pause())
{
togglePause();
frontend->setPauseEvent();
}
}
}
else if(event.type == SDL_QUIT)
{
doQuit();
frontend->setQuitEvent();
}
#ifdef HAVE_JOYSTICK
// Read joystick events and modify event states
if(theLeftJoystick)
StellaEvent::JoyStick stick;
StellaEvent::JoyCode code;
Int32 state;
Uint8 axis;
Sint16 value;
if(event.jbutton.which >= StellaEvent::LastJSTICK)
return;
stick = joyList[event.jbutton.which];
if((event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP))
{
if(((event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP))
&& (event.jbutton.which == 0))
{
button = event.jbutton.button;
state = event.jbutton.state;
state = (state == SDL_PRESSED) ? 1 : 0;
if(event.jbutton.button >= StellaEvent::LastJCODE)
return;
if(button == 0) // fire button
{
theEvent.set(Event::JoystickZeroFire, state ?
1 : keyboardEvent.get(Event::JoystickZeroFire));
code = joyButtonList[event.jbutton.button];
state = event.jbutton.state == SDL_PRESSED ? 1 : 0;
// If we're using real paddles then set paddle event as well
if(theConsole->settings().thePaddleMode == 4)
theEvent.set(Event::PaddleZeroFire, state);
}
else if(button == 1) // booster button
{
theEvent.set(Event::BoosterGripZeroTrigger, state ?
1 : keyboardEvent.get(Event::BoosterGripZeroTrigger));
// If we're using real paddles then set paddle event as well
if(theConsole->settings().thePaddleMode == 4)
theEvent.set(Event::PaddleOneFire, state);
}
}
else if((event.type == SDL_JOYAXISMOTION) && (event.jaxis.which == 0))
{
axis = event.jaxis.axis;
value = event.jaxis.value;
if(axis == 0) // x-axis
{
theEvent.set(Event::JoystickZeroLeft, (value < -16384) ?
1 : keyboardEvent.get(Event::JoystickZeroLeft));
theEvent.set(Event::JoystickZeroRight, (value > 16384) ?
1 : keyboardEvent.get(Event::JoystickZeroRight));
// If we're using real paddles then set paddle events as well
if(theConsole->settings().thePaddleMode == 4)
{
uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536);
theEvent.set(Event::PaddleZeroResistance, r);
}
}
else if(axis == 1) // y-axis
{
theEvent.set(Event::JoystickZeroUp, (value < -16384) ?
1 : keyboardEvent.get(Event::JoystickZeroUp));
theEvent.set(Event::JoystickZeroDown, (value > 16384) ?
1 : keyboardEvent.get(Event::JoystickZeroDown));
// If we're using real paddles then set paddle events as well
if(theConsole->settings().thePaddleMode == 4)
{
uInt32 r = (uInt32)((1.0E6L * (value + 32767L)) / 65536);
theEvent.set(Event::PaddleOneResistance, r);
}
}
}
theConsole->eventHandler().sendJoyEvent(stick, code, state);
}
else if(event.type == SDL_JOYAXISMOTION)
{
code = StellaEvent::LastJCODE;
state = 1;
axis = event.jaxis.axis;
value = event.jaxis.value;
if(axis == 0) // x-axis
{
if(value < -16384)
code = StellaEvent::JAXIS_LEFT;
else if(value > 16384)
code = StellaEvent::JAXIS_RIGHT;
else
{
theConsole->eventHandler().sendJoyEvent(stick, StellaEvent::JAXIS_LEFT, 0);
theConsole->eventHandler().sendJoyEvent(stick, StellaEvent::JAXIS_RIGHT, 0);
return;
}
}
else if(axis == 1) // y-axis
{
if(value < -16384)
code = StellaEvent::JAXIS_UP;
else if(value > 16384)
code = StellaEvent::JAXIS_DOWN;
else
{
theConsole->eventHandler().sendJoyEvent(stick, StellaEvent::JAXIS_UP, 0);
theConsole->eventHandler().sendJoyEvent(stick, StellaEvent::JAXIS_DOWN, 0);
return;
}
}
theConsole->eventHandler().sendJoyEvent(stick, code, state);
}
/*
if(theRightJoystick)
{
if(((event.type == SDL_JOYBUTTONDOWN) || (event.type == SDL_JOYBUTTONUP))
@ -1230,6 +1184,7 @@ void handleEvents()
}
}
}
*/
#endif
}
}
@ -1448,30 +1403,22 @@ bool setupProperties(PropertiesSet& set, Settings& settings)
#endif
// Check to see if the user has specified an alternate .pro file.
// If it exists, use it.
if(settings.theAlternateProFile != "")
{
if(access(settings.theAlternateProFile.c_str(), R_OK) == 0)
{
set.load(settings.theAlternateProFile, &Console::defaultProperties(), useMemList);
return true;
}
else
{
cerr << "ERROR: Couldn't find \"" << settings.theAlternateProFile
<< "\" properties file." << endl;
return false;
}
}
if(access(homePropertiesFile.c_str(), R_OK) == 0)
{
set.load(homePropertiesFile, &Console::defaultProperties(), useMemList);
set.load(settings.theAlternateProFile, &Console::defaultProperties(), useMemList);
return true;
}
else if(access(systemPropertiesFile.c_str(), R_OK) == 0)
if(frontend->userPropertiesFilename() != "")
{
set.load(systemPropertiesFile, &Console::defaultProperties(), useMemList);
set.load(frontend->userPropertiesFilename(),
&Console::defaultProperties(), useMemList);
return true;
}
else if(frontend->systemPropertiesFilename() != "")
{
set.load(frontend->systemPropertiesFilename(),
&Console::defaultProperties(), useMemList);
return true;
}
else
@ -1487,6 +1434,9 @@ bool setupProperties(PropertiesSet& set, Settings& settings)
*/
void cleanup()
{
if(frontend)
delete frontend;
if(theConsole)
delete theConsole;
@ -1518,58 +1468,27 @@ void cleanup()
}
/**
Creates some directories under $HOME.
Required directories are $HOME/.stella and $HOME/.stella/state
Also sets up various locations for properties files, etc.
This must be called before any other function.
*/
bool setupDirs()
{
homeDir = getenv("HOME");
string path = homeDir + "/.stella";
if(access(path.c_str(), R_OK|W_OK|X_OK) != 0 )
{
if(mkdir(path.c_str(), 0777) != 0)
return false;
}
stateDir = homeDir + "/.stella/state/";
if(access(stateDir.c_str(), R_OK|W_OK|X_OK) != 0 )
{
if(mkdir(stateDir.c_str(), 0777) != 0)
return false;
}
homePropertiesFile = homeDir + "/.stella/stella.pro";
systemPropertiesFile = "/etc/stella.pro";
homeRCFile = homeDir + "/.stella/stellarc";
systemRCFile = "/etc/stellarc";
return true;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int main(int argc, char* argv[])
{
// First set up the directories where Stella will find RC and state files
if(!setupDirs())
// First set up the frontend to communicate with the emulation core
//#ifdef UNIX
frontend = new FrontendUNIX();
//#endif
if(!frontend)
{
cerr << "ERROR: Couldn't set up config directories.\n";
cerr << "ERROR: Couldn't set up the frontend.\n";
cleanup();
return 0;
}
// Create some settings for the emulator
string infile = "";
string outfile = homeRCFile;
if(access(homeRCFile.c_str(), R_OK) == 0 )
infile = homeRCFile;
else if(access(systemRCFile.c_str(), R_OK) == 0 )
infile = systemRCFile;
string outfile = frontend->userConfigFilename();
if(frontend->userConfigFilename() != "")
infile = frontend->userConfigFilename();
else if(frontend->systemConfigFilename() != "")
infile = frontend->systemConfigFilename();
Settings settings(infile, outfile);
@ -1654,11 +1573,11 @@ int main(int argc, char* argv[])
// Create the 2600 game console for users or developers
#ifdef DEVELOPER_SUPPORT
theConsole = new Console(image, size, filename,
settings, propertiesSet, sound->getSampleRate(),
settings, propertiesSet, *frontend, sound->getSampleRate(),
&settings.userDefinedProperties);
#else
theConsole = new Console(image, size, filename,
settings, propertiesSet, sound->getSampleRate());
settings, propertiesSet, *frontend, sound->getSampleRate());
#endif
// Free the image since we don't need it any longer
@ -1695,7 +1614,7 @@ int main(int argc, char* argv[])
for(;;)
{
// Exit if the user wants to quit
if(theQuitIndicator)
if(frontend->quit())
{
break;
}
@ -1703,7 +1622,7 @@ int main(int argc, char* argv[])
// Call handleEvents here to see if user pressed pause
startTime = getTicks();
handleEvents();
if(thePauseIndicator)
if(frontend->pause())
{
updateDisplay(theConsole->mediaSource());
SDL_Delay(10);
@ -1741,14 +1660,14 @@ int main(int argc, char* argv[])
for(;;)
{
// Exit if the user wants to quit
if(theQuitIndicator)
if(frontend->quit())
{
break;
}
startTime = getTicks();
handleEvents();
if(!thePauseIndicator)
if(!frontend->pause())
{
theConsole->mediaSource().update();
sound->updateSound(theConsole->mediaSource());