2003-09-25 16:20:34 +00:00
|
|
|
//============================================================================
|
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
2005-06-16 01:11:29 +00:00
|
|
|
// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team
|
2003-09-25 16:20:34 +00:00
|
|
|
//
|
|
|
|
// See the file "license" for information on usage and redistribution of
|
|
|
|
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
|
|
//
|
2005-07-20 17:33:03 +00:00
|
|
|
// $Id: FrameBuffer.cxx,v 1.56 2005-07-20 17:33:03 stephena Exp $
|
2003-09-25 16:20:34 +00:00
|
|
|
//============================================================================
|
|
|
|
|
2003-09-30 01:22:45 +00:00
|
|
|
#include <sstream>
|
|
|
|
|
2003-09-25 16:20:34 +00:00
|
|
|
#include "bspf.hxx"
|
|
|
|
#include "Console.hxx"
|
2003-09-26 00:32:00 +00:00
|
|
|
#include "Event.hxx"
|
The first version of a GUI for event remapping is here!
Now for the things that aren't finished yet:
- Only the most basic functions can be remapped. If you
erase the mapping for those that can't yet be remapped,
you'll have to delete the 'keymap' line from stellarc and
start over.
- Core events can only be remapped to other keys on the keyboard.
I haven't got the joystick remapping working yet (but it should
be easy to do).
- The TIA needs to be modified to show 320 pixels horizontally.
Right now, I'm using 8 pixel-width fonts on a framebuffer of
160 pixels, so there's not a lot of horizontal real estate.
So text will probably overwrite other stuff. This is cosmetic,
and WILL be fixed.
- Modification of the TIA will break every frontends rendering
code. It had to be done sometime ...
- I haven't yet added any user feedback mechanism for the user. So when
you go into remap mode and are about to remap a key, you won't
know it :) I'll be adding arrows (like in XMAME) ...
I've added a "Game Information" menu, which shows things like Game name,
manufacturer, rarity, type, etc. Basically stuff from the stella.pro file.
It has no purpose other than for coolness :)
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@193 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-09-28 21:59:24 +00:00
|
|
|
#include "EventHandler.hxx"
|
2003-09-25 16:20:34 +00:00
|
|
|
#include "Settings.hxx"
|
|
|
|
#include "MediaSrc.hxx"
|
2003-10-17 18:02:16 +00:00
|
|
|
#include "FrameBuffer.hxx"
|
2005-06-08 18:45:09 +00:00
|
|
|
#include "Font.hxx"
|
2005-03-13 03:38:41 +00:00
|
|
|
#include "GuiUtils.hxx"
|
2005-03-10 22:59:40 +00:00
|
|
|
#include "Menu.hxx"
|
Added first pass of the ROM launcher. When you press 'Start' in the ROM
launcher, it launches Frostbite. Then pressing 'Escape' goes back to the
launcher, and you're able to then launch Frostbite again! Success !!!
Still TODO is actually get a ROM listing and use the selected game, but
the fact that it works multiple times for some game means that the
infrastructure is working correctly :)
Changed behaviour of the 'Escape' key. Specifically, it now only acts
as a key to enter ROM launcher mode. In the case where the emulation
was started without the launcher, the key will now do nothing. From now
on, the only way to quit Stella is Ctrl-Q (or equivalent for OSX),
close the window, or from the 'Quit' button.
Also, the 'Enter launcher mode' event will eventually be made remappable,
as will the 'Enter menu mode' event (currently the 'Tab' key).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@412 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-05-06 18:39:00 +00:00
|
|
|
#include "Launcher.hxx"
|
2005-05-27 18:00:49 +00:00
|
|
|
#include "Debugger.hxx"
|
2005-02-21 02:23:57 +00:00
|
|
|
#include "OSystem.hxx"
|
|
|
|
|
|
|
|
#include "stella.xpm" // The Stella icon
|
2003-09-25 16:20:34 +00:00
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-02-21 20:43:53 +00:00
|
|
|
FrameBuffer::FrameBuffer(OSystem* osystem)
|
|
|
|
: myOSystem(osystem),
|
2005-06-23 14:33:12 +00:00
|
|
|
theRedrawTIAIndicator(true),
|
2005-07-20 15:52:58 +00:00
|
|
|
theRedrawOverlayIndicator(false),
|
2005-05-08 17:38:23 +00:00
|
|
|
theZoomLevel(2),
|
|
|
|
theMaxZoomLevel(2),
|
2005-02-21 02:23:57 +00:00
|
|
|
theAspectRatio(1.0),
|
2003-10-26 19:40:39 +00:00
|
|
|
myFrameRate(0),
|
2003-11-12 19:36:25 +00:00
|
|
|
myPauseStatus(false),
|
2005-07-20 15:52:58 +00:00
|
|
|
myMessageTime(-1),
|
2003-09-26 22:39:36 +00:00
|
|
|
myMessageText(""),
|
2005-04-24 01:57:47 +00:00
|
|
|
myNumRedraws(0)
|
2003-09-25 16:20:34 +00:00
|
|
|
{
|
2005-03-28 00:04:54 +00:00
|
|
|
myBaseDim.x = myBaseDim.y = myBaseDim.w = myBaseDim.h = 0;
|
|
|
|
myImageDim = myScreenDim = myDesktopDim = myBaseDim;
|
2003-10-17 18:02:16 +00:00
|
|
|
}
|
2003-10-01 19:01:02 +00:00
|
|
|
|
2003-10-17 18:02:16 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
FrameBuffer::~FrameBuffer(void)
|
|
|
|
{
|
|
|
|
}
|
2003-09-26 22:39:36 +00:00
|
|
|
|
2003-10-17 18:02:16 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-06 22:50:15 +00:00
|
|
|
void FrameBuffer::initialize(const string& title, uInt32 width, uInt32 height,
|
2005-05-16 00:02:32 +00:00
|
|
|
bool useAspect)
|
2003-10-17 18:02:16 +00:00
|
|
|
{
|
2005-02-22 18:41:16 +00:00
|
|
|
bool isAlreadyInitialized = (SDL_WasInit(SDL_INIT_VIDEO) & SDL_INIT_VIDEO) > 0;
|
2005-02-21 02:23:57 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
myBaseDim.w = (uInt16) width;
|
|
|
|
myBaseDim.h = (uInt16) height;
|
2005-05-12 18:45:21 +00:00
|
|
|
myFrameRate = myOSystem->frameRate();
|
2005-02-21 02:23:57 +00:00
|
|
|
|
2005-02-22 18:41:16 +00:00
|
|
|
// Now (re)initialize the SDL video system
|
|
|
|
if(!isAlreadyInitialized)
|
|
|
|
{
|
|
|
|
Uint32 initflags = SDL_INIT_VIDEO | SDL_INIT_TIMER;
|
|
|
|
|
|
|
|
if(SDL_Init(initflags) < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
setWindowIcon();
|
|
|
|
}
|
2005-02-21 02:23:57 +00:00
|
|
|
|
2005-04-29 19:05:06 +00:00
|
|
|
// Calculate the desktop size
|
|
|
|
myDesktopDim.w = myDesktopDim.h = 0;
|
|
|
|
|
|
|
|
// Get the system-specific WM information
|
|
|
|
SDL_SysWMinfo myWMInfo;
|
|
|
|
SDL_VERSION(&myWMInfo.version);
|
|
|
|
if(SDL_GetWMInfo(&myWMInfo) > 0)
|
|
|
|
{
|
|
|
|
#if defined(UNIX)
|
|
|
|
if(myWMInfo.subsystem == SDL_SYSWM_X11)
|
|
|
|
{
|
|
|
|
myWMInfo.info.x11.lock_func();
|
|
|
|
myDesktopDim.w = DisplayWidth(myWMInfo.info.x11.display,
|
|
|
|
DefaultScreen(myWMInfo.info.x11.display));
|
|
|
|
myDesktopDim.h = DisplayHeight(myWMInfo.info.x11.display,
|
|
|
|
DefaultScreen(myWMInfo.info.x11.display));
|
|
|
|
myWMInfo.info.x11.unlock_func();
|
|
|
|
}
|
|
|
|
#elif defined(WIN32)
|
|
|
|
myDesktopDim.w = (uInt16) GetSystemMetrics(SM_CXSCREEN);
|
|
|
|
myDesktopDim.h = (uInt16) GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
#elif defined(MAC_OSX)
|
|
|
|
// FIXME - add OSX Desktop code here (I don't think SDL supports it yet)
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set fullscreen flag
|
2005-02-21 02:23:57 +00:00
|
|
|
mySDLFlags = myOSystem->settings().getBool("fullscreen") ? SDL_FULLSCREEN : 0;
|
|
|
|
|
2005-02-22 18:41:16 +00:00
|
|
|
// Set window title
|
|
|
|
setWindowTitle(title);
|
|
|
|
|
2005-05-30 16:25:47 +00:00
|
|
|
// Get the aspect ratio for the display if it's been enabled
|
|
|
|
theAspectRatio = 1.0;
|
|
|
|
if(useAspect)
|
|
|
|
setAspectRatio();
|
2005-05-06 22:50:15 +00:00
|
|
|
|
2005-04-29 19:05:06 +00:00
|
|
|
// Get the maximum size of a window for the current desktop
|
|
|
|
theMaxZoomLevel = maxWindowSizeForScreen();
|
|
|
|
|
|
|
|
// Check to see if window size will fit in the screen
|
|
|
|
if((uInt32)myOSystem->settings().getInt("zoom") > theMaxZoomLevel)
|
|
|
|
theZoomLevel = theMaxZoomLevel;
|
|
|
|
else
|
|
|
|
theZoomLevel = myOSystem->settings().getInt("zoom");
|
|
|
|
|
2005-02-21 02:23:57 +00:00
|
|
|
// Initialize video subsystem
|
|
|
|
initSubsystem();
|
2005-05-12 18:45:21 +00:00
|
|
|
|
2005-07-19 17:59:59 +00:00
|
|
|
// Set emulation palette if a console exists
|
|
|
|
if(&myOSystem->console())
|
|
|
|
setPalette(myOSystem->console().mediaSource().palette());
|
|
|
|
|
2005-06-07 21:22:39 +00:00
|
|
|
// Enable unicode so we can see translated key events
|
|
|
|
// (lowercase vs. uppercase characters)
|
|
|
|
SDL_EnableUNICODE(1);
|
|
|
|
|
2005-05-12 18:45:21 +00:00
|
|
|
// Erase any messages from a previous run
|
|
|
|
myMessageTime = 0;
|
2003-10-26 19:40:39 +00:00
|
|
|
}
|
The first version of a GUI for event remapping is here!
Now for the things that aren't finished yet:
- Only the most basic functions can be remapped. If you
erase the mapping for those that can't yet be remapped,
you'll have to delete the 'keymap' line from stellarc and
start over.
- Core events can only be remapped to other keys on the keyboard.
I haven't got the joystick remapping working yet (but it should
be easy to do).
- The TIA needs to be modified to show 320 pixels horizontally.
Right now, I'm using 8 pixel-width fonts on a framebuffer of
160 pixels, so there's not a lot of horizontal real estate.
So text will probably overwrite other stuff. This is cosmetic,
and WILL be fixed.
- Modification of the TIA will break every frontends rendering
code. It had to be done sometime ...
- I haven't yet added any user feedback mechanism for the user. So when
you go into remap mode and are about to remap a key, you won't
know it :) I'll be adding arrows (like in XMAME) ...
I've added a "Game Information" menu, which shows things like Game name,
manufacturer, rarity, type, etc. Basically stuff from the stella.pro file.
It has no purpose other than for coolness :)
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@193 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-09-28 21:59:24 +00:00
|
|
|
|
2003-10-26 19:40:39 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::update()
|
|
|
|
{
|
|
|
|
// Do any pre-frame stuff
|
|
|
|
preFrameUpdate();
|
The first version of a GUI for event remapping is here!
Now for the things that aren't finished yet:
- Only the most basic functions can be remapped. If you
erase the mapping for those that can't yet be remapped,
you'll have to delete the 'keymap' line from stellarc and
start over.
- Core events can only be remapped to other keys on the keyboard.
I haven't got the joystick remapping working yet (but it should
be easy to do).
- The TIA needs to be modified to show 320 pixels horizontally.
Right now, I'm using 8 pixel-width fonts on a framebuffer of
160 pixels, so there's not a lot of horizontal real estate.
So text will probably overwrite other stuff. This is cosmetic,
and WILL be fixed.
- Modification of the TIA will break every frontends rendering
code. It had to be done sometime ...
- I haven't yet added any user feedback mechanism for the user. So when
you go into remap mode and are about to remap a key, you won't
know it :) I'll be adding arrows (like in XMAME) ...
I've added a "Game Information" menu, which shows things like Game name,
manufacturer, rarity, type, etc. Basically stuff from the stella.pro file.
It has no purpose other than for coolness :)
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@193 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-09-28 21:59:24 +00:00
|
|
|
|
2005-02-27 23:41:19 +00:00
|
|
|
// Determine which mode we are in (from the EventHandler)
|
|
|
|
// Take care of S_EMULATE mode here, otherwise let the GUI
|
|
|
|
// figure out what to draw
|
|
|
|
switch(myOSystem->eventHandler().state())
|
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending.
It's a work in progress right now, but is already quite stable.
It's not as optimized as the software version yet, but this will
change as well. For now, you have to compile the SDL version in
either normal software mode or OpenGL mode. This will change
before the 1.4 release.
When entering menu mode, the emulation is now suspended. And when
pause is pressed, you can't enter menu mode. Because of these changes,
CPU use has dropped dramatically when viewing menus. This will benefit
all ports, since menus are now redrawn only when necessary, instead of
at the current framerate.
For a reference, on a Pentium-IV 2.4GHz, the software SDL version
maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is
at 60 fps and a zoomlevel of 4. While some small improvements can
(possibly) be made to the OpenGL version, I think we'll soon be hitting
the glass ceiling.
Work on the Porting.txt document is progressing, and I estimate it to
be 45% complete.
The Windows version still doesn't compile, and I still haven't looked
at it. Rest assured that it will be done before 1.4. There will be
a simultaneous release, even if the Linux versions are finished.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-11-06 22:22:33 +00:00
|
|
|
{
|
2005-02-27 23:41:19 +00:00
|
|
|
case EventHandler::S_EMULATE:
|
|
|
|
{
|
|
|
|
// Draw changes to the mediasource
|
|
|
|
if(!myPauseStatus)
|
2005-06-29 00:31:49 +00:00
|
|
|
{
|
2005-02-27 23:41:19 +00:00
|
|
|
myOSystem->console().mediaSource().update();
|
2005-06-29 00:31:49 +00:00
|
|
|
if(myOSystem->eventHandler().frying())
|
|
|
|
myOSystem->console().fry();
|
|
|
|
}
|
2003-09-25 16:20:34 +00:00
|
|
|
|
2005-02-27 23:41:19 +00:00
|
|
|
// We always draw the screen, even if the core is paused
|
|
|
|
drawMediaSource();
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-02-27 23:41:19 +00:00
|
|
|
if(!myPauseStatus)
|
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending.
It's a work in progress right now, but is already quite stable.
It's not as optimized as the software version yet, but this will
change as well. For now, you have to compile the SDL version in
either normal software mode or OpenGL mode. This will change
before the 1.4 release.
When entering menu mode, the emulation is now suspended. And when
pause is pressed, you can't enter menu mode. Because of these changes,
CPU use has dropped dramatically when viewing menus. This will benefit
all ports, since menus are now redrawn only when necessary, instead of
at the current framerate.
For a reference, on a Pentium-IV 2.4GHz, the software SDL version
maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is
at 60 fps and a zoomlevel of 4. While some small improvements can
(possibly) be made to the OpenGL version, I think we'll soon be hitting
the glass ceiling.
Work on the Porting.txt document is progressing, and I estimate it to
be 45% complete.
The Windows version still doesn't compile, and I still haven't looked
at it. Rest assured that it will be done before 1.4. There will be
a simultaneous release, even if the Linux versions are finished.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-11-06 22:22:33 +00:00
|
|
|
{
|
2005-02-27 23:41:19 +00:00
|
|
|
// Draw any pending messages
|
|
|
|
if(myMessageTime > 0)
|
|
|
|
{
|
2005-06-08 18:45:09 +00:00
|
|
|
int w = myOSystem->font().getStringWidth(myMessageText) + 10;
|
|
|
|
int h = myOSystem->font().getFontHeight() + 8;
|
2005-05-16 00:02:32 +00:00
|
|
|
int x = (myBaseDim.w >> 1) - (w >> 1);
|
|
|
|
int y = myBaseDim.h - h - 10/2;
|
2005-02-27 23:41:19 +00:00
|
|
|
|
|
|
|
// Draw the bounded box and text
|
2005-03-26 19:26:48 +00:00
|
|
|
blendRect(x+1, y+2, w-2, h-4, kBGColor);
|
2005-03-13 03:38:41 +00:00
|
|
|
box(x, y+1, w, h-2, kColor, kColor);
|
2005-06-14 01:11:48 +00:00
|
|
|
drawString(&myOSystem->font(), myMessageText, x+1, y+4, w, kTextColor, kTextAlignCenter);
|
2005-02-27 23:41:19 +00:00
|
|
|
myMessageTime--;
|
|
|
|
|
|
|
|
// Erase this message on next update
|
|
|
|
if(myMessageTime == 0)
|
2005-07-20 15:52:58 +00:00
|
|
|
{
|
|
|
|
myMessageTime = -1;
|
|
|
|
theRedrawTIAIndicator = true;
|
|
|
|
}
|
2005-02-27 23:41:19 +00:00
|
|
|
}
|
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending.
It's a work in progress right now, but is already quite stable.
It's not as optimized as the software version yet, but this will
change as well. For now, you have to compile the SDL version in
either normal software mode or OpenGL mode. This will change
before the 1.4 release.
When entering menu mode, the emulation is now suspended. And when
pause is pressed, you can't enter menu mode. Because of these changes,
CPU use has dropped dramatically when viewing menus. This will benefit
all ports, since menus are now redrawn only when necessary, instead of
at the current framerate.
For a reference, on a Pentium-IV 2.4GHz, the software SDL version
maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is
at 60 fps and a zoomlevel of 4. While some small improvements can
(possibly) be made to the OpenGL version, I think we'll soon be hitting
the glass ceiling.
Work on the Porting.txt document is progressing, and I estimate it to
be 45% complete.
The Windows version still doesn't compile, and I still haven't looked
at it. Rest assured that it will be done before 1.4. There will be
a simultaneous release, even if the Linux versions are finished.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-11-06 22:22:33 +00:00
|
|
|
}
|
2005-02-27 23:41:19 +00:00
|
|
|
break; // S_EMULATE
|
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending.
It's a work in progress right now, but is already quite stable.
It's not as optimized as the software version yet, but this will
change as well. For now, you have to compile the SDL version in
either normal software mode or OpenGL mode. This will change
before the 1.4 release.
When entering menu mode, the emulation is now suspended. And when
pause is pressed, you can't enter menu mode. Because of these changes,
CPU use has dropped dramatically when viewing menus. This will benefit
all ports, since menus are now redrawn only when necessary, instead of
at the current framerate.
For a reference, on a Pentium-IV 2.4GHz, the software SDL version
maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is
at 60 fps and a zoomlevel of 4. While some small improvements can
(possibly) be made to the OpenGL version, I think we'll soon be hitting
the glass ceiling.
Work on the Porting.txt document is progressing, and I estimate it to
be 45% complete.
The Windows version still doesn't compile, and I still haven't looked
at it. Rest assured that it will be done before 1.4. There will be
a simultaneous release, even if the Linux versions are finished.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-11-06 22:22:33 +00:00
|
|
|
}
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-03-13 03:38:41 +00:00
|
|
|
case EventHandler::S_MENU:
|
2005-02-27 23:41:19 +00:00
|
|
|
{
|
2005-05-28 17:25:41 +00:00
|
|
|
// Only update the screen if it's been invalidated
|
2005-06-23 14:33:12 +00:00
|
|
|
if(theRedrawTIAIndicator)
|
2005-02-27 23:41:19 +00:00
|
|
|
drawMediaSource();
|
|
|
|
|
2005-05-28 17:25:41 +00:00
|
|
|
// Only update the overlay if it's changed
|
2005-06-23 14:33:12 +00:00
|
|
|
if(theRedrawOverlayIndicator)
|
2005-03-10 22:59:40 +00:00
|
|
|
myOSystem->menu().draw();
|
2005-02-27 23:41:19 +00:00
|
|
|
|
2005-07-20 15:52:58 +00:00
|
|
|
break; // S_MENU
|
2005-02-27 23:41:19 +00:00
|
|
|
}
|
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending.
It's a work in progress right now, but is already quite stable.
It's not as optimized as the software version yet, but this will
change as well. For now, you have to compile the SDL version in
either normal software mode or OpenGL mode. This will change
before the 1.4 release.
When entering menu mode, the emulation is now suspended. And when
pause is pressed, you can't enter menu mode. Because of these changes,
CPU use has dropped dramatically when viewing menus. This will benefit
all ports, since menus are now redrawn only when necessary, instead of
at the current framerate.
For a reference, on a Pentium-IV 2.4GHz, the software SDL version
maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is
at 60 fps and a zoomlevel of 4. While some small improvements can
(possibly) be made to the OpenGL version, I think we'll soon be hitting
the glass ceiling.
Work on the Porting.txt document is progressing, and I estimate it to
be 45% complete.
The Windows version still doesn't compile, and I still haven't looked
at it. Rest assured that it will be done before 1.4. There will be
a simultaneous release, even if the Linux versions are finished.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-11-06 22:22:33 +00:00
|
|
|
|
Added first pass of the ROM launcher. When you press 'Start' in the ROM
launcher, it launches Frostbite. Then pressing 'Escape' goes back to the
launcher, and you're able to then launch Frostbite again! Success !!!
Still TODO is actually get a ROM listing and use the selected game, but
the fact that it works multiple times for some game means that the
infrastructure is working correctly :)
Changed behaviour of the 'Escape' key. Specifically, it now only acts
as a key to enter ROM launcher mode. In the case where the emulation
was started without the launcher, the key will now do nothing. From now
on, the only way to quit Stella is Ctrl-Q (or equivalent for OSX),
close the window, or from the 'Quit' button.
Also, the 'Enter launcher mode' event will eventually be made remappable,
as will the 'Enter menu mode' event (currently the 'Tab' key).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@412 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-05-06 18:39:00 +00:00
|
|
|
case EventHandler::S_LAUNCHER:
|
|
|
|
{
|
2005-05-28 17:25:41 +00:00
|
|
|
// Only update the screen if it's been invalidated or the overlay have changed
|
2005-06-23 14:33:12 +00:00
|
|
|
if(theRedrawOverlayIndicator)
|
Added first pass of the ROM launcher. When you press 'Start' in the ROM
launcher, it launches Frostbite. Then pressing 'Escape' goes back to the
launcher, and you're able to then launch Frostbite again! Success !!!
Still TODO is actually get a ROM listing and use the selected game, but
the fact that it works multiple times for some game means that the
infrastructure is working correctly :)
Changed behaviour of the 'Escape' key. Specifically, it now only acts
as a key to enter ROM launcher mode. In the case where the emulation
was started without the launcher, the key will now do nothing. From now
on, the only way to quit Stella is Ctrl-Q (or equivalent for OSX),
close the window, or from the 'Quit' button.
Also, the 'Enter launcher mode' event will eventually be made remappable,
as will the 'Enter menu mode' event (currently the 'Tab' key).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@412 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-05-06 18:39:00 +00:00
|
|
|
myOSystem->launcher().draw();
|
|
|
|
|
2005-07-20 15:52:58 +00:00
|
|
|
break; // S_LAUNCHER
|
Added first pass of the ROM launcher. When you press 'Start' in the ROM
launcher, it launches Frostbite. Then pressing 'Escape' goes back to the
launcher, and you're able to then launch Frostbite again! Success !!!
Still TODO is actually get a ROM listing and use the selected game, but
the fact that it works multiple times for some game means that the
infrastructure is working correctly :)
Changed behaviour of the 'Escape' key. Specifically, it now only acts
as a key to enter ROM launcher mode. In the case where the emulation
was started without the launcher, the key will now do nothing. From now
on, the only way to quit Stella is Ctrl-Q (or equivalent for OSX),
close the window, or from the 'Quit' button.
Also, the 'Enter launcher mode' event will eventually be made remappable,
as will the 'Enter menu mode' event (currently the 'Tab' key).
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@412 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2005-05-06 18:39:00 +00:00
|
|
|
}
|
2004-06-23 03:43:47 +00:00
|
|
|
|
2005-02-27 23:41:19 +00:00
|
|
|
case EventHandler::S_DEBUGGER:
|
2005-06-23 14:33:12 +00:00
|
|
|
{
|
2005-05-28 17:25:41 +00:00
|
|
|
// Only update the overlay if it's changed
|
2005-07-20 15:52:58 +00:00
|
|
|
// This is a performance hack to only draw the menus when necessary
|
2005-06-23 14:33:12 +00:00
|
|
|
if(theRedrawOverlayIndicator)
|
2005-05-27 18:00:49 +00:00
|
|
|
myOSystem->debugger().draw();
|
|
|
|
|
|
|
|
break; // S_DEBUGGER
|
2005-06-23 14:33:12 +00:00
|
|
|
}
|
2005-02-27 23:41:19 +00:00
|
|
|
|
|
|
|
case EventHandler::S_NONE:
|
|
|
|
return;
|
|
|
|
break;
|
2003-10-26 19:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Do any post-frame stuff
|
|
|
|
postFrameUpdate();
|
2005-07-20 17:33:03 +00:00
|
|
|
|
|
|
|
// The frame doesn't need to be completely redrawn anymore
|
|
|
|
theRedrawTIAIndicator = theRedrawOverlayIndicator = false;
|
2003-09-25 16:20:34 +00:00
|
|
|
}
|
|
|
|
|
2005-06-23 14:33:12 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::refreshTIA(bool now)
|
|
|
|
{
|
|
|
|
// cerr << "refreshTIA() " << myNumRedraws++ << endl;
|
|
|
|
theRedrawTIAIndicator = true;
|
|
|
|
if(now)
|
|
|
|
{
|
|
|
|
myMessageTime = 0;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::refreshOverlay(bool now)
|
|
|
|
{
|
|
|
|
// cerr << "refreshOverlay()\n";
|
|
|
|
if(myOSystem->eventHandler().state() == EventHandler::S_MENU)
|
|
|
|
refreshTIA(now);
|
|
|
|
|
|
|
|
theRedrawOverlayIndicator = true;
|
|
|
|
if(now) update();
|
2005-07-15 18:19:29 +00:00
|
|
|
}
|
|
|
|
|
2005-03-13 03:38:41 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::showMessage(const string& message)
|
|
|
|
{
|
|
|
|
myMessageText = message;
|
|
|
|
myMessageTime = myFrameRate << 1; // Show message for 2 seconds
|
|
|
|
}
|
|
|
|
|
2003-09-25 16:20:34 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-03-28 00:04:54 +00:00
|
|
|
void FrameBuffer::pause(bool status)
|
2003-09-25 16:20:34 +00:00
|
|
|
{
|
2005-03-28 00:04:54 +00:00
|
|
|
myPauseStatus = status;
|
2003-09-26 17:35:05 +00:00
|
|
|
}
|
2003-09-25 16:20:34 +00:00
|
|
|
|
2003-10-26 19:40:39 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-05 00:10:49 +00:00
|
|
|
void FrameBuffer::setPalette(const uInt32* palette)
|
2003-10-26 19:40:39 +00:00
|
|
|
{
|
2005-03-28 00:04:54 +00:00
|
|
|
for(uInt32 i = 0; i < 256; ++i)
|
|
|
|
{
|
|
|
|
Uint8 r, g, b;
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-05-05 00:10:49 +00:00
|
|
|
r = (Uint8) ((palette[i] & 0x00ff0000) >> 16);
|
|
|
|
g = (Uint8) ((palette[i] & 0x0000ff00) >> 8);
|
|
|
|
b = (Uint8) (palette[i] & 0x000000ff);
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
myPalette[i] = mapRGB(r, g, b);
|
|
|
|
}
|
|
|
|
|
2005-06-23 14:33:12 +00:00
|
|
|
theRedrawTIAIndicator = true;
|
2003-10-26 19:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-01 20:11:07 +00:00
|
|
|
void FrameBuffer::toggleFullscreen()
|
2003-10-26 19:40:39 +00:00
|
|
|
{
|
2005-05-01 20:11:07 +00:00
|
|
|
setFullscreen(!myOSystem->settings().getBool("fullscreen"));
|
|
|
|
}
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-05-01 20:11:07 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::setFullscreen(bool enable)
|
|
|
|
{
|
2005-03-28 00:04:54 +00:00
|
|
|
// Update the settings
|
2005-05-01 20:11:07 +00:00
|
|
|
myOSystem->settings().setBool("fullscreen", enable);
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-05-01 20:11:07 +00:00
|
|
|
if(enable)
|
2005-03-28 00:04:54 +00:00
|
|
|
mySDLFlags |= SDL_FULLSCREEN;
|
|
|
|
else
|
|
|
|
mySDLFlags &= ~SDL_FULLSCREEN;
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
if(!createScreen())
|
|
|
|
return;
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
setCursorState();
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-05-01 20:11:07 +00:00
|
|
|
void FrameBuffer::resize(Size size, Int8 zoom)
|
2005-03-28 00:04:54 +00:00
|
|
|
{
|
2005-05-01 20:11:07 +00:00
|
|
|
switch(size)
|
2003-10-26 19:40:39 +00:00
|
|
|
{
|
2005-05-01 20:11:07 +00:00
|
|
|
case PreviousSize: // decrease size
|
2005-03-28 00:04:54 +00:00
|
|
|
if(myOSystem->settings().getBool("fullscreen"))
|
|
|
|
return;
|
2005-05-01 20:11:07 +00:00
|
|
|
if(theZoomLevel == 1)
|
|
|
|
theZoomLevel = theMaxZoomLevel;
|
|
|
|
else
|
|
|
|
theZoomLevel--;
|
|
|
|
break;
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-05-01 20:11:07 +00:00
|
|
|
case NextSize: // increase size
|
|
|
|
if(myOSystem->settings().getBool("fullscreen"))
|
|
|
|
return;
|
2005-03-28 00:04:54 +00:00
|
|
|
if(theZoomLevel == theMaxZoomLevel)
|
|
|
|
theZoomLevel = 1;
|
|
|
|
else
|
|
|
|
theZoomLevel++;
|
2005-05-01 20:11:07 +00:00
|
|
|
break;
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-05-01 20:11:07 +00:00
|
|
|
case GivenSize: // use 'zoom' quantity
|
|
|
|
if(zoom < 1)
|
|
|
|
theZoomLevel = 1;
|
|
|
|
else if((uInt32)zoom > theMaxZoomLevel)
|
2005-03-28 00:04:54 +00:00
|
|
|
theZoomLevel = theMaxZoomLevel;
|
|
|
|
else
|
2005-05-01 20:11:07 +00:00
|
|
|
theZoomLevel = zoom;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default: // should never happen
|
|
|
|
return;
|
|
|
|
break;
|
2003-10-26 19:40:39 +00:00
|
|
|
}
|
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
if(!createScreen())
|
|
|
|
return;
|
2003-10-26 19:40:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-03-28 00:04:54 +00:00
|
|
|
void FrameBuffer::setCursorState()
|
2003-10-26 19:40:39 +00:00
|
|
|
{
|
2005-03-28 00:04:54 +00:00
|
|
|
bool isFullscreen = myOSystem->settings().getBool("fullscreen");
|
2005-05-06 22:50:15 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
if(isFullscreen)
|
|
|
|
grabMouse(true);
|
2005-05-06 22:50:15 +00:00
|
|
|
else
|
|
|
|
grabMouse(myOSystem->settings().getBool("grabmouse"));
|
2003-10-26 19:40:39 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
switch(myOSystem->eventHandler().state())
|
|
|
|
{
|
|
|
|
case EventHandler::S_EMULATE:
|
2005-05-06 22:50:15 +00:00
|
|
|
showCursor(false);
|
2005-03-28 00:04:54 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
showCursor(true);
|
|
|
|
}
|
2003-10-01 19:01:02 +00:00
|
|
|
}
|
|
|
|
|
2003-09-26 17:35:05 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-03-28 00:04:54 +00:00
|
|
|
void FrameBuffer::showCursor(bool show)
|
2003-09-26 17:35:05 +00:00
|
|
|
{
|
2005-03-28 00:04:54 +00:00
|
|
|
if(show)
|
|
|
|
SDL_ShowCursor(SDL_ENABLE);
|
|
|
|
else
|
|
|
|
SDL_ShowCursor(SDL_DISABLE);
|
|
|
|
}
|
2003-09-26 22:39:36 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::grabMouse(bool grab)
|
|
|
|
{
|
|
|
|
if(grab)
|
|
|
|
SDL_WM_GrabInput(SDL_GRAB_ON);
|
|
|
|
else
|
|
|
|
SDL_WM_GrabInput(SDL_GRAB_OFF);
|
|
|
|
}
|
Huge changes across the map. Lets see if I can remember it all ...
There is now an SDL OpenGL port with filtering and alpha-blending.
It's a work in progress right now, but is already quite stable.
It's not as optimized as the software version yet, but this will
change as well. For now, you have to compile the SDL version in
either normal software mode or OpenGL mode. This will change
before the 1.4 release.
When entering menu mode, the emulation is now suspended. And when
pause is pressed, you can't enter menu mode. Because of these changes,
CPU use has dropped dramatically when viewing menus. This will benefit
all ports, since menus are now redrawn only when necessary, instead of
at the current framerate.
For a reference, on a Pentium-IV 2.4GHz, the software SDL version
maxes CPU usage at 9%, and the SDL OpenGL version at 13.5%. This is
at 60 fps and a zoomlevel of 4. While some small improvements can
(possibly) be made to the OpenGL version, I think we'll soon be hitting
the glass ceiling.
Work on the Porting.txt document is progressing, and I estimate it to
be 45% complete.
The Windows version still doesn't compile, and I still haven't looked
at it. Rest assured that it will be done before 1.4. There will be
a simultaneous release, even if the Linux versions are finished.
git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@200 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
2003-11-06 22:22:33 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
bool FrameBuffer::fullScreen()
|
|
|
|
{
|
|
|
|
return myOSystem->settings().getBool("fullscreen");
|
|
|
|
}
|
2003-09-26 22:39:36 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
uInt32 FrameBuffer::maxWindowSizeForScreen()
|
|
|
|
{
|
|
|
|
uInt32 sWidth = myDesktopDim.w;
|
|
|
|
uInt32 sHeight = myDesktopDim.h;
|
2005-05-30 16:25:47 +00:00
|
|
|
uInt32 multiplier = 10;
|
2003-09-26 22:39:36 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
// If screenwidth or height could not be found, use default zoom value
|
|
|
|
if(sWidth == 0 || sHeight == 0)
|
|
|
|
return 4;
|
2003-09-26 22:39:36 +00:00
|
|
|
|
2005-03-28 00:04:54 +00:00
|
|
|
bool found = false;
|
|
|
|
while(!found && (multiplier > 0))
|
|
|
|
{
|
|
|
|
// Figure out the desired size of the window
|
2005-05-30 16:25:47 +00:00
|
|
|
uInt32 width = (uInt32) (myBaseDim.w * multiplier * theAspectRatio);
|
2005-03-28 00:04:54 +00:00
|
|
|
uInt32 height = myBaseDim.h * multiplier;
|
|
|
|
|
|
|
|
if((width < sWidth) && (height < sHeight))
|
|
|
|
found = true;
|
|
|
|
else
|
|
|
|
multiplier--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(found)
|
|
|
|
return multiplier;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::setWindowTitle(const string& title)
|
|
|
|
{
|
|
|
|
SDL_WM_SetCaption(title.c_str(), "stella");
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::setWindowIcon()
|
|
|
|
{
|
|
|
|
#ifndef MAC_OSX
|
|
|
|
// Set the window icon
|
|
|
|
uInt32 w, h, ncols, nbytes;
|
|
|
|
uInt32 rgba[256], icon[32 * 32];
|
|
|
|
uInt8 mask[32][4];
|
|
|
|
|
|
|
|
sscanf(stella_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes);
|
|
|
|
if((w != 32) || (h != 32) || (ncols > 255) || (nbytes > 1))
|
|
|
|
{
|
|
|
|
cerr << "ERROR: Couldn't load the icon.\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uInt32 i = 0; i < ncols; i++)
|
|
|
|
{
|
|
|
|
unsigned char code;
|
|
|
|
char color[32];
|
|
|
|
uInt32 col;
|
|
|
|
|
|
|
|
sscanf(stella_icon[1 + i], "%c c %s", &code, color);
|
|
|
|
if(!strcmp(color, "None"))
|
|
|
|
col = 0x00000000;
|
|
|
|
else if(!strcmp(color, "black"))
|
|
|
|
col = 0xFF000000;
|
|
|
|
else if (color[0] == '#')
|
|
|
|
{
|
|
|
|
sscanf(color + 1, "%06x", &col);
|
|
|
|
col |= 0xFF000000;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cerr << "ERROR: Couldn't load the icon.\n";
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
rgba[code] = col;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(mask, 0, sizeof(mask));
|
|
|
|
for(h = 0; h < 32; h++)
|
|
|
|
{
|
|
|
|
const char* line = stella_icon[1 + ncols + h];
|
|
|
|
for(w = 0; w < 32; w++)
|
|
|
|
{
|
|
|
|
icon[w + 32 * h] = rgba[(int)line[w]];
|
|
|
|
if(rgba[(int)line[w]] & 0xFF000000)
|
|
|
|
mask[h][w >> 3] |= 1 << (7 - (w & 0x07));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32,
|
|
|
|
32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
|
|
|
|
SDL_WM_SetIcon(surface, (unsigned char *) mask);
|
|
|
|
SDL_FreeSurface(surface);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::box(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
|
|
|
OverlayColor colorA, OverlayColor colorB)
|
|
|
|
{
|
|
|
|
hLine(x + 1, y, x + w - 2, colorA);
|
|
|
|
hLine(x, y + 1, x + w - 1, colorA);
|
|
|
|
vLine(x, y + 1, y + h - 2, colorA);
|
|
|
|
vLine(x + 1, y, y + h - 1, colorA);
|
|
|
|
|
|
|
|
hLine(x + 1, y + h - 2, x + w - 1, colorB);
|
|
|
|
hLine(x + 1, y + h - 1, x + w - 2, colorB);
|
|
|
|
vLine(x + w - 1, y + 1, y + h - 2, colorB);
|
|
|
|
vLine(x + w - 2, y + 1, y + h - 1, colorB);
|
|
|
|
}
|
|
|
|
|
2005-04-04 02:19:22 +00:00
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
void FrameBuffer::frameRect(uInt32 x, uInt32 y, uInt32 w, uInt32 h,
|
2005-06-25 16:35:36 +00:00
|
|
|
OverlayColor color, FrameStyle style)
|
2005-04-04 02:19:22 +00:00
|
|
|
{
|
2005-06-25 16:35:36 +00:00
|
|
|
switch(style)
|
|
|
|
{
|
|
|
|
case kSolidLine:
|
|
|
|
hLine(x, y, x + w - 1, color);
|
|
|
|
hLine(x, y + h - 1, x + w - 1, color);
|
|
|
|
vLine(x, y, y + h - 1, color);
|
|
|
|
vLine(x + w - 1, y, y + h - 1, color);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case kDashLine:
|
|
|
|
unsigned int i, skip, lwidth = 1;
|
|
|
|
|
|
|
|
for(i = x, skip = 1; i < x+w-1; i=i+lwidth+1, ++skip)
|
|
|
|
{
|
|
|
|
if(skip % 2)
|
|
|
|
{
|
|
|
|
hLine(i, y, i + lwidth, color);
|
|
|
|
hLine(i, y + h - 1, i + lwidth, color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(i = y, skip = 1; i < y+h-1; i=i+lwidth+1, ++skip)
|
|
|
|
{
|
|
|
|
if(skip % 2)
|
|
|
|
{
|
|
|
|
vLine(x, i, i + lwidth, color);
|
|
|
|
vLine(x + w - 1, i, i + lwidth, color);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2005-04-04 02:19:22 +00:00
|
|
|
}
|
2005-06-08 18:45:09 +00:00
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
2005-06-14 01:11:48 +00:00
|
|
|
void FrameBuffer::drawString(const GUI::Font* font, const string& s,
|
2005-06-08 18:45:09 +00:00
|
|
|
int x, int y, int w,
|
|
|
|
OverlayColor color, TextAlignment align,
|
|
|
|
int deltax, bool useEllipsis)
|
|
|
|
{
|
|
|
|
const int leftX = x, rightX = x + w;
|
|
|
|
unsigned int i;
|
2005-06-14 01:11:48 +00:00
|
|
|
int width = font->getStringWidth(s);
|
2005-06-08 18:45:09 +00:00
|
|
|
string str;
|
|
|
|
|
|
|
|
if(useEllipsis && width > w)
|
|
|
|
{
|
|
|
|
// String is too wide. So we shorten it "intelligently", by replacing
|
|
|
|
// parts of it by an ellipsis ("..."). There are three possibilities
|
|
|
|
// for this: replace the start, the end, or the middle of the string.
|
|
|
|
// What is best really depends on the context; but unless we want to
|
|
|
|
// make this configurable, replacing the middle probably is a good
|
|
|
|
// compromise.
|
2005-06-14 01:11:48 +00:00
|
|
|
const int ellipsisWidth = font->getStringWidth("...");
|
2005-06-08 18:45:09 +00:00
|
|
|
|
|
|
|
// SLOW algorithm to remove enough of the middle. But it is good enough for now.
|
|
|
|
const int halfWidth = (w - ellipsisWidth) / 2;
|
|
|
|
int w2 = 0;
|
|
|
|
|
|
|
|
for(i = 0; i < s.size(); ++i)
|
|
|
|
{
|
2005-06-14 01:11:48 +00:00
|
|
|
int charWidth = font->getCharWidth(s[i]);
|
2005-06-08 18:45:09 +00:00
|
|
|
if(w2 + charWidth > halfWidth)
|
|
|
|
break;
|
|
|
|
|
|
|
|
w2 += charWidth;
|
|
|
|
str += s[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point we know that the first 'i' chars are together 'w2'
|
|
|
|
// pixels wide. We took the first i-1, and add "..." to them.
|
|
|
|
str += "...";
|
|
|
|
|
|
|
|
// The original string is width wide. Of those we already skipped past
|
|
|
|
// w2 pixels, which means (width - w2) remain.
|
|
|
|
// The new str is (w2+ellipsisWidth) wide, so we can accomodate about
|
|
|
|
// (w - (w2+ellipsisWidth)) more pixels.
|
|
|
|
// Thus we skip ((width - w2) - (w - (w2+ellipsisWidth))) =
|
|
|
|
// (width + ellipsisWidth - w)
|
|
|
|
int skip = width + ellipsisWidth - w;
|
|
|
|
for(; i < s.size() && skip > 0; ++i)
|
2005-06-14 01:11:48 +00:00
|
|
|
skip -= font->getCharWidth(s[i]);
|
2005-06-08 18:45:09 +00:00
|
|
|
|
|
|
|
// Append the remaining chars, if any
|
|
|
|
for(; i < s.size(); ++i)
|
|
|
|
str += s[i];
|
|
|
|
|
2005-06-14 01:11:48 +00:00
|
|
|
width = font->getStringWidth(str);
|
2005-06-08 18:45:09 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
str = s;
|
|
|
|
|
|
|
|
if(align == kTextAlignCenter)
|
|
|
|
x = x + (w - width - 1)/2;
|
|
|
|
else if(align == kTextAlignRight)
|
|
|
|
x = x + w - width;
|
|
|
|
|
|
|
|
x += deltax;
|
|
|
|
for(i = 0; i < str.size(); ++i)
|
|
|
|
{
|
2005-06-14 01:11:48 +00:00
|
|
|
w = font->getCharWidth(str[i]);
|
2005-06-08 18:45:09 +00:00
|
|
|
if(x+w > rightX)
|
|
|
|
break;
|
|
|
|
if(x >= leftX)
|
|
|
|
drawChar(font, str[i], x, y, color);
|
|
|
|
|
|
|
|
x += w;
|
|
|
|
}
|
|
|
|
}
|
2005-07-02 01:28:43 +00:00
|
|
|
|
|
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
const uInt8 FrameBuffer::ourGUIColors[kNumColors-256][3] = {
|
|
|
|
{104, 104, 104},
|
|
|
|
{0, 0, 0},
|
|
|
|
{64, 64, 64},
|
|
|
|
{32, 160, 32},
|
|
|
|
{0, 255, 0},
|
|
|
|
{200, 0, 0}
|
|
|
|
};
|