Yet more changes to the user interface. Its beginning to come together.

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@191 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2003-09-26 17:35:05 +00:00
parent 267a9edf25
commit dbe02b2af4
6 changed files with 168 additions and 289 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: EventHandler.cxx,v 1.11 2003-09-26 00:32:00 stephena Exp $
// $Id: EventHandler.cxx,v 1.12 2003-09-26 17:35:05 stephena Exp $
//============================================================================
#include <algorithm>
@ -37,10 +37,7 @@
EventHandler::EventHandler(Console* console)
: myConsole(console),
myCurrentState(0),
myMenuStatus(false),
myReturnPressedFlag(false),
myRemapModeFlag(false),
myEventSelectedFlag(false)
myMenuStatus(false)
{
Int32 i;
@ -94,73 +91,15 @@ void EventHandler::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
if(key == StellaEvent::KCODE_TAB && state == 1)
{
myMenuStatus = !myMenuStatus;
if(myMenuStatus)
{
myConsole->gui().showMenu(UserInterface::MENU_MAIN);
}
else
{
myConsole->gui().showMenu(UserInterface::MENU_NONE);
myReturnPressedFlag = myRemapModeFlag = myEventSelectedFlag = false;
}
myConsole->gui().showMainMenu(myMenuStatus);
return;
}
// Determine where the event should be sent
if(myMenuStatus && state == 1)
{
if(key == StellaEvent::KCODE_RETURN)
myReturnPressedFlag = true;
processMenuEvent(key);
}
if(myMenuStatus)
myConsole->gui().sendKeyEvent(key, state);
else
{
sendEvent(myKeyTable[key], state);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::processMenuEvent(StellaEvent::KeyCode key)
{
if(myRemapModeFlag && myEventSelectedFlag)
{
if(key == StellaEvent::KCODE_ESCAPE)
// associate nothing with the selected event
cerr << "delete binding for " << mySelectedEvent << endl;
else
// associate this stellaevent with the selected event
cerr << "add binding " << key << " for " << mySelectedEvent << endl;
myReturnPressedFlag = myEventSelectedFlag = false;
}
else if(myReturnPressedFlag && myRemapModeFlag)
{
cerr << "return pressed while in remap mode\n";
mySelectedEvent = Event::ConsoleSelect; // FIXME - get from gui() which event is currently selected
myEventSelectedFlag = true;
myReturnPressedFlag = false;
}
else if(myReturnPressedFlag)
{
UserInterface::MenuType menu = myConsole->gui().currentSelectedMenu();
if(menu == UserInterface::MENU_REMAP)
{
myConsole->gui().showMenu(UserInterface::MENU_REMAP);
myRemapModeFlag = true;
}
else if(menu == UserInterface::MENU_INFO)
{
myConsole->gui().showMenu(UserInterface::MENU_INFO);
}
myReturnPressedFlag = false;
}
else if(key == StellaEvent::KCODE_UP)
myConsole->gui().moveCursorUp();
else if(key == StellaEvent::KCODE_DOWN)
myConsole->gui().moveCursorDown();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -168,14 +107,10 @@ void EventHandler::sendJoyEvent(StellaEvent::JoyStick stick,
StellaEvent::JoyCode code, Int32 state)
{
// Determine where the event should be sent
if(myMenuStatus && state == 1)
{
cerr << "send joy event to remap class\nstick = " << stick << ", button = " << code << endl;
}
if(myMenuStatus)
myConsole->gui().sendJoyEvent(stick, code, state);
else
{
sendEvent(myJoyTable[stick][code], state);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.7 2003-09-25 16:20:34 stephena Exp $
// $Id: EventHandler.hxx,v 1.8 2003-09-26 17:35:05 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -33,14 +33,15 @@ class MediaSource;
The frontends will send translated events here, and the handler will
check to see what the current 'mode' is. For now, the modes can be
normal and remap.
normal and menu mode.
If in normal mode, events received from the frontends are remapped and
sent to the emulation core. If in remap mode, the events are sent
unchanged to the remap class, where key remapping can take place.
sent to the emulation core. If in menu mode, the events are sent
unchanged to the user interface, where (among other things) changing key
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.7 2003-09-25 16:20:34 stephena Exp $
@version $Id: EventHandler.hxx,v 1.8 2003-09-26 17:35:05 stephena Exp $
*/
class EventHandler
{
@ -125,7 +126,6 @@ class EventHandler
void takeSnapshot();
void processMenuEvent(StellaEvent::KeyCode key);
// void processMenuEvent(StellaEvent::JoyStick stick, StellaEvent::JoyCode code);
private:
// Array of key events
@ -158,14 +158,8 @@ class EventHandler
// The current joymap in string form
string myJoymapString;
// Indicates that a menu should be entered
// Indicates that the main menu is being entered
bool myMenuStatus;
// These are used for the state machine that processes menu events
bool myReturnPressedFlag, myRemapModeFlag, myEventSelectedFlag;
//
Event::Type mySelectedEvent;
};
#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: TIA.cxx,v 1.21 2003-09-26 00:32:00 stephena Exp $
// $Id: TIA.cxx,v 1.22 2003-09-26 17:35:05 stephena Exp $
//============================================================================
#include <cassert>
@ -594,115 +594,6 @@ bool TIA::pause(bool state)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void TIA::drawMessageText()
{
// Set up the correct coordinates to draw the surrounding box
uInt32 xBoxOffSet = 2 + myFrameXStart;
uInt32 yBoxOffSet = myFrameHeight - 18;
uInt32 boxToTextXOffSet = 2;
uInt32 boxToTextYOffSet = 4;
// Set up the correct coordinates to print the message
uInt32 xTextOffSet = xBoxOffSet + boxToTextXOffSet;
uInt32 yTextOffSet = yBoxOffSet + boxToTextYOffSet;
// 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 and background
uInt8 fontColor, backColor;
// Palette index depends on whether we are in NTSC or PAL mode
if(myConsole.properties().get("Display.Format") == "PAL")
{
fontColor = 10;
backColor = 0;
}
else
{
fontColor = 10;
backColor = 0;
}
// Clip the length if its wider than the screen
uInt8 length = myMessageText.length();
if(((length * 5) + xTextOffSet) >= myFrameWidth)
length = (myFrameWidth - xTextOffSet) / 5;
// Reset the offsets to center the message
uInt32 boxWidth = (5 * length) + boxToTextXOffSet;
uInt32 boxHeight = 8 + (2 * (yTextOffSet - yBoxOffSet));
xBoxOffSet = (myFrameWidth >> 1) - (boxWidth >> 1);
xTextOffSet = xBoxOffSet + boxToTextXOffSet;
// First, draw the surrounding box
for(uInt32 x = 0; x < boxWidth; ++x)
{
for(uInt32 y = 0; y < boxHeight; ++y)
{
uInt32 position = ((yBoxOffSet + y) * myFrameWidth) + x + xBoxOffSet;
if((x == 0) || (x == boxWidth - 1) || (y == 0) || (y == boxHeight - 1))
myCurrentFrameBuffer[position] = fontColor;
else
myCurrentFrameBuffer[position] = backColor;
}
}
// Then, draw the text
//FIXME - change back to x
for(uInt8 x1 = 0; x1 < length; ++x1)
{
char letter = myMessageText[x1];
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
{
xTextOffSet += 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 + yTextOffSet) * myFrameWidth + (4 - xPos) + xTextOffSet;
myCurrentFrameBuffer[position] = fontColor;
}
}
// move left to the next character
xTextOffSet += 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
{

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.7 2002-10-09 04:38:12 bwmott Exp $
// $Id: TIA.hxx,v 1.8 2003-09-26 17:35:05 stephena Exp $
//============================================================================
#ifndef TIA_HXX
@ -43,7 +43,7 @@ class Deserializer;
in a bounded queue.
@author Bradford W. Mott
@version $Id: TIA.hxx,v 1.7 2002-10-09 04:38:12 bwmott Exp $
@version $Id: TIA.hxx,v 1.8 2003-09-26 17:35:05 stephena Exp $
*/
class TIA : public Device , public MediaSource
{
@ -137,12 +137,6 @@ 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
@ -319,12 +313,6 @@ 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;
@ -566,9 +554,6 @@ 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&);
@ -578,4 +563,3 @@ class TIA : public Device , public MediaSource
};
#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: UserInterface.cxx,v 1.2 2003-09-26 00:32:00 stephena Exp $
// $Id: UserInterface.cxx,v 1.3 2003-09-26 17:35:05 stephena Exp $
//============================================================================
#include "bspf.hxx"
@ -27,9 +27,11 @@
UserInterface::UserInterface(Console* console, MediaSource* mediasrc)
: myConsole(console),
myMediaSource(mediasrc),
myBufferSize(160*300),
myBufferDirtyFlag(true),
myCurrentMenu(MENU_NONE)
myCurrentWidget(NONE),
myRemapEventSelectedFlag(false),
mySelectedEvent(Event::NoType),
myMessageTime(0),
myMessageText("")
{
}
@ -39,43 +41,63 @@ UserInterface::~UserInterface(void)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void UserInterface::showMenu(MenuType type)
void UserInterface::showMainMenu(bool show)
{
if(myCurrentMenu != type)
myBufferDirtyFlag = true;
myCurrentMenu = type;
// if(myBufferDirtyFlag)
// cls();
/* uInt8* frontbuffer = myMediaSource->currentFrameBuffer();
uInt8* backbuffer = myMediaSource->previousFrameBuffer();
// First, draw the surrounding box
for(uInt32 x = 0; x < 100; ++x)
{
for(uInt32 y = 0; y < 100; ++y)
{
uInt32 position = ((20 + y) * myWidth) + x + 20;
if((x == 0) || (x == 200 - 1) || (y == 0) || (y == 200 - 1))
frontbuffer[position] = backbuffer[position] = 10;
else
frontbuffer[position] = backbuffer[position] = 0;
}
}*/
myCurrentWidget = show ? MAIN_MENU : NONE;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void UserInterface::cls()
void UserInterface::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
{
if(myCurrentWidget == NONE || state != 1)
return;
else if(myCurrentWidget == MAIN_MENU)
{
if(key == StellaEvent::KCODE_RETURN)
myCurrentWidget = currentSelectedWidget();
else if(key == StellaEvent::KCODE_UP)
moveCursorUp();
else if(key == StellaEvent::KCODE_DOWN)
moveCursorDown();
}
else if(myCurrentWidget == REMAP_MENU)
{
if(myRemapEventSelectedFlag)
{
if(key == StellaEvent::KCODE_ESCAPE)
// associate nothing with the selected event
cerr << "delete binding for " << mySelectedEvent << endl;
else
// associate this stellaevent with the selected event
cerr << "add binding " << key << " for " << mySelectedEvent << endl;
myRemapEventSelectedFlag = false;
}
else if(key == StellaEvent::KCODE_RETURN)
{
cerr << "event selected for remapping\n";
mySelectedEvent = currentSelectedEvent();
myRemapEventSelectedFlag = true;
}
else if(key == StellaEvent::KCODE_UP)
moveCursorUp();
else if(key == StellaEvent::KCODE_DOWN)
moveCursorDown();
else if(key == StellaEvent::KCODE_ESCAPE)
myCurrentWidget = MAIN_MENU;
}
else if(myCurrentWidget == INFO_MENU)
{
cerr << "key received while in info menu\n";
if(key == StellaEvent::KCODE_ESCAPE)
myCurrentWidget = MAIN_MENU;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void UserInterface::sendJoyEvent(StellaEvent::JoyStick stick,
StellaEvent::JoyCode code, Int32 state)
{
cerr << "UserInterface::cls() called\n";
// Initialize buffer to -1, which represents an 'opaque' color
// When the buffer is overlaid onto the TIA, all pixels with a
// color of -1 will be use the underlying color, like a color mask
for(uInt32 i = 0; i < myBufferSize; ++i)
myBuffer[i] = -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -83,30 +105,28 @@ void UserInterface::update()
{
uInt8* frontbuffer = myMediaSource->currentFrameBuffer();
if(myCurrentMenu == MENU_NONE)
if(myCurrentWidget == NONE)
{
myCurrentMenu = MENU_NONE;
return; // this shouldn't happen
}
else if(myCurrentMenu == MENU_MAIN)
else if(myCurrentWidget == MAIN_MENU)
{
cerr << "draw main menu\n";
; // draw main menu
}
else if(myCurrentMenu == MENU_REMAP)
else if(myCurrentWidget == REMAP_MENU)
{
cerr << "draw remap menu\n";
; // draw remap menu
}
else if(myCurrentMenu == MENU_INFO)
else if(myCurrentWidget == INFO_MENU)
{
cerr << "draw info menu\n";
// FIXME - this will disappear soon ...
// First, draw the surrounding box
for(uInt32 x = 10; x < 100; ++x)
for(uInt32 x = 0; x < 100; ++x)
{
for(uInt32 y = 10; y < 200; ++y)
for(uInt32 y = 0; y < 100; ++y)
{
uInt32 position = ((20 + y) * 160) + x + 20;
uInt32 position = ((20 + y) * myMediaSource->width()) + x + 20;
if((x == 0) || (x == 200 - 1) || (y == 0) || (y == 200 - 1))
frontbuffer[position] = 10;
@ -114,21 +134,19 @@ void UserInterface::update()
frontbuffer[position] = 0;
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
UserInterface::MenuType UserInterface::currentSelectedMenu()
UserInterface::Widget UserInterface::currentSelectedWidget()
{
return MENU_INFO; // FIXME
return REMAP_MENU; // FIXME
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Event::Type UserInterface::currentSelectedItem()
Event::Type UserInterface::currentSelectedEvent()
{
return Event::NoType; // FIXME
return Event::ConsoleSelect; // FIXME
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -281,3 +299,33 @@ const uInt32 UserInterface::ourFontData[36] = {
0x6996996, // 8
0x6997196 // 9
};
/* uInt8* frontbuffer = myMediaSource->currentFrameBuffer();
uInt8* backbuffer = myMediaSource->previousFrameBuffer();
// First, draw the surrounding box
for(uInt32 x = 0; x < 100; ++x)
{
for(uInt32 y = 0; y < 100; ++y)
{
uInt32 position = ((20 + y) * myWidth) + x + 20;
if((x == 0) || (x == 200 - 1) || (y == 0) || (y == 200 - 1))
frontbuffer[position] = backbuffer[position] = 10;
else
frontbuffer[position] = backbuffer[position] = 0;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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]);
}
*/

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: UserInterface.hxx,v 1.2 2003-09-26 00:32:00 stephena Exp $
// $Id: UserInterface.hxx,v 1.3 2003-09-26 17:35:05 stephena Exp $
//============================================================================
#ifndef USERINTERFACE_HXX
@ -21,6 +21,7 @@
#include "bspf.hxx"
#include "Event.hxx"
#include "StellaEvent.hxx"
class Console;
class MediaSource;
@ -30,7 +31,7 @@ class MediaSource;
can be changed.
@author Stephen Anthony
@version $Id: UserInterface.hxx,v 1.2 2003-09-26 00:32:00 stephena Exp $
@version $Id: UserInterface.hxx,v 1.3 2003-09-26 17:35:05 stephena Exp $
*/
class UserInterface
{
@ -48,22 +49,45 @@ class UserInterface
*/
virtual ~UserInterface(void);
// Enumeration representing the different types of menus
enum MenuType { MENU_NONE, MENU_MAIN, MENU_REMAP, MENU_INFO };
/**
Send a keyboard event to the user interface.
@param code The StellaEvent code
@param state The StellaEvent state
*/
void sendKeyEvent(StellaEvent::KeyCode code, Int32 state);
/**
Send a joystick button event to the user interface.
@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);
void sendKeymap(Event::Type table[StellaEvent::LastKCODE]);
void sendJoymap(Event::Type table[StellaEvent::LastJSTICK][StellaEvent::LastJCODE]);
public:
MenuType currentSelectedMenu();
Event::Type currentSelectedItem();
bool drawPending() { return myCurrentMenu != MENU_NONE; }
void showMenu(MenuType type);
bool drawPending() { return myCurrentWidget != NONE; }
void showMainMenu(bool show);
void showMessage(string& message);
void update();
private:
// Enumeration representing the different types of user interface widgets
enum Widget { NONE, MAIN_MENU, REMAP_MENU, INFO_MENU, MESSAGE };
Widget currentSelectedWidget();
Event::Type currentSelectedEvent();
void moveCursorUp();
void moveCursorDown();
private:
// Clears the internal framebuffer
void cls();
// Draw a bounded box centered horizontally
void drawBoundedBox(uInt32 width, uInt32 height);
private:
// The Console for the system
@ -72,23 +96,26 @@ class UserInterface
// The Mediasource for the system
MediaSource* myMediaSource;
// A buffer containing the current interface element to be drawn
Int16* myBuffer;
// Indicates the size of the framebuffer
uInt32 myBufferSize;
// Bounds for the window frame
uInt32 myXStart, myYStart, myWidth, myHeight;
// Table of bitmapped fonts. Holds A..Z and 0..9.
static const uInt32 ourFontData[36];
// Indicates if buffers are dirty (have been modified)
bool myBufferDirtyFlag;
// Type of interface item currently slated for redraw
Widget myCurrentWidget;
// Menu type currently slated for redraw
MenuType myCurrentMenu;
// Indicates that an event is currently being remapped
bool myRemapEventSelectedFlag;
// Indicates the current selected event being remapped
Event::Type mySelectedEvent;
// Message timer
Int32 myMessageTime;
// Message text
string myMessageText;
};
#endif