Added beginnings of VideoDialog box. Things are proceeding nicely ...

git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@382 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2005-03-14 04:08:15 +00:00
parent 24a81a0d11
commit c7383bb103
24 changed files with 1335 additions and 205 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.65 2005-03-13 03:38:39 stephena Exp $
## $Id: makefile,v 1.66 2005-03-14 04:08:12 stephena Exp $
##============================================================================
##============================================================================
@ -153,7 +153,8 @@ CORE_OBJS = Booster.o Cart.o Cart2K.o Cart3F.o Cart4K.o CartAR.o CartDPC.o \
Event.o Joystick.o Keyboard.o M6532.o MD5.o MediaSrc.o Paddles.o \
Props.o PropsSet.o Random.o Sound.o Switches.o Settings.o TIA.o \
Serializer.o Deserializer.o TIASound.o EventHandler.o FrameBuffer.o \
OSystem.o StellaFont.o Menu.o Widget.o Dialog.o OptionsDialog.o\
OSystem.o StellaFont.o Menu.o Widget.o PopUpWidget.o Dialog.o \
OptionsDialog.o VideoDialog.o \
$(M6502_OBJS)
stella: $(CORE_OBJS) $(OBJS)
@ -361,8 +362,14 @@ Menu.o: $(GUI)/Menu.cxx $(GUI)/Menu.hxx
Widget.o: $(GUI)/Widget.cxx $(GUI)/Widget.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/Widget.cxx
PopUpWidget.o: $(GUI)/PopUpWidget.cxx $(GUI)/PopUpWidget.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/PopUpWidget.cxx
Dialog.o: $(GUI)/Dialog.cxx $(GUI)/Dialog.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/Dialog.cxx
OptionsDialog.o: $(GUI)/OptionsDialog.cxx $(GUI)/OptionsDialog.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/OptionsDialog.cxx
VideoDialog.o: $(GUI)/VideoDialog.cxx $(GUI)/VideoDialog.hxx
$(CXX) -c $(FLAGS) $(OPTIONS) $(LDFLAGS) $(GUI)/VideoDialog.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: FrameBufferSoft.cxx,v 1.11 2005-03-13 03:38:39 stephena Exp $
// $Id: FrameBufferSoft.cxx,v 1.12 2005-03-14 04:08:13 stephena Exp $
//============================================================================
#include <SDL.h>
@ -260,56 +260,6 @@ void FrameBufferSoft::drawMediaSource()
theRedrawEntireFrameIndicator = false;
}
/*
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::drawText(uInt32 xorig, uInt32 yorig, const string& message)
{
SDL_Rect tmp;
uInt8 length = message.length();
for(uInt32 x = 0; x < length; x++)
{
for(uInt32 y = 0; y < 8; y++)
{
for(uInt32 z = 0; z < 8; z++)
{
char letter = message[x];
if((ourFontData[(letter << 3) + y] >> z) & 1)
{
tmp.x = ((x<<3) + z + xorig) * theZoomLevel;
tmp.y = (y + yorig) * theZoomLevel;
tmp.w = tmp.h = theZoomLevel;
SDL_FillRect(myScreen, &tmp, myPalette[10]);
}
}
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::drawChar(uInt32 xorig, uInt32 yorig, uInt32 c)
{
if(c >= 256 )
return;
SDL_Rect tmp;
for(uInt32 y = 0; y < 8; y++)
{
for(uInt32 z = 0; z < 8; z++)
{
if((ourFontData[(c << 3) + y] >> z) & 1)
{
tmp.x = (z + xorig) * theZoomLevel;
tmp.y = (y + yorig) * theZoomLevel;
tmp.w = tmp.h = theZoomLevel;
SDL_FillRect(myScreen, &tmp, myPalette[10]);
}
}
}
}
*/
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBufferSoft::preFrameUpdate()
{

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.27 2005-02-27 23:41:17 stephena Exp $
// $Id: mainSDL.cxx,v 1.28 2005-03-14 04:08:13 stephena Exp $
//============================================================================
#include <fstream>
@ -410,7 +410,7 @@ void HandleEvents()
case SDLK_p: // Ctrl-p toggles different palettes
theOSystem->console().togglePalette();
theDisplay->setupPalette();
// theDisplay->setupPalette();
break;
#ifdef DEVELOPER_SUPPORT
@ -456,37 +456,15 @@ void HandleEvents()
case SDL_MOUSEMOTION:
{
uInt32 zoom = theDisplay->zoomLevel();
Int32 width = theDisplay->width() * zoom;
// Grabmouse and hidecursor introduce some lag into the mouse movement,
// so we need to fudge the numbers a bit
if(theGrabMouseIndicator && theHideCursorIndicator)
mouseX = (int)((float)mouseX + (float)event.motion.xrel
* 1.5 * (float) zoom);
else
mouseX = mouseX + event.motion.xrel * zoom;
// Check to make sure mouseX is within the game window
if(mouseX < 0)
mouseX = 0;
else if(mouseX > width)
mouseX = width;
Int32 resistance = (Int32)(1000000.0 * (width - mouseX) / width);
theOSystem->eventHandler().handleEvent(Paddle_Resistance[thePaddleMode], resistance);
theOSystem->eventHandler().handleMouseMotionEvent(event);
break; // SDL_MOUSEMOTION
}
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
{
Int32 value = event.button.type == SDL_MOUSEBUTTONDOWN ? 1 : 0;
theOSystem->eventHandler().handleEvent(Paddle_Button[thePaddleMode], value);
uInt8 state = event.button.type == SDL_MOUSEBUTTONDOWN ? 1 : 0;
theOSystem->eventHandler().handleMouseButtonEvent(event, state);
break; // SDL_MOUSEBUTTONUP, SDL_MOUSEBUTTONDOWN
}
@ -497,7 +475,6 @@ void HandleEvents()
if(!theOSystem->eventHandler().doPause())
theOSystem->eventHandler().handleEvent(Event::Pause, 1);
}
break; // SDL_ACTIVEEVENT
}

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.42 2005-02-25 02:29:37 stephena Exp $
// $Id: Console.cxx,v 1.43 2005-03-14 04:08:13 stephena Exp $
//============================================================================
#include <assert.h>
@ -45,6 +45,7 @@
#include "TIA.hxx"
#include "FrameBuffer.hxx"
#include "OSystem.hxx"
#include "Menu.hxx"
#ifdef SNAPSHOT_SUPPORT
#include "Snapshot.hxx"
@ -182,6 +183,9 @@ Console::Console(const uInt8* image, uInt32 size, OSystem* osystem)
// Initialize the sound interface.
uInt32 soundFrameRate = (myProperties.get("Display.Format") == "PAL") ? 50 : 60;
myOSystem->sound().initialize(soundFrameRate);
// Initialize the menuing system with updated values from the framebuffer
myOSystem->menu().initialize();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -236,30 +240,51 @@ void Console::toggleFormat()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::togglePalette()
void Console::togglePalette(const string& palette)
{
string type = myOSystem->settings().getString("palette");
string message, type;
// Since the toggle cycles in order, if we know which palette to switch
// to we set the 'type' to the previous one in the sequence
if(palette != "")
{
if(palette == "Standard")
type = "z26";
else if(palette == "Original")
type = "standard";
else if(palette == "Z26")
type = "original";
else
type = "";
}
else
type = myOSystem->settings().getString("palette");
if(type == "standard") // switch to original
{
myOSystem->frameBuffer().showMessage("Original Stella colors");
myOSystem->settings().setString("palette", "original");
type = "original";
message = "Original Stella colors";
}
else if(type == "original") // switch to z26
{
myOSystem->frameBuffer().showMessage("Z26 colors");
myOSystem->settings().setString("palette", "z26");
type = "z26";
message = "Z26 colors";
}
else if(type == "z26") // switch to standard
{
myOSystem->frameBuffer().showMessage("Standard Stella colors");
myOSystem->settings().setString("palette", "standard");
type = "standard";
message = "Standard Stella colors";
}
else // switch to standard mode if we get this far
{
myOSystem->frameBuffer().showMessage("Standard Stella colors");
myOSystem->settings().setString("palette", "standard");
type = "standard";
message = "Standard Stella colors";
}
myOSystem->settings().setString("palette", type);
myOSystem->frameBuffer().setupPalette();
myOSystem->frameBuffer().showMessage(message);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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.24 2005-02-21 20:41:26 stephena Exp $
// $Id: Console.hxx,v 1.25 2005-03-14 04:08:14 stephena Exp $
//============================================================================
#ifndef CONSOLE_HXX
@ -36,7 +36,7 @@ class OSystem;
This class represents the entire game console.
@author Bradford W. Mott
@version $Id: Console.hxx,v 1.24 2005-02-21 20:41:26 stephena Exp $
@version $Id: Console.hxx,v 1.25 2005-03-14 04:08:14 stephena Exp $
*/
class Console
{
@ -127,8 +127,11 @@ class Console
/**
Toggle between the available palettes. The frontends will need to
reload their palette.
@param palette The palette to switch to, or just switch in order
if no palette is specified.
*/
void togglePalette();
void togglePalette(const string& palette = "");
/**
Save a copy of the current properties after any changes.

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.37 2005-03-12 01:47:15 stephena Exp $
// $Id: EventHandler.cxx,v 1.38 2005-03-14 04:08:14 stephena Exp $
//============================================================================
#include <algorithm>
@ -112,16 +112,17 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
if(myState == S_EMULATE)
{
myState = S_MENU;
myOSystem->menu().reset();
myOSystem->menu().reStack();
myOSystem->frameBuffer().refresh();
myOSystem->frameBuffer().setCursorState();
myOSystem->sound().mute(true);
return;
}
else if(myState == S_MENU)
{
myState = S_EMULATE;
myOSystem->menu().reset();
myOSystem->frameBuffer().refresh();
myOSystem->frameBuffer().setCursorState();
myOSystem->sound().mute(false);
return;
}
@ -157,6 +158,124 @@ void EventHandler::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::handleMouseMotionEvent(SDL_Event& event)
{
// Determine which mode we're in, then send the event to the appropriate place
switch(myState)
{
case S_EMULATE:
// FIXME - add code here to generate paddle events
/*
uInt32 zoom = theDisplay->zoomLevel();
Int32 width = theDisplay->width() * zoom;
// Grabmouse and hidecursor introduce some lag into the mouse movement,
// so we need to fudge the numbers a bit
if(theGrabMouseIndicator && theHideCursorIndicator)
mouseX = (int)((float)mouseX + (float)event.motion.xrel
* 1.5 * (float) zoom);
else
mouseX = mouseX + event.motion.xrel * zoom;
// Check to make sure mouseX is within the game window
if(mouseX < 0)
mouseX = 0;
else if(mouseX > width)
mouseX = width;
Int32 resistance = (Int32)(1000000.0 * (width - mouseX) / width);
theOSystem->eventHandler().handleEvent(Paddle_Resistance[thePaddleMode], resistance);
*/
break;
case S_MENU:
{
// Take window zooming into account
Int32 x = event.motion.x / myOSystem->frameBuffer().zoomLevel();
Int32 y = event.motion.y / myOSystem->frameBuffer().zoomLevel();
myOSystem->menu().handleMouseMotionEvent(x, y, 0);
break;
}
case S_BROWSER:
// Not yet implemented
break;
case S_DEBUGGER:
// Not yet implemented
break;
case S_NONE:
return;
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::handleMouseButtonEvent(SDL_Event& event, uInt8 state)
{
// Determine which mode we're in, then send the event to the appropriate place
switch(myState)
{
case S_EMULATE:
// FIXME - add code here to generate paddle buttons
/*
Int32 value = event.button.type == SDL_MOUSEBUTTONDOWN ? 1 : 0;
theOSystem->eventHandler().handleEvent(Paddle_Button[thePaddleMode], value);
*/
break;
case S_MENU:
{
// Take window zooming into account
Int32 x = event.button.x / myOSystem->frameBuffer().zoomLevel();
Int32 y = event.button.y / myOSystem->frameBuffer().zoomLevel();
MouseButton button;
if(state == 1)
{
if(event.button.button == SDL_BUTTON_LEFT)
button = EVENT_LBUTTONDOWN;
else if(event.button.button == SDL_BUTTON_RIGHT)
button = EVENT_RBUTTONDOWN;
else if(event.button.button == SDL_BUTTON_WHEELUP)
button = EVENT_WHEELUP;
else if(event.button.button == SDL_BUTTON_WHEELDOWN)
button = EVENT_WHEELDOWN;
else
break;
}
else
{
if(event.button.button == SDL_BUTTON_LEFT)
button = EVENT_LBUTTONUP;
else if(event.button.button == SDL_BUTTON_RIGHT)
button = EVENT_RBUTTONUP;
else
break;
}
myOSystem->menu().handleMouseButtonEvent(button, x, y, state);
break;
}
case S_BROWSER:
// Not yet implemented
break;
case S_DEBUGGER:
// Not yet implemented
break;
case S_NONE:
return;
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventHandler::sendJoyEvent(StellaEvent::JoyStick stick,
StellaEvent::JoyCode code, Int32 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.18 2005-02-27 23:41:19 stephena Exp $
// $Id: EventHandler.hxx,v 1.19 2005-03-14 04:08:14 stephena Exp $
//============================================================================
#ifndef EVENTHANDLER_HXX
@ -28,6 +28,15 @@
class Console;
class OSystem;
enum MouseButton {
EVENT_LBUTTONDOWN,
EVENT_LBUTTONUP,
EVENT_RBUTTONDOWN,
EVENT_RBUTTONUP,
EVENT_WHEELDOWN,
EVENT_WHEELUP
};
/**
This class takes care of event remapping and dispatching for the
Stella core, as well as keeping track of the current 'mode'.
@ -41,7 +50,7 @@ class OSystem;
mapping can take place.
@author Stephen Anthony
@version $Id: EventHandler.hxx,v 1.18 2005-02-27 23:41:19 stephena Exp $
@version $Id: EventHandler.hxx,v 1.19 2005-03-14 04:08:14 stephena Exp $
*/
class EventHandler
{
@ -98,6 +107,20 @@ class EventHandler
*/
void handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state);
/**
Send a mouse motion event to the handler.
@param event The mouse motion event generated by SDL
*/
void handleMouseMotionEvent(SDL_Event& event);
/**
Send a mouse button event to the handler.
@param event The mouse button event generated by SDL
*/
void handleMouseButtonEvent(SDL_Event& event, uInt8 state);
/**
Send a joystick button event to the handler.

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: FrameBuffer.cxx,v 1.20 2005-03-13 03:38:40 stephena Exp $
// $Id: FrameBuffer.cxx,v 1.21 2005-03-14 04:08:15 stephena Exp $
//============================================================================
#include <sstream>
@ -67,7 +67,8 @@ FrameBuffer::FrameBuffer(OSystem* osystem)
theMenuChangedIndicator(false),
myMessageTime(0),
myMessageText(""),
myMenuRedraws(2)
myMenuRedraws(2),
val(0) // FIXME
{
// Add the framebuffer to the system
myOSystem->attach(this);
@ -143,21 +144,8 @@ void FrameBuffer::initialize(const string title, uInt32 width, uInt32 height)
// Initialize video subsystem
initSubsystem();
// Make sure that theUseFullScreenFlag sets up fullscreen mode correctly
if(myOSystem->settings().getBool("fullscreen"))
{
grabMouse(true);
showCursor(false);
}
else
{
// Keep mouse in game window if grabmouse is selected
grabMouse(myOSystem->settings().getBool("grabmouse"));
// Show or hide the cursor depending on the 'hidecursor' argument
showCursor(!myOSystem->settings().getBool("hidecursor"));
}
// Show or hide the cursor based on the current state
setCursorState();
/*
// Fill the properties info array with game information
@ -253,7 +241,7 @@ void FrameBuffer::update()
case EventHandler::S_MENU:
{
// Only update the screen if it's been invalidated or the menus have changed
if(theMenuChangedIndicator || theRedrawEntireFrameIndicator)
if(theRedrawEntireFrameIndicator)
{
drawMediaSource();
@ -907,16 +895,7 @@ void FrameBuffer::toggleFullscreen()
if(!createScreen())
return;
if(isFullscreen) // now in fullscreen mode
{
grabMouse(true);
showCursor(false);
}
else // now in windowed mode
{
grabMouse(myOSystem->settings().getBool("grabmouse"));
showCursor(!myOSystem->settings().getBool("hidecursor"));
}
setCursorState();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -957,6 +936,33 @@ void FrameBuffer::resize(int mode)
myOSystem->settings().setInt("zoom", theZoomLevel);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::setCursorState()
{
bool isFullscreen = myOSystem->settings().getBool("fullscreen");
if(isFullscreen)
grabMouse(true);
switch(myOSystem->eventHandler().state())
{
case EventHandler::S_EMULATE:
if(isFullscreen)
showCursor(false);
else
{
// Keep mouse in game window if grabmouse is selected
grabMouse(myOSystem->settings().getBool("grabmouse"));
// Show or hide the cursor depending on the 'hidecursor' argument
showCursor(!myOSystem->settings().getBool("hidecursor"));
}
break;
default:
showCursor(true);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FrameBuffer::showCursor(bool show)
{

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: FrameBuffer.hxx,v 1.20 2005-03-13 03:38:40 stephena Exp $
// $Id: FrameBuffer.hxx,v 1.21 2005-03-14 04:08:15 stephena Exp $
//============================================================================
#ifndef FRAMEBUFFER_HXX
@ -41,7 +41,7 @@ class OSystem;
All GUI elements (ala ScummVM) are drawn here as well.
@author Stephen Anthony
@version $Id: FrameBuffer.hxx,v 1.20 2005-03-13 03:38:40 stephena Exp $
@version $Id: FrameBuffer.hxx,v 1.21 2005-03-14 04:08:15 stephena Exp $
*/
class FrameBuffer
{
@ -142,6 +142,7 @@ FIXME
*/
void refresh(bool now = false)
{
//FIXME cerr << "refresh() " << val++ << endl;
theRedrawEntireFrameIndicator = true;
myMenuRedraws = 2;
if(now) drawMediaSource();
@ -163,6 +164,12 @@ FIXME
*/
void resize(int mode);
/**
Sets the state of the cursor (hidden or grabbed) based on the
current mode.
*/
void setCursorState();
/**
Shows or hides the cursor based on the given boolean value.
*/
@ -179,13 +186,13 @@ FIXME
bool fullScreen();
/**
Answers the current zoom level of the SDL
Answers the current zoom level of the SDL window.
*/
uInt32 zoomLevel() { return theZoomLevel; }
inline uInt32 zoomLevel() { return theZoomLevel; }
/**
Calculate the maximum window size that the current screen can hold.
Only works in X11 for now. If not running under X11, always return 4.
Only works in X11/Win32 for now, otherwise always return 4.
*/
uInt32 maxWindowSizeForScreen();
@ -215,9 +222,9 @@ FIXME
/**
Indicate that the specified area should be redrawn.
Currently this is a null-op.
Currently we just redraw the entire screen.
*/
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) {}
void addDirtyRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h) { refresh(); }
public:
//////////////////////////////////////////////////////////////////////
@ -460,6 +467,7 @@ FIXME
// Number of times menu have been drawn
uInt32 myMenuRedraws;
int val;
/*
// Structure used for main menu items
struct MainMenuItem

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: OSystem.cxx,v 1.5 2005-03-10 22:59:40 stephena Exp $
// $Id: OSystem.cxx,v 1.6 2005-03-14 04:08:15 stephena Exp $
//============================================================================
#include <cassert>
@ -43,7 +43,6 @@ OSystem::OSystem()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OSystem::~OSystem()
{
cerr << "OSystem::~OSystem()\n";
delete myMenu;
// delete myBrowser;

184
stella/src/gui/Array.hxx Normal file
View File

@ -0,0 +1,184 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: Array.hxx,v 1.1 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef ARRAY_HXX
#define ARRAY_HXX
#include <assert.h>
#include "bspf.hxx"
template <class T>
class Array
{
protected:
int _capacity;
int _size;
T *_data;
public:
typedef T *iterator;
typedef const T *const_iterator;
public:
Array<T>() : _capacity(0), _size(0), _data(0) {}
Array<T>(const Array<T>& array) : _capacity(0), _size(0), _data(0)
{
_size = array._size;
_capacity = _size + 32;
_data = new T[_capacity];
for(int i = 0; i < _size; i++)
_data[i] = array._data[i];
}
~Array<T>()
{
if (_data)
delete [] _data;
}
void push_back(const T& element)
{
ensureCapacity(_size + 1);
_data[_size++] = element;
}
void push_back(const Array<T>& array)
{
ensureCapacity(_size + array._size);
for(int i = 0; i < array._size; i++)
_data[_size++] = array._data[i];
}
void insert_at(int idx, const T& element)
{
assert(idx >= 0 && idx <= _size);
ensureCapacity(_size + 1);
// The following loop is not efficient if you can just memcpy things around.
// e.g. if you have a list of ints. But for real objects (String...), memcpy
// usually isn't correct (specifically, for any class which has a non-default
// copy behaviour. E.g. the String class uses a refCounter which has to be
// updated whenever a String is copied.
for(int i = _size; i > idx; i--)
_data[i] = _data[i-1];
_data[idx] = element;
_size++;
}
T remove_at(int idx)
{
assert(idx >= 0 && idx < _size);
T tmp = _data[idx];
for(int i = idx; i < _size - 1; i++)
_data[i] = _data[i+1];
_size--;
return tmp;
}
// TODO: insert, remove, ...
T& operator [](int idx)
{
assert(idx >= 0 && idx < _size);
return _data[idx];
}
const T& operator [](int idx) const
{
assert(idx >= 0 && idx < _size);
return _data[idx];
}
Array<T>& operator =(const Array<T>& array)
{
if (_data)
delete [] _data;
_size = array._size;
_capacity = _size + 32;
_data = new T[_capacity];
for(int i = 0; i < _size; i++)
_data[i] = array._data[i];
return *this;
}
uInt32 size() const { return _size; }
void clear()
{
if (_data) {
delete [] _data;
_data = 0;
}
_size = 0;
_capacity = 0;
}
bool isEmpty() const {
return (_size == 0);
}
iterator begin() {
return _data;
}
iterator end() {
return _data + _size;
}
const_iterator begin() const {
return _data;
}
const_iterator end() const {
return _data + _size;
}
bool contains(const T &key) const {
for (const_iterator i = begin(); i != end(); ++i) {
if (*i == key)
return true;
}
return false;
}
protected:
void ensureCapacity(int new_len) {
if (new_len <= _capacity)
return;
T *old_data = _data;
_capacity = new_len + 32;
_data = new T[_capacity];
if (old_data) {
// Copy old data
for (int i = 0; i < _size; i++)
_data[i] = old_data[i];
delete [] old_data;
}
}
};
#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: Dialog.cxx,v 1.5 2005-03-13 03:38:40 stephena Exp $
// $Id: Dialog.cxx,v 1.6 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -42,16 +42,13 @@ Dialog::Dialog(OSystem* instance, uInt16 x, uInt16 y, uInt16 w, uInt16 h)
_focusedWidget(0),
_visible(true)
{
cerr << "Dialog::Dialog()\n";
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Dialog::~Dialog()
{
cerr << "Dialog::~Dialog()\n";
delete _firstWidget;
_firstWidget = 0;
_firstWidget = NULL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -61,7 +58,7 @@ int Dialog::runModal() // FIXME
open();
// Start processing events
// g_gui.runLoop();
// g_gui.runLoop();
// Return the result code
return _result;
@ -71,6 +68,7 @@ int Dialog::runModal() // FIXME
void Dialog::open()
{
_result = 0;
_visible = true;
Widget* w = _firstWidget;
@ -94,6 +92,7 @@ void Dialog::close()
}
releaseFocus();
instance()->menu().removeDialog();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -204,8 +203,6 @@ void Dialog::handleMouseWheel(int x, int y, int direction)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::handleKeyDown(uInt16 ascii, Int32 keycode, Int32 modifiers)
{
cerr << "Dialog::handleKeyDown()\n";
if(_focusedWidget)
if (_focusedWidget->handleKeyDown(ascii, keycode, modifiers))
return;
@ -228,14 +225,6 @@ cerr << "Dialog::handleKeyDown()\n";
w = w->_next;
}
}
// ESC closes all dialogs by default
if (keycode == 27) {
setResult(-1);
close();
}
// TODO: tab/shift-tab should focus the next/previous focusable widget
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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: Dialog.hxx,v 1.4 2005-03-12 01:47:15 stephena Exp $
// $Id: Dialog.hxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -23,6 +23,7 @@
#define DIALOG_HXX
class OSystem;
class Menu;
#include "Command.hxx"
#include "Widget.hxx"
@ -30,19 +31,16 @@ class OSystem;
#include "bspf.hxx"
// Some "common" commands sent to handleCommand()
enum {
kCloseCmd = 'clos'
};
/**
This is the base class for all dialog boxes.
@author Stephen Anthony
@version $Id: Dialog.hxx,v 1.4 2005-03-12 01:47:15 stephena Exp $
@version $Id: Dialog.hxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
*/
class Dialog : public GuiObject
{
friend class Menu;
public:
Dialog(OSystem* instance, uInt16 x, uInt16 y, uInt16 w, uInt16 h);

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: GuiObject.hxx,v 1.3 2005-03-11 23:36:30 stephena Exp $
// $Id: GuiObject.hxx,v 1.4 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -24,6 +24,7 @@
class OSystem;
class Widget;
class Menu;
#include "Command.hxx"
#include "bspf.hxx"
@ -32,11 +33,12 @@ class Widget;
This is the base class for all GUI objects/widgets.
@author Stephen Anthony
@version $Id: GuiObject.hxx,v 1.3 2005-03-11 23:36:30 stephena Exp $
@version $Id: GuiObject.hxx,v 1.4 2005-03-14 04:08:15 stephena Exp $
*/
class GuiObject : public CommandReceiver
{
friend class Widget;
friend class Menu;
public:
GuiObject(OSystem* osystem, int x, int y, int w, int h)

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: GuiUtils.hxx,v 1.1 2005-03-13 03:38:40 stephena Exp $
// $Id: GuiUtils.hxx,v 1.2 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -22,12 +22,14 @@
#ifndef UTILITIES_HXX
#define UTILITIES_HXX
#include "bspf.hxx"
/**
A place to put GUI-related things that don't fit anywhere else.
Probably not very neat, but at least it works ...
@author Stephen Anthony
@version $Id: GuiUtils.hxx,v 1.1 2005-03-13 03:38:40 stephena Exp $
@version $Id: GuiUtils.hxx,v 1.2 2005-03-14 04:08:15 stephena Exp $
*/
// Colors indices to use for the various GUI elements
@ -39,4 +41,14 @@ enum OverlayColor {
kTextColorHi
};
// Standard entries for OK/Cancel buttons
enum {
kOKCmd = 'ok ',
kCloseCmd = 'clos'
};
static const string EmptyString("");
#define kLineHeight 12
#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: Menu.cxx,v 1.4 2005-03-13 03:38:40 stephena Exp $
// $Id: Menu.cxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
//============================================================================
#include <SDL.h>
@ -30,20 +30,27 @@ Menu::Menu(OSystem* osystem)
: myOSystem(osystem),
myOptionsDialog(NULL)
{
cerr << "Menu::Menu()\n";
myOSystem->attach(this);
// Create the top-level menu
myOptionsDialog = new OptionsDialog(myOSystem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Menu::~Menu()
{
cerr << "Menu::~Menu()\n";
if(myOptionsDialog)
delete myOptionsDialog;
}
delete myOptionsDialog;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Menu::initialize()
{
if(myOptionsDialog)
{
delete myOptionsDialog;
myOptionsDialog = NULL;
}
// Create the top-level menu
myOptionsDialog = new OptionsDialog(myOSystem);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -61,25 +68,28 @@ void Menu::draw()
void Menu::addDialog(Dialog* d)
{
myDialogStack.push(d);
myOSystem->frameBuffer().refresh();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Menu::removeDialog()
{
if(!myDialogStack.empty())
{
myDialogStack.pop();
myOSystem->frameBuffer().refresh();
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Menu::reset()
void Menu::reStack()
{
// Pop all items from the stack, and then add the base menu
for(Int32 i = 0; i < myDialogStack.size(); i++)
while(!myDialogStack.empty())
{
Dialog* d = myDialogStack.pop();
d->close();
}
myDialogStack.push(myOptionsDialog);
}
@ -98,3 +108,48 @@ void Menu::handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state)
else
activeDialog->handleKeyUp(key, key, mod);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Menu::handleMouseMotionEvent(Int32 x, Int32 y, Int32 button)
{
if(myDialogStack.empty())
return;
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
activeDialog->handleMouseMoved(x - activeDialog->_x,
y - activeDialog->_y,
button);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Menu::handleMouseButtonEvent(MouseButton b, Int32 x, Int32 y, uInt8 state)
{
if(myDialogStack.empty())
return;
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
// We don't currently use 'clickCount'
switch(b)
{
case EVENT_LBUTTONDOWN:
case EVENT_RBUTTONDOWN:
activeDialog->handleMouseDown(x - activeDialog->_x, y - activeDialog->_y, 1, 1);
break;
case EVENT_LBUTTONUP:
case EVENT_RBUTTONUP:
activeDialog->handleMouseUp(x - activeDialog->_x, y - activeDialog->_y, 1, 1);
break;
case EVENT_WHEELUP:
activeDialog->handleMouseWheel(x - activeDialog->_x, y - activeDialog->_y, -1);
break;
case EVENT_WHEELDOWN:
activeDialog->handleMouseWheel(x - activeDialog->_x, y - activeDialog->_y, 1);
break;
}
}

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: Menu.hxx,v 1.3 2005-03-11 23:36:30 stephena Exp $
// $Id: Menu.hxx,v 1.4 2005-03-14 04:08:15 stephena Exp $
//============================================================================
#ifndef MENU_HXX
@ -26,6 +26,7 @@ class OptionsDialog;
#include <SDL.h>
#include "Stack.hxx"
#include "EventHandler.hxx"
#include "bspf.hxx"
typedef FixedStack<Dialog *> DialogStack;
@ -37,7 +38,7 @@ typedef FixedStack<Dialog *> DialogStack;
a stack, and handles their events.
@author Stephen Anthony
@version $Id: Menu.hxx,v 1.3 2005-03-11 23:36:30 stephena Exp $
@version $Id: Menu.hxx,v 1.4 2005-03-14 04:08:15 stephena Exp $
*/
class Menu
{
@ -60,9 +61,34 @@ class Menu
@param mod modifiers
@param state state of key
*/
void handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state);
void handleKeyEvent(SDLKey key, SDLMod mod, uInt8 state); //FIXME - this shouldn't refer to SDL directly
// FIXME - add mouse and joystick handlers
/**
Handle a mouse motion event.
@param x The x location
@param y The y location
@param button The currently pressed button
*/
void handleMouseMotionEvent(Int32 x, Int32 y, Int32 button);
/**
Handle a mouse button event.
@param b The mouse button
@param x The x location
@param y The y location
@param state The state (pressed or released)
*/
void handleMouseButtonEvent(MouseButton b, Int32 x, Int32 y, uInt8 state);
// FIXME - add joystick handler
/**
(Re)initialize the menuing system. This is necessary if a new Console
has been loaded, since in most cases the screen dimensions will have changed.
*/
void initialize();
/**
Draw the stack of menus.
@ -82,7 +108,7 @@ class Menu
/**
Reset dialog stack to the main configuration menu
*/
void reset();
void reStack();
private:
OSystem* myOSystem;

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: OptionsDialog.cxx,v 1.4 2005-03-13 03:38:40 stephena Exp $
// $Id: OptionsDialog.cxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -24,6 +24,7 @@
#include "Dialog.hxx"
#include "Widget.hxx"
#include "Control.hxx"
#include "VideoDialog.hxx"
#include "OptionsDialog.hxx"
#include "bspf.hxx"
@ -45,19 +46,17 @@ enum {
};
#define addBigButton(label, cmd, hotkey) \
new ButtonWidget(this, x, y, kBigButtonWidth, 18, label, cmd, hotkey); y += kRowHeight
new ButtonWidget(this, xoffset, yoffset, kBigButtonWidth, 18, label, cmd, hotkey); yoffset += kRowHeight
OptionsDialog::OptionsDialog(OSystem* osystem)
: Dialog(osystem, (320 - kMainMenuWidth) / 2, (200 - kMainMenuHeight)/2, kMainMenuWidth, kMainMenuHeight)
/* FIXME - make this depend on the framebuffer dimensions
: Dialog(osystem, (osystem->frameBuffer().width() - kMainMenuWidth) / 2,
(osystem->frameBuffer().height() - kMainMenuHeight)/2,
kMainMenuWidth, kMainMenuHeight)
*/
kMainMenuWidth, kMainMenuHeight),
myVideoDialog(NULL)
{
int y = 7;
int yoffset = 7;
const int xoffset = (_w - kBigButtonWidth) / 2;
const int x = (_w - kBigButtonWidth) / 2;
addBigButton("Video Settings", kVidCmd, 'V');
addBigButton("Audio Settings", kAudCmd, 'A');
addBigButton("Event Remapping", kEMapCmd, 'E');
@ -65,9 +64,23 @@ OptionsDialog::OptionsDialog(OSystem* osystem)
addBigButton("Game Information", kInfoCmd, 'I');
addBigButton("Help", kHelpCmd, 'H');
/*
// Set some sane values for the dialog boxes
uInt32 fbWidth = osystem->frameBuffer().width();
uInt32 fbHeight = osystem->frameBuffer().height();
uInt16 x, y, w, h;
// Now create all the dialogs attached to each menu button
myVideoDialog = new VideoDialog(myOSystem);
w = 250; h = 150;
if(w > fbWidth) w = fbWidth;
if(h > fbHeight) h = fbHeight;
x = (fbWidth - w) / 2;
y = (fbHeight - h) / 2;
myVideoDialog = new VideoDialog(myOSystem, x, y, w, h);
/*
myAudioDialog = new AudioDialog(myOSystem);
myEventMappingDialog = new EventMappingDialog(myOSystem);
myMiscDialog = new MiscDialog(myOSystem);
@ -78,8 +91,8 @@ OptionsDialog::OptionsDialog(OSystem* osystem)
OptionsDialog::~OptionsDialog()
{
/* FIXME
delete myVideoDialog;
/* FIXME
delete myAudioDialog;
delete myEventMappingDialog;
delete myMiscDialog;
@ -93,8 +106,7 @@ void OptionsDialog::handleCommand(CommandSender* sender, uInt32 cmd, uInt32 data
switch(cmd)
{
case kVidCmd:
// instance()->menu().addDialog(myVideoDialog);
cerr << "push VideoDialog to top of stack\n";
instance()->menu().addDialog(myVideoDialog);
break;
case kAudCmd:

View File

@ -0,0 +1,363 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PopUpWidget.cxx,v 1.1 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "bspf.hxx"
#include "OSystem.hxx"
#include "FrameBuffer.hxx"
#include "Stack.hxx"
#include "Menu.hxx"
#include "Dialog.hxx"
#include "GuiUtils.hxx"
#include "PopUpWidget.hxx"
#define UP_DOWN_BOX_HEIGHT 10
// Little up/down arrow
static uInt32 up_down_arrows[8] = {
0x00000000,
0x00001000,
0x00011100,
0x00111110,
0x00000000,
0x00111110,
0x00011100,
0x00001000,
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PopUpDialog::PopUpDialog(PopUpWidget* boss, Int32 clickX, Int32 clickY)
: Dialog(boss->instance(), 0, 0, 16, 16),
_popUpBoss(boss)
{
// Copy the selection index
_selection = _popUpBoss->_selectedItem;
// Calculate real popup dimensions
_x = _popUpBoss->getAbsX() + _popUpBoss->_labelWidth;
_y = _popUpBoss->getAbsY() - _popUpBoss->_selectedItem * kLineHeight;
_h = _popUpBoss->_entries.size() * kLineHeight + 2;
_w = _popUpBoss->_w - 10 - _popUpBoss->_labelWidth;
// Perform clipping / switch to scrolling mode if we don't fit on the screen
// FIXME - hard coded screen height 200. We really need an API in OSystem to query the
// screen height, and also OSystem should send out notification messages when the screen
// resolution changes... we could generalize CommandReceiver and CommandSender.
if(_h >= 200) // FIXME - change this to actual height of the window
_h = 199;
if(_y < 0)
_y = 0;
else if(_y + _h >= 200)
_y = 199 - _h;
// TODO - implement scrolling if we had to move the menu, or if there are too many entries
// Remember original mouse position
_clickX = clickX - _x;
_clickY = clickY - _y;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::drawDialog()
{
FrameBuffer& fb = _popUpBoss->instance()->frameBuffer();
// Draw the menu border
fb.hLine(_x, _y, _x+_w - 1, kColor);
fb.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
fb.vLine(_x, _y, _y+_h - 1, kColor);
fb.vLine(_x + _w - 1, _y, _y + _h - 1, kShadowColor);
// Draw the entries
Int32 count = _popUpBoss->_entries.size();
for(Int32 i = 0; i < count; i++)
drawMenuEntry(i, i == _selection);
fb.addDirtyRect(_x, _y, _w, _h);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::handleMouseDown(Int32 x, Int32 y, Int32 button, Int32 clickCount)
{
_clickX = -1;
_clickY = -1;
_openTime = (uInt32)-1;
// We remove the dialog and delete the dialog when the user has selected an item
_popUpBoss->instance()->menu().removeDialog();
delete this;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::handleMouseWheel(Int32 x, Int32 y, Int32 direction)
{
if(direction < 0)
moveUp();
else if(direction > 0)
moveDown();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::handleMouseMoved(Int32 x, Int32 y, Int32 button)
{
// Compute over which item the mouse is...
Int32 item = findItem(x, y);
if(item >= 0 && _popUpBoss->_entries[item].name.size() == 0)
item = -1;
if(item == -1 && !isMouseDown())
return;
// ...and update the selection accordingly
setSelection(item);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::handleKeyDown(uInt16 ascii, Int32 keycode, Int32 modifiers)
{
if(isMouseDown())
return;
switch(keycode)
{
case '\n': // enter/return
case '\r':
setResult(_selection);
close();
break;
case 256+17: // up arrow
moveUp();
break;
case 256+18: // down arrow
moveDown();
break;
case 256+22: // home
setSelection(0);
break;
case 256+23: // end
setSelection(_popUpBoss->_entries.size()-1);
break;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 PopUpDialog::findItem(Int32 x, Int32 y) const
{
if(x >= 0 && x < _w && y >= 0 && y < _h)
return (y-2) / kLineHeight;
return -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::setSelection(Int32 item)
{
if(item != _selection)
{
// Undraw old selection
if(_selection >= 0)
drawMenuEntry(_selection, false);
// Change selection
_selection = item;
_popUpBoss->_selectedItem = item;
// Draw new selection
if(item >= 0)
drawMenuEntry(item, true);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PopUpDialog::isMouseDown()
{
// TODO/FIXME - need a way to determine whether any mouse buttons are pressed or not.
// Sure, we could just count mouse button up/down events, but that is cumbersome and
// error prone. Would be much nicer to add an API to OSystem for this...
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::moveUp()
{
if(_selection < 0)
{
setSelection(_popUpBoss->_entries.size() - 1);
}
else if(_selection > 0)
{
Int32 item = _selection;
do {
item--;
} while (item >= 0 && _popUpBoss->_entries[item].name.size() == 0);
if(item >= 0)
setSelection(item);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::moveDown()
{
Int32 lastItem = _popUpBoss->_entries.size() - 1;
if(_selection < 0)
{
setSelection(0);
}
else if(_selection < lastItem)
{
Int32 item = _selection;
do {
item++;
} while (item <= lastItem && _popUpBoss->_entries[item].name.size() == 0);
if(item <= lastItem)
setSelection(item);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpDialog::drawMenuEntry(Int32 entry, bool hilite)
{
// Draw one entry of the popup menu, including selection
assert(entry >= 0);
Int32 x = _x + 1;
Int32 y = _y + 1 + kLineHeight * entry;
Int32 w = _w - 2;
string& name = _popUpBoss->_entries[entry].name;
FrameBuffer& fb = _popUpBoss->instance()->frameBuffer();
fb.fillRect(x, y, w, kLineHeight, hilite ? kTextColorHi : kBGColor);
if(name.size() == 0)
{
// Draw a separator
fb.hLine(x - 1, y + kLineHeight / 2, x + w, kShadowColor);
fb.hLine(x, y + 1 + kLineHeight / 2, x + w, kColor);
}
else
fb.font().drawString(name, x + 1, y + 2, w - 2, hilite ? kBGColor : kTextColor);
fb.addDirtyRect(x, y, w, kLineHeight);
}
//
// PopUpWidget
//
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PopUpWidget::PopUpWidget(GuiObject* boss, Int32 x, Int32 y, Int32 w, Int32 h,
const string& label, uInt32 labelWidth)
: Widget(boss, x, y - 1, w, h + 2),
CommandSender(boss),
_label(label),
_labelWidth(labelWidth)
{
_flags = WIDGET_ENABLED | WIDGET_CLEARBG | WIDGET_RETAIN_FOCUS;
_type = kPopUpWidget;
_selectedItem = -1;
if(!_label.empty() && _labelWidth == 0)
_labelWidth = instance()->frameBuffer().font().getStringWidth(_label);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::handleMouseDown(Int32 x, Int32 y, Int32 button, Int32 clickCount)
{
if(isEnabled())
{
myPopUpDialog = new PopUpDialog(this, x + getAbsX(), y + getAbsY());
instance()->menu().addDialog(myPopUpDialog);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::appendEntry(const string& entry, uInt32 tag)
{
Entry e;
e.name = entry;
e.tag = tag;
_entries.push_back(e);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::clearEntries()
{
_entries.clear();
_selectedItem = -1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::setSelected(Int32 item)
{
if(item != _selectedItem)
{
if(item >= 0 && item < (int)_entries.size())
_selectedItem = item;
else
_selectedItem = -1;
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::setSelectedTag(uInt32 tag)
{
for(uInt32 item = 0; item < _entries.size(); ++item)
{
if(_entries[item].tag == tag)
{
setSelected(item);
return;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PopUpWidget::drawWidget(bool hilite)
{
FrameBuffer& fb = instance()->frameBuffer();
Int32 x = _x + _labelWidth;
Int32 w = _w - _labelWidth;
// Draw the label, if any
if (_labelWidth > 0)
fb.font().drawString(_label, _x, _y + 3, _labelWidth,
isEnabled() ? kTextColor : kColor, kTextAlignRight);
// Draw a thin frame around us.
fb.hLine(x, _y, x + w - 1, kColor);
fb.hLine(x, _y +_h-1, x + w - 1, kShadowColor);
fb.vLine(x, _y, _y+_h-1, kColor);
fb.vLine(x + w - 1, _y, _y +_h - 1, kShadowColor);
// Draw an arrow pointing down at the right end to signal this is a dropdown/popup
// fb.drawBitmap(up_down_arrows, x+w - 10, _y+2,
// FIXME !isEnabled() ? kColor : hilite ? kTextColorHi : kTextColor);
// Draw the selected entry, if any
if(_selectedItem >= 0)
{
TextAlignment align = (fb.font().getStringWidth(_entries[_selectedItem].name) > w-6) ?
kTextAlignRight : kTextAlignLeft;
fb.font().drawString(_entries[_selectedItem].name, x+2, _y+3, w-6,
!isEnabled() ? kColor : kTextColor, align);
}
}

View File

@ -0,0 +1,124 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: PopUpWidget.hxx,v 1.1 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef POPUP_WIDGET_HXX
#define POPUP_WIDGET_HXX
class GUIObject;
class PopUpDialog;
#include "Dialog.hxx"
#include "Widget.hxx"
#include "Command.hxx"
#include "Array.hxx"
#include "GuiUtils.hxx"
#include "bspf.hxx"
enum {
kPopUpItemSelectedCmd = 'POPs'
};
/**
* Popup or dropdown widget which, when clicked, "pop up" a list of items and
* lets the user pick on of them.
*
* Implementation wise, when the user selects an item, then a kPopUpItemSelectedCmd
* is broadcast, with data being equal to the tag value of the selected entry.
*/
class PopUpWidget : public Widget, public CommandSender
{
friend class PopUpDialog;
struct Entry {
string name;
uInt32 tag;
};
typedef Array<Entry> EntryList;
protected:
EntryList _entries;
Int32 _selectedItem;
string _label;
uInt32 _labelWidth;
public:
PopUpWidget(GuiObject* boss, Int32 x, Int32 y, Int32 w, Int32 h,
const string& label, uInt32 labelWidth = 0);
void handleMouseDown(Int32 x, Int32 y, Int32 button, Int32 clickCount);
void appendEntry(const string& entry, uInt32 tag = (uInt32)-1);
void clearEntries();
/** Select the entry at the given index. */
void setSelected(Int32 item);
/** Select the first entry matching the given tag. */
void setSelectedTag(uInt32 tag);
Int32 getSelected() const { return _selectedItem; }
uInt32 getSelectedTag() const { return (_selectedItem >= 0) ? _entries[_selectedItem].tag : (uInt32)-1; }
const string& getSelectedString() const { return (_selectedItem >= 0) ? _entries[_selectedItem].name : EmptyString; }
protected:
void drawWidget(bool hilite);
private:
PopUpDialog* myPopUpDialog;
};
//
// PopUpDialog
//
class PopUpDialog : public Dialog
{
protected:
PopUpWidget* _popUpBoss;
Int32 _clickX, _clickY;
uInt8* _buffer;
Int32 _selection;
uInt32 _openTime;
public:
PopUpDialog(PopUpWidget* boss, Int32 clickX, Int32 clickY);
void drawDialog();
void handleMouseDown(Int32 x, Int32 y, Int32 button, Int32 clickCount);
void handleMouseWheel(Int32 x, Int32 y, Int32 direction); // Scroll through entries with scroll wheel
void handleMouseMoved(Int32 x, Int32 y, Int32 button); // Redraw selections depending on mouse position
void handleKeyDown(uInt16 ascii, Int32 keycode, Int32 modifiers); // Scroll through entries with arrow keys etc.
protected:
void drawMenuEntry(Int32 entry, bool hilite);
Int32 findItem(Int32 x, Int32 y) const;
void setSelection(Int32 item);
bool isMouseDown();
void moveUp();
void moveDown();
};
#endif

View File

@ -0,0 +1,197 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoDialog.cxx,v 1.1 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#include "OSystem.hxx"
#include "Settings.hxx"
#include "Menu.hxx"
#include "Control.hxx"
#include "Widget.hxx"
#include "PopUpWidget.hxx"
#include "Dialog.hxx"
#include "VideoDialog.hxx"
#include "GuiUtils.hxx"
#include "bspf.hxx"
enum {
kVideoRowHeight = 12,
kVideoWidth = 200,
kVideoHeight = 100
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VideoDialog::VideoDialog(OSystem* osystem, uInt16 x, uInt16 y, uInt16 w, uInt16 h)
: Dialog(osystem, x, y, w, h),
myDriver(NULL)
{
int yoff = 10;
const int xoff = 2;
const int woff = _w - 120;
const int labelWidth = 65;
// Video driver (query FrameBuffer for what's supported)
myDriver = new PopUpWidget(this, xoff, yoff, woff, kLineHeight, "(*)Driver: ", labelWidth);
myDriver->appendEntry("<default>", 0);
myDriver->appendEntry("");
myDriver->appendEntry("First one", 1);
myDriver->appendEntry("Another one", 2);
yoff += kVideoRowHeight + 4;
// Video renderer
myRenderer = new PopUpWidget(this, xoff, yoff, woff, kLineHeight, "(*)Renderer: ", labelWidth);
myRenderer->appendEntry("<default>", 0);
myRenderer->appendEntry("");
myRenderer->appendEntry("Software", 1);
myRenderer->appendEntry("OpenGL", 2);
yoff += kVideoRowHeight + 4;
// Video filter
myFilter = new PopUpWidget(this, xoff, yoff, woff, kLineHeight, "Filter: ", labelWidth);
myFilter->appendEntry("<default>", 0);
myFilter->appendEntry("");
myFilter->appendEntry("Linear", 1);
myFilter->appendEntry("Nearest", 2);
yoff += kVideoRowHeight + 4;
// Aspect ratio FIXME - maybe this should be a slider ??
myAspectRatio = new PopUpWidget(this, xoff, yoff, woff, kLineHeight, "(*)Aspect: ", labelWidth);
myAspectRatio->appendEntry("<default>", 0);
myAspectRatio->appendEntry("");
myAspectRatio->appendEntry("1.0", 1);
myAspectRatio->appendEntry("1.1", 2);
myAspectRatio->appendEntry("1.2", 3);
myAspectRatio->appendEntry("1.3", 4);
myAspectRatio->appendEntry("1.4", 5);
/*
myAspectRatio->appendEntry("1.5", 6);
myAspectRatio->appendEntry("1.6", 7);
myAspectRatio->appendEntry("1.7", 8);
myAspectRatio->appendEntry("1.8", 9);
myAspectRatio->appendEntry("1.9", 10);
myAspectRatio->appendEntry("2.0", 11);
*/
yoff += kVideoRowHeight + 4;
// Palette
myPalette = new PopUpWidget(this, xoff, yoff, woff, kLineHeight, "Palette: ", labelWidth);
myPalette->appendEntry("<default>", 0);
myPalette->appendEntry("");
myPalette->appendEntry("Standard", 1);
myPalette->appendEntry("Original", 2);
myPalette->appendEntry("Z26", 3);
yoff += kVideoRowHeight + 4;
// Add OK & Cancel buttons
#ifndef MAC_OSX
addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "OK", kOKCmd, 0);
addButton(_w - (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0);
#else
addButton(_w - 2 * (kButtonWidth + 10), _h - 24, "OK", kOKCmd, 0);
addButton(_w - (kButtonWidth + 10), _h - 24, "Cancel", kCloseCmd, 0);
#endif
// Set the items according to current settings
loadConfig();
// FIXME - get list of video drivers from OSystem
// const Common::LanguageDescription *l = Common::g_languages;
// for (; l->code; ++l) {
// _langPopUp->appendEntry(l->description, l->id);
// }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
VideoDialog::~VideoDialog()
{
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::loadConfig()
{
string s;
bool b;
uInt32 i;
// Driver setting
myDriver->setSelectedTag(0); // FIXME
// Renderer setting
s = instance()->settings().getString("video");
if(s == "soft")
myRenderer->setSelectedTag(1);
else if(s == "gl")
myRenderer->setSelectedTag(2);
else
myRenderer->setSelectedTag(0);
// Filter setting
s = instance()->settings().getString("gl_filter");
if(s == "linear")
myFilter->setSelectedTag(1);
else if(s == "nearest")
myFilter->setSelectedTag(2);
else
myFilter->setSelectedTag(0);
// Aspect ratio
s = instance()->settings().getString("gl_aspect");
// TODO
// Palette
// Filter setting
s = instance()->settings().getString("palette");
if(s == "standard")
myPalette->setSelectedTag(1);
else if(s == "original")
myPalette->setSelectedTag(2);
else if(s == "z26")
myPalette->setSelectedTag(3);
else
myPalette->setSelectedTag(0);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::saveConfig()
{
cerr << "VideoDialog::saveConfig()\n";
string s;
// Palette
s = myPalette->getSelectedString();
instance()->settings().setString("palette", s);
instance()->console().togglePalette(s);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void VideoDialog::handleCommand(CommandSender* sender, uInt32 cmd, uInt32 data)
{
switch(cmd)
{
case kOKCmd:
saveConfig();
close();
break;
default:
Dialog::handleCommand(sender, cmd, data);
break;
}
}

View File

@ -0,0 +1,52 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2005 by Bradford W. Mott
//
// See the file "license" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//
// $Id: VideoDialog.hxx,v 1.1 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
//============================================================================
#ifndef VIDEO_DIALOG_HXX
#define VIDEO_DIALOG_HXX
class CommandSender;
class Dialog;
class PopUpWidget;
#include "OSystem.hxx"
#include "bspf.hxx"
class VideoDialog : public Dialog
{
public:
VideoDialog(OSystem* osystem, uInt16 x, uInt16 y, uInt16 w, uInt16 h);
~VideoDialog();
virtual void handleCommand(CommandSender* sender, uInt32 cmd, uInt32 data);
protected:
PopUpWidget* myDriver;
PopUpWidget* myRenderer;
PopUpWidget* myFilter;
PopUpWidget* myAspectRatio;
PopUpWidget* myPalette;
private:
void loadConfig();
void saveConfig();
};
#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: Widget.cxx,v 1.4 2005-03-13 03:38:41 stephena Exp $
// $Id: Widget.cxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -26,7 +26,7 @@
#include "Command.hxx"
#include "GuiObject.hxx"
#include "bspf.hxx"
#include "GuiUtils.hxx"
#include "Widget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -47,6 +47,7 @@ Widget::Widget(GuiObject* boss, Int32 x, Int32 y, Int32 w, Int32 h)
Widget::~Widget()
{
delete _next;
_next = NULL;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -172,8 +173,6 @@ void ButtonWidget::handleMouseUp(Int32 x, Int32 y, Int32 button, Int32 clickCoun
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ButtonWidget::drawWidget(bool hilite)
{
int kLineHeight = 10; //FIXME
FrameBuffer& fb = _boss->instance()->frameBuffer();
fb.font().drawString(_label, _x, _y + (_h - kLineHeight)/2 + 1, _w,
!isEnabled() ? kColor :

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: Widget.hxx,v 1.4 2005-03-13 03:38:41 stephena Exp $
// $Id: Widget.hxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
//
// Based on code from ScummVM - Scumm Interpreter
// Copyright (C) 2002-2004 The ScummVM project
@ -62,7 +62,7 @@ enum {
This is the base class for all widgets.
@author Stephen Anthony
@version $Id: Widget.hxx,v 1.4 2005-03-13 03:38:41 stephena Exp $
@version $Id: Widget.hxx,v 1.5 2005-03-14 04:08:15 stephena Exp $
*/
class Widget : public GuiObject
{
@ -199,13 +199,13 @@ class SliderWidget : public ButtonWidget
SliderWidget(GuiObject *boss, Int32 x, Int32 y, Int32 w, Int32 h, const string& label = "",
Int32 labelWidth = 0, Int32 cmd = 0, uInt8 hotkey = 0);
void setValue(Int32 value) { _value = value; }
Int32 getValue() const { return _value; }
void setValue(Int32 value) { _value = value; }
Int32 getValue() const { return _value; }
void setMinValue(Int32 value) { _valueMin = value; }
Int32 getMinValue() const { return _valueMin; }
void setMaxValue(Int32 value) { _valueMax = value; }
Int32 getMaxValue() const { return _valueMax; }
void setMinValue(Int32 value) { _valueMin = value; }
Int32 getMinValue() const { return _valueMin; }
void setMaxValue(Int32 value) { _valueMax = value; }
Int32 getMaxValue() const { return _valueMax; }
void handleMouseMoved(Int32 x, Int32 y, Int32 button);
void handleMouseDown(Int32 x, Int32 y, Int32 button, Int32 clickCount);