mirror of https://github.com/stella-emu/stella.git
Cleaned up the UserInterface class a little.
Added arrows for user feedback in the key remapping section of the UserInterface class. Still have to indicate which key is being remapped, though. Added another menu to the main menu (of the GUI) called 'Character Set', showing the font being used. I found it useful for determining what particular character to use when coding the GUI, but I don't know if it will remain in the final release. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@197 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
bcd76bddfc
commit
aa2a397b6c
|
@ -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.8 2003-09-30 18:46:12 stephena Exp $
|
||||
// $Id: UserInterface.cxx,v 1.9 2003-10-01 19:01:01 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <sstream>
|
||||
|
@ -37,10 +37,19 @@
|
|||
#define XBOXOFFSET 8 // 4 pixels to the left and right of text
|
||||
#define YBOXOFFSET 8 // 4 pixels to the top and bottom of text
|
||||
|
||||
#define UPARROW 24 // Indicates more lines above
|
||||
#define DOWNARROW 25 // Indicates more lines below
|
||||
#define LEFTARROW 26 // Left arrow for indicating current line
|
||||
#define RIGHTARROW 27 // Left arrow for indicating current line
|
||||
|
||||
#define LEFTMARKER 17 // Indicates item being remapped
|
||||
#define RIGHTMARKER 16 // Indicates item being remapped
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
UserInterface::UserInterface(Console* console, MediaSource* mediasrc)
|
||||
: myConsole(console),
|
||||
myMediaSource(mediasrc),
|
||||
myFrameRate(0),
|
||||
myCurrentWidget(W_NONE),
|
||||
myRemapEventSelectedFlag(false),
|
||||
mySelectedEvent(Event::NoType),
|
||||
|
@ -56,6 +65,8 @@ UserInterface::UserInterface(Console* console, MediaSource* mediasrc)
|
|||
myMessageText(""),
|
||||
myInfoMenuWidth(0)
|
||||
{
|
||||
myFrameRate = myConsole->settings().getInt("framerate");
|
||||
|
||||
myXStart = atoi(myConsole->properties().get("Display.XStart").c_str());
|
||||
myWidth = atoi(myConsole->properties().get("Display.Width").c_str());
|
||||
myYStart = atoi(myConsole->properties().get("Display.YStart").c_str());
|
||||
|
@ -117,6 +128,13 @@ void UserInterface::showMainMenu(bool show)
|
|||
mySelectedEvent = Event::NoType;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UserInterface::showMessage(const string& message)
|
||||
{
|
||||
myMessageText = message;
|
||||
myMessageTime = myFrameRate << 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UserInterface::sendKeyEvent(StellaEvent::KeyCode key, Int32 state)
|
||||
{
|
||||
|
@ -169,6 +187,10 @@ cerr << "'" << ourRemapMenu[myRemapMenuIndex].action << "' selected for remappin
|
|||
if(key == StellaEvent::KCODE_ESCAPE)
|
||||
myCurrentWidget = MAIN_MENU;
|
||||
|
||||
case FONTS_MENU:
|
||||
if(key == StellaEvent::KCODE_ESCAPE)
|
||||
myCurrentWidget = MAIN_MENU;
|
||||
|
||||
break; // INFO_MENU
|
||||
|
||||
default:
|
||||
|
@ -225,86 +247,44 @@ cerr << "stick = " << stick << ", button = " << code << endl;
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UserInterface::update()
|
||||
{
|
||||
// I know this method is hideous :)
|
||||
uInt32 x, y, width, height, i;
|
||||
switch(myCurrentWidget)
|
||||
{
|
||||
case W_NONE:
|
||||
break;
|
||||
|
||||
case MAIN_MENU:
|
||||
drawMainMenu();
|
||||
break;
|
||||
|
||||
case REMAP_MENU:
|
||||
drawRemapMenu();
|
||||
break;
|
||||
|
||||
case INFO_MENU:
|
||||
drawInfoMenu();
|
||||
break;
|
||||
|
||||
case FONTS_MENU:
|
||||
drawFontsMenu();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// A message is a special case of interface element
|
||||
// It can overwrite even a menu, so we should check for that first
|
||||
// It can overwrite even a menu
|
||||
if(myMessageTime > 0)
|
||||
{
|
||||
width = myMessageText.length()*FONTWIDTH + FONTWIDTH;
|
||||
height = LINEOFFSET + FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = myHeight - height - LINEOFFSET/2;
|
||||
uInt32 width = myMessageText.length()*FONTWIDTH + FONTWIDTH;
|
||||
uInt32 height = LINEOFFSET + FONTHEIGHT;
|
||||
uInt32 x = (myWidth >> 1) - (width >> 1);
|
||||
uInt32 y = myHeight - height - LINEOFFSET/2;
|
||||
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y, width, height);
|
||||
drawText(x + XBOXOFFSET/2, LINEOFFSET/2 + y, myMessageText);
|
||||
myMessageTime--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
switch(myCurrentWidget)
|
||||
{
|
||||
case W_NONE:
|
||||
return;
|
||||
break; // NONE
|
||||
|
||||
case MAIN_MENU:
|
||||
width = 16*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = myMainMenuItems*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y, width, height);
|
||||
for(i = 0; i < myMainMenuItems; i++)
|
||||
drawText(x + XBOXOFFSET, LINEOFFSET*i + y + YBOXOFFSET, ourMainMenu[i].action);
|
||||
|
||||
// FIXME - change the '~' to an arrow on each end of the line
|
||||
// Now draw the selection arrow around the currently selected item
|
||||
drawText(x + 2, LINEOFFSET*myMainMenuIndex + y + YBOXOFFSET, "~");
|
||||
|
||||
break; // MAIN_MENU
|
||||
|
||||
case REMAP_MENU:
|
||||
width = 16*FONTWIDTH + 2*FONTWIDTH; // FIXME - change 16 to maximum in new framebuffer (~ 40)
|
||||
height = myMaxLines*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y, width, height);
|
||||
for(i = myRemapMenuLowIndex; i < myRemapMenuHighIndex; i++)
|
||||
{
|
||||
drawText(x + XBOXOFFSET, LINEOFFSET*(i-myRemapMenuLowIndex) + y + YBOXOFFSET,
|
||||
ourRemapMenu[i].action);
|
||||
drawText(x + XBOXOFFSET+100, LINEOFFSET*(i-myRemapMenuLowIndex) + y + YBOXOFFSET,
|
||||
ourRemapMenu[i].key);
|
||||
}
|
||||
|
||||
// FIXME - change the '~' to an arrow on each end of the line
|
||||
// Now draw the selection arrow around the currently selected item
|
||||
drawText(x + 2, LINEOFFSET*(myRemapMenuIndex-myRemapMenuLowIndex) + y + YBOXOFFSET, "~");
|
||||
|
||||
break; // REMAP_MENU
|
||||
|
||||
case INFO_MENU:
|
||||
width = myInfoMenuWidth*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = 6*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text
|
||||
drawBoundedBox(x, y, width, height);
|
||||
for(i = 0; i < 6; i++)
|
||||
drawText(x + XBOXOFFSET, LINEOFFSET*i + y + YBOXOFFSET, ourPropertiesInfo[i]);
|
||||
|
||||
break; // INFO_MENU
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,10 +441,124 @@ void UserInterface::movePageDown()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UserInterface::showMessage(const string& message)
|
||||
inline void UserInterface::drawMainMenu()
|
||||
{
|
||||
myMessageText = message;
|
||||
myMessageTime = 2 * myConsole->settings().getInt("framerate");
|
||||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = 16*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = myMainMenuItems*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text, leaving a little room for arrows
|
||||
xpos = x + XBOXOFFSET;
|
||||
drawBoundedBox(x-2, y-2, width+3, height+3);
|
||||
for(i = 0; i < myMainMenuItems; i++)
|
||||
drawText(xpos, LINEOFFSET*i + y + YBOXOFFSET, ourMainMenu[i].action);
|
||||
|
||||
// Now draw the selection arrow around the currently selected item
|
||||
ypos = LINEOFFSET*myMainMenuIndex + y + YBOXOFFSET;
|
||||
drawChar(x, ypos, LEFTARROW);
|
||||
drawChar(width - x, ypos, RIGHTARROW);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline void UserInterface::drawRemapMenu()
|
||||
{
|
||||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = 16*FONTWIDTH + 2*FONTWIDTH; // FIXME - change 16 to maximum in new framebuffer (~ 40)
|
||||
height = myMaxLines*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// FIXME - change 100 to left bound of key strings in new frmaebuffer
|
||||
// Draw the bounded box and text, leaving a little room for arrows
|
||||
drawBoundedBox(x-2, y-2, width+3, height+3);
|
||||
for(i = myRemapMenuLowIndex; i < myRemapMenuHighIndex; i++)
|
||||
{
|
||||
drawText(x + XBOXOFFSET, LINEOFFSET*(i-myRemapMenuLowIndex) + y + YBOXOFFSET,
|
||||
ourRemapMenu[i].action);
|
||||
drawText(x + XBOXOFFSET+100, LINEOFFSET*(i-myRemapMenuLowIndex) + y + YBOXOFFSET,
|
||||
ourRemapMenu[i].key);
|
||||
}
|
||||
|
||||
// Normally draw an arrow indicating the current line,
|
||||
// otherwise highlight the currently selected item for remapping
|
||||
if(!myRemapEventSelectedFlag)
|
||||
{
|
||||
ypos = LINEOFFSET*(myRemapMenuIndex-myRemapMenuLowIndex) + y + YBOXOFFSET;
|
||||
drawChar(x, ypos, LEFTARROW);
|
||||
drawChar(width - x, ypos, RIGHTARROW);
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME - draw "<| |>" around key being changed
|
||||
// Can't be done until the framebuffer has been updated and I know exactly
|
||||
// where the item will be located on the line.
|
||||
// cerr << "draw brackets around '" << ourRemapMenu[myRemapMenuIndex].key << "'\n";
|
||||
drawText(x + 2, LINEOFFSET*(myRemapMenuIndex-myRemapMenuLowIndex) + y + YBOXOFFSET, ">");
|
||||
}
|
||||
|
||||
// Finally, indicate that there are more items to the top or bottom
|
||||
xpos = (width >> 1) - FONTWIDTH/2;
|
||||
if(myRemapMenuHighIndex - myMaxLines > 0)
|
||||
drawChar(xpos, y, UPARROW);
|
||||
|
||||
if(myRemapMenuLowIndex + myMaxLines < myRemapMenuItems)
|
||||
drawChar(xpos, height - FONTWIDTH/2, DOWNARROW);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline void UserInterface::drawInfoMenu()
|
||||
{
|
||||
uInt32 x, y, width, height, i, xpos, ypos;
|
||||
|
||||
width = myInfoMenuWidth*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = 6*LINEOFFSET + 2*FONTHEIGHT;
|
||||
x = (myWidth >> 1) - (width >> 1);
|
||||
y = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text
|
||||
xpos = x + XBOXOFFSET;
|
||||
drawBoundedBox(x, y, width, height);
|
||||
for(i = 0; i < 6; i++)
|
||||
drawText(xpos, LINEOFFSET*i + y + YBOXOFFSET, ourPropertiesInfo[i]);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
inline void UserInterface::drawFontsMenu()
|
||||
{
|
||||
uInt32 xorig, yorig, width, height, xpos, ypos;
|
||||
|
||||
width = 16*FONTWIDTH + 2*FONTWIDTH;
|
||||
height = myMaxLines*LINEOFFSET;
|
||||
xorig = (myWidth >> 1) - (width >> 1);
|
||||
yorig = (myHeight >> 1) - (height >> 1);
|
||||
|
||||
// Draw the bounded box and text
|
||||
xpos = xorig + XBOXOFFSET;
|
||||
ypos = yorig + YBOXOFFSET;
|
||||
drawBoundedBox(xorig, yorig, width, height);
|
||||
|
||||
uInt8* buffer = myMediaSource->currentFrameBuffer();
|
||||
|
||||
for(uInt32 lines = 0; lines < 256; lines+=16)
|
||||
{
|
||||
for(uInt32 x = 0; x < 16; x++)
|
||||
{
|
||||
for(uInt32 y = 0; y < FONTHEIGHT; y++)
|
||||
{
|
||||
for(uInt32 z = 0; z < FONTWIDTH; z++)
|
||||
{
|
||||
uInt32 letter = lines + x;
|
||||
if((ourFontData[(letter << 3) + y] >> z) & 1)
|
||||
buffer[(y + ypos)*myWidth + (x<<3) + z + xpos] = FGCOLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
ypos += LINEOFFSET;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -506,6 +600,24 @@ void UserInterface::drawText(uInt32 xorig, uInt32 yorig, const string& message)
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UserInterface::drawChar(uInt32 xorig, uInt32 yorig, uInt32 c)
|
||||
{
|
||||
if(c >= 256 )
|
||||
return;
|
||||
|
||||
uInt8* buffer = myMediaSource->currentFrameBuffer();
|
||||
|
||||
for(uInt32 y = 0; y < FONTHEIGHT; y++)
|
||||
{
|
||||
for(uInt32 z = 0; z < FONTWIDTH; z++)
|
||||
{
|
||||
if((ourFontData[(c << 3) + y] >> z) & 1)
|
||||
buffer[(y + yorig)*myWidth + z + xorig] = FGCOLOR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void UserInterface::loadRemapMenu()
|
||||
{
|
||||
|
@ -527,7 +639,7 @@ void UserInterface::loadRemapMenu()
|
|||
}
|
||||
for(uInt32 j = 0; j < myJoyTableSize; ++j)
|
||||
{
|
||||
if(myJoyTable[j] == event)
|
||||
if(myJoyTable[j] == event) // FIXME - don't label axis as button
|
||||
{
|
||||
ostringstream joyevent;
|
||||
uInt32 stick = j / StellaEvent::LastJCODE;
|
||||
|
@ -590,9 +702,10 @@ const uInt8 UserInterface::ourFontData[2048] = {
|
|||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
UserInterface::MainMenuItem UserInterface::ourMainMenu[2] = {
|
||||
UserInterface::MainMenuItem UserInterface::ourMainMenu[3] = {
|
||||
{ REMAP_MENU, "Key Remapping" },
|
||||
{ INFO_MENU, "Game Information" }
|
||||
{ INFO_MENU, "Game Information" },
|
||||
{ FONTS_MENU, "Character Set" }
|
||||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -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.6 2003-09-30 01:22:45 stephena Exp $
|
||||
// $Id: UserInterface.hxx,v 1.7 2003-10-01 19:01:02 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef USERINTERFACE_HXX
|
||||
|
@ -31,7 +31,7 @@ class MediaSource;
|
|||
can be changed.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: UserInterface.hxx,v 1.6 2003-09-30 01:22:45 stephena Exp $
|
||||
@version $Id: UserInterface.hxx,v 1.7 2003-10-01 19:01:02 stephena Exp $
|
||||
*/
|
||||
class UserInterface
|
||||
{
|
||||
|
@ -74,7 +74,7 @@ class UserInterface
|
|||
|
||||
private:
|
||||
// Enumeration representing the different types of user interface widgets
|
||||
enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU };
|
||||
enum Widget { W_NONE, MAIN_MENU, REMAP_MENU, INFO_MENU, FONTS_MENU };
|
||||
|
||||
Widget currentSelectedWidget();
|
||||
Event::Type currentSelectedEvent();
|
||||
|
@ -91,12 +91,27 @@ class UserInterface
|
|||
// Move the list down 1 page and put the cursor at the top
|
||||
void movePageDown();
|
||||
|
||||
// Draw the main menu
|
||||
void drawMainMenu();
|
||||
|
||||
// Draw the remap menu
|
||||
void drawRemapMenu();
|
||||
|
||||
// Draw the info menu
|
||||
void drawInfoMenu();
|
||||
|
||||
// Draw the fonts menu
|
||||
void drawFontsMenu();
|
||||
|
||||
// Draw a bounded box at the specified coordinates
|
||||
void drawBoundedBox(uInt32 x, uInt32 y, uInt32 width, uInt32 height);
|
||||
|
||||
// Draw message text at specified coordinates
|
||||
void drawText(uInt32 x, uInt32 y, const string& message);
|
||||
|
||||
// Draw character 'c' at specified coordinates
|
||||
void drawChar(uInt32 x, uInt32 y, uInt32 c);
|
||||
|
||||
// scan the mapping arrays and update the remap menu
|
||||
void loadRemapMenu();
|
||||
|
||||
|
@ -118,6 +133,9 @@ class UserInterface
|
|||
// The Mediasource for the system
|
||||
MediaSource* myMediaSource;
|
||||
|
||||
// Indicates the current framerate of the system
|
||||
uInt32 myFrameRate;
|
||||
|
||||
// Structure used for main menu items
|
||||
struct MainMenuItem
|
||||
{
|
||||
|
@ -174,7 +192,7 @@ class UserInterface
|
|||
string ourPropertiesInfo[6];
|
||||
|
||||
// Holds static strings for the main menu
|
||||
static MainMenuItem ourMainMenu[2];
|
||||
static MainMenuItem ourMainMenu[3];
|
||||
|
||||
// Holds static strings for the remap menu
|
||||
static RemapMenuItem ourRemapMenu[57];
|
||||
|
|
Loading…
Reference in New Issue