* initial works on GUI, launcher works, not external themes yet

* cleanup header files
This commit is contained in:
Pawel Kolodziejski 2009-10-04 10:58:28 +00:00
parent aaa9ce687a
commit 26f97ed5a3
177 changed files with 45509 additions and 216 deletions

View File

@ -25,7 +25,7 @@ CXXFLAGS:= -Wall $(CXXFLAGS)
CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder -Wno-unused-parameter
# Enable even more warnings...
#CXXFLAGS+= -Wpointer-arith -Wcast-qual -Wcast-align
#CXXFLAGS+= -Wshadow -Wimplicit -Wundef -Wnon-virtual-dtor -Wwrite-strings
#CXXFLAGS+= -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings
# Disable RTTI and exceptions, and enabled checking of pointers returned by "new"
#CXXFLAGS+= -fno-rtti -fno-exceptions -fcheck-new

View File

@ -198,6 +198,9 @@ dist-src: \
@#DEB-src?
# Themes files
DIST_FILES_THEMES:=$(addprefix $(srcdir)/gui/themes/,scummmodern.zip)
# Plugin files
DIST_FILES_PLUGINS:=$(addprefix $(srcdir)/,$(PLUGINS))

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -25,6 +25,14 @@
#include "backends/base-backend.h"
#include "backends/events/default/default-events.h"
#include "gui/message.h"
void BaseBackend::displayMessageOnOSD(const char *msg) {
// Display the message for 1.5 seconds
GUI::TimedMessageDialog dialog(msg, 1500);
dialog.runModal();
}
static Common::EventManager *s_eventManager = 0;

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -33,6 +33,7 @@
class BaseBackend : public OSystem, EventProvider {
public:
virtual Common::EventManager *getEventManager();
virtual void displayMessageOnOSD(const char *msg);
virtual Common::SeekableReadStream *createConfigReadStream();
virtual Common::WriteStream *createConfigWriteStream();

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#if !defined(DISABLE_DEFAULT_EVENTMANAGER)
@ -27,6 +28,12 @@
#include "common/system.h"
#include "common/config-manager.h"
#include "backends/events/default/default-events.h"
#include "backends/keymapper/keymapper.h"
#include "backends/keymapper/remap-dialog.h"
#include "backends/vkeybd/virtual-keyboard.h"
#include "engines/engine.h"
#include "gui/message.h"
#define RECORD_SIGNATURE 0x54455354
#define RECORD_VERSION 1
@ -429,6 +436,66 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_currentKeyDown.keycode = event.kbd.keycode;
_currentKeyDown.flags = event.kbd.flags;
_keyRepeatTime = time + kKeyRepeatInitialDelay;
#endif
// Global Main Menu
if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == Common::KEYCODE_F5) {
if (g_engine && !g_engine->isPaused()) {
Common::Event menuEvent;
menuEvent.type = Common::EVENT_MAINMENU;
// FIXME: GSoC RTL branch passes the F6 key event to the
// engine, and also enqueues a EVENT_MAINMENU. For now,
// we just drop the key event and return an EVENT_MAINMENU
// instead. This way, we don't have to add special cases
// to engines (like it was the case for LURE in the RTL branch).
//
// However, this has other consequences, possibly negative ones.
// Like, what happens with key repeat for the trigger key?
//pushEvent(menuEvent);
event = menuEvent;
// FIXME: Since now we do not push another MAINMENU event onto
// our event stack, the GMM would never open, so we have to do
// that here. Of course when the engine would handle MAINMENU
// as an event now and open up the GMM itself it would open the
// menu twice.
if (g_engine && !g_engine->isPaused())
g_engine->openMainMenuDialog();
if (_shouldQuit)
event.type = Common::EVENT_QUIT;
else if (_shouldRTL)
event.type = Common::EVENT_RTL;
}
}
#ifdef ENABLE_VKEYBD
else if (event.kbd.keycode == Common::KEYCODE_F7 && event.kbd.flags == 0) {
if (_vk->isDisplaying()) {
_vk->close(true);
} else {
if (g_engine)
g_engine->pauseEngine(true);
_vk->show();
if (g_engine)
g_engine->pauseEngine(false);
result = false;
}
}
#endif
#ifdef ENABLE_KEYMAPPER
else if (event.kbd.keycode == Common::KEYCODE_F8 && event.kbd.flags == 0) {
if (!_remap) {
_remap = true;
Common::RemapDialog _remapDialog;
if (g_engine)
g_engine->pauseEngine(true);
_remapDialog.runModal();
if (g_engine)
g_engine->pauseEngine(false);
_remap = false;
}
}
#endif
break;
@ -464,8 +531,50 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_buttonState &= ~RBUTTON;
break;
case Common::EVENT_MAINMENU:
if (g_engine && !g_engine->isPaused())
g_engine->openMainMenuDialog();
if (_shouldQuit)
event.type = Common::EVENT_QUIT;
else if (_shouldRTL)
event.type = Common::EVENT_RTL;
break;
case Common::EVENT_RTL:
if (ConfMan.getBool("confirm_exit")) {
if (g_engine)
g_engine->pauseEngine(true);
GUI::MessageDialog alert("Do you really want to return to the Launcher?", "Launcher", "Cancel");
result = _shouldRTL = (alert.runModal() == GUI::kMessageOK);
if (g_engine)
g_engine->pauseEngine(false);
} else
_shouldRTL = true;
break;
case Common::EVENT_MUTE:
if (g_engine)
g_engine->flipMute();
break;
case Common::EVENT_QUIT:
_shouldQuit = true;
if (ConfMan.getBool("confirm_exit")) {
if (_confirmExitDialogActive) {
result = false;
break;
}
_confirmExitDialogActive = true;
if (g_engine)
g_engine->pauseEngine(true);
GUI::MessageDialog alert("Do you really want to quit?", "Quit", "Cancel");
result = _shouldQuit = (alert.runModal() == GUI::kMessageOK);
if (g_engine)
g_engine->pauseEngine(false);
_confirmExitDialogActive = false;
} else
_shouldQuit = true;
break;
default:

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef BACKENDS_FS_STDIOSTREAM_H

View File

@ -9,11 +9,24 @@ MODULE_OBJS := \
fs/posix/posix-fs-factory.o \
fs/psp/psp-fs-factory.o \
fs/windows/windows-fs-factory.o \
keymapper/action.o \
keymapper/keymap.o \
keymapper/keymapper.o \
keymapper/remap-dialog.o \
plugins/dc/dc-provider.o \
plugins/posix/posix-provider.o \
plugins/sdl/sdl-provider.o \
plugins/win32/win32-provider.o \
saves/savefile.o \
saves/default/default-saves.o \
saves/posix/posix-saves.o \
saves/psp/psp-saves.o \
timer/default/default-timer.o
timer/default/default-timer.o \
vkeybd/image-map.o \
vkeybd/polygon.o \
vkeybd/virtual-keyboard.o \
vkeybd/virtual-keyboard-gui.o \
vkeybd/virtual-keyboard-parser.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -0,0 +1,233 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "backends/platform/sdl/sdl.h"
#include "backends/keymapper/keymapper.h"
#include "common/keyboard.h"
#ifdef ENABLE_KEYMAPPER
using namespace Common;
struct Key {
const char *hwId;
KeyCode keycode;
uint16 ascii;
const char *desc;
KeyType preferredAction;
bool shiftable;
};
static const Key keys[] = {
{"BACKSPACE", KEYCODE_BACKSPACE, ASCII_BACKSPACE, "Backspace", kActionKeyType, false},
{"TAB", KEYCODE_TAB, ASCII_TAB, "Tab", kActionKeyType, false},
{"CLEAR", KEYCODE_CLEAR, 0, "Clear", kActionKeyType, false},
{"RETURN", KEYCODE_RETURN, ASCII_RETURN, "Return", kActionKeyType, false},
{"PAUSE", KEYCODE_PAUSE, 0, "Pause", kActionKeyType, false},
{"ESCAPE", KEYCODE_ESCAPE, ASCII_ESCAPE, "Esc", kStartKeyType, false},
{"SPACE", KEYCODE_SPACE, ASCII_SPACE, "Space", kActionKeyType, false},
{"EXCLAIM", KEYCODE_EXCLAIM, '!', "!", kActionKeyType, false},
{"QUOTEDBL", KEYCODE_QUOTEDBL, '"', "\"", kActionKeyType, false},
{"HASH", KEYCODE_HASH, '#', "#", kActionKeyType, false},
{"DOLLAR", KEYCODE_DOLLAR, '$', "$", kActionKeyType, false},
{"AMPERSAND", KEYCODE_AMPERSAND, '&', "&", kActionKeyType, false},
{"QUOTE", KEYCODE_QUOTE, '\'', "'", kActionKeyType, false},
{"LEFTPAREN", KEYCODE_LEFTPAREN, '(', "(", kActionKeyType, false},
{"RIGHTPAREN", KEYCODE_RIGHTPAREN, ')', ")", kActionKeyType, false},
{"ASTERISK", KEYCODE_ASTERISK, '*', "*", kActionKeyType, false},
{"PLUS", KEYCODE_PLUS, '+', "+", kActionKeyType, false},
{"COMMA", KEYCODE_COMMA, ',', ",", kActionKeyType, false},
{"MINUS", KEYCODE_MINUS, '-', "-", kActionKeyType, false},
{"PERIOD", KEYCODE_PERIOD, '.', ".", kActionKeyType, false},
{"SLASH", KEYCODE_SLASH, '/', "/", kActionKeyType, false},
{"0", KEYCODE_0, '0', "0", kActionKeyType, false},
{"1", KEYCODE_1, '1', "1", kActionKeyType, false},
{"2", KEYCODE_2, '2', "2", kActionKeyType, false},
{"3", KEYCODE_3, '3', "3", kActionKeyType, false},
{"4", KEYCODE_4, '4', "4", kActionKeyType, false},
{"5", KEYCODE_5, '5', "5", kActionKeyType, false},
{"6", KEYCODE_6, '6', "6", kActionKeyType, false},
{"7", KEYCODE_7, '7', "7", kActionKeyType, false},
{"8", KEYCODE_8, '8', "8", kActionKeyType, false},
{"9", KEYCODE_9, '9', "9", kActionKeyType, false},
{"COLON", KEYCODE_COLON, ':', ":", kActionKeyType, false},
{"SEMICOLON", KEYCODE_SEMICOLON, ';', ";", kActionKeyType, false},
{"LESS", KEYCODE_LESS, '<', "<", kActionKeyType, false},
{"EQUALS", KEYCODE_EQUALS, '=', "=", kActionKeyType, false},
{"GREATER", KEYCODE_GREATER, '>', ">", kActionKeyType, false},
{"QUESTION", KEYCODE_QUESTION, '?', "?", kActionKeyType, false},
{"AT", KEYCODE_AT, '@', "@", kActionKeyType, false},
{"LEFTBRACKET", KEYCODE_LEFTBRACKET, '[', "[", kActionKeyType, false},
{"BACKSLASH", KEYCODE_BACKSLASH, '\\', "\\", kActionKeyType, false},
{"RIGHTBRACKET", KEYCODE_RIGHTBRACKET, ']', "]", kActionKeyType, false},
{"CARET", KEYCODE_CARET, '^', "^", kActionKeyType, false},
{"UNDERSCORE", KEYCODE_UNDERSCORE, '_', "_", kActionKeyType, false},
{"BACKQUOTE", KEYCODE_BACKQUOTE, '`', "`", kActionKeyType, false},
{"a", KEYCODE_a, 'a', "a", kActionKeyType, true},
{"b", KEYCODE_b, 'b', "b", kActionKeyType, true},
{"c", KEYCODE_c, 'c', "c", kActionKeyType, true},
{"d", KEYCODE_d, 'd', "d", kActionKeyType, true},
{"e", KEYCODE_e, 'e', "e", kActionKeyType, true},
{"f", KEYCODE_f, 'f', "f", kActionKeyType, true},
{"g", KEYCODE_g, 'g', "g", kActionKeyType, true},
{"h", KEYCODE_h, 'h', "h", kActionKeyType, true},
{"i", KEYCODE_i, 'i', "i", kActionKeyType, true},
{"j", KEYCODE_j, 'j', "j", kActionKeyType, true},
{"k", KEYCODE_k, 'k', "k", kActionKeyType, true},
{"l", KEYCODE_l, 'l', "l", kActionKeyType, true},
{"m", KEYCODE_m, 'm', "m", kActionKeyType, true},
{"n", KEYCODE_n, 'n', "n", kActionKeyType, true},
{"o", KEYCODE_o, 'o', "o", kActionKeyType, true},
{"p", KEYCODE_p, 'p', "p", kActionKeyType, true},
{"q", KEYCODE_q, 'q', "q", kActionKeyType, true},
{"r", KEYCODE_r, 'r', "r", kActionKeyType, true},
{"s", KEYCODE_s, 's', "s", kActionKeyType, true},
{"t", KEYCODE_t, 't', "t", kActionKeyType, true},
{"u", KEYCODE_u, 'u', "u", kActionKeyType, true},
{"v", KEYCODE_v, 'v', "v", kActionKeyType, true},
{"w", KEYCODE_w, 'w', "w", kActionKeyType, true},
{"x", KEYCODE_x, 'x', "x", kActionKeyType, true},
{"y", KEYCODE_y, 'y', "y", kActionKeyType, true},
{"z", KEYCODE_z, 'z', "z", kActionKeyType, true},
{"DELETE", KEYCODE_DELETE, 0, "Del", kActionKeyType, false},
// Numeric keypad
{"KP0", KEYCODE_KP0, 0, "KP0", kActionKeyType, false},
{"KP1", KEYCODE_KP1, 0, "KP1", kActionKeyType, false},
{"KP2", KEYCODE_KP2, 0, "KP2", kActionKeyType, false},
{"KP3", KEYCODE_KP3, 0, "KP3", kActionKeyType, false},
{"KP4", KEYCODE_KP4, 0, "KP4", kActionKeyType, false},
{"KP5", KEYCODE_KP5, 0, "KP5", kActionKeyType, false},
{"KP6", KEYCODE_KP6, 0, "KP6", kActionKeyType, false},
{"KP7", KEYCODE_KP7, 0, "KP7", kActionKeyType, false},
{"KP8", KEYCODE_KP8, 0, "KP8", kActionKeyType, false},
{"KP9", KEYCODE_KP9, 0, "KP9", kActionKeyType, false},
{"KP_PERIOD", KEYCODE_KP_PERIOD, 0, "KP.", kActionKeyType, false},
{"KP_DIVIDE", KEYCODE_KP_DIVIDE, 0, "KP/", kActionKeyType, false},
{"KP_MULTIPLY", KEYCODE_KP_MULTIPLY, 0, "KP*", kActionKeyType, false},
{"KP_MINUS", KEYCODE_KP_MINUS, 0, "KP-", kActionKeyType, false},
{"KP_PLUS", KEYCODE_KP_PLUS, 0, "KP+", kActionKeyType, false},
{"KP_ENTER", KEYCODE_KP_ENTER, 0, "KP Enter", kActionKeyType, false},
{"KP_EQUALS", KEYCODE_KP_EQUALS, 0, "KP=", kActionKeyType, false},
// Arrows + Home/End pad
{"UP", KEYCODE_UP, 0, "Up", kDirUpKeyType, false},
{"DOWN", KEYCODE_DOWN, 0, "Down", kDirDownKeyType, false},
{"RIGHT", KEYCODE_RIGHT, 0, "Right", kDirRightKeyType, false},
{"LEFT", KEYCODE_LEFT, 0, "Left", kDirLeftKeyType, false},
{"INSERT", KEYCODE_INSERT, 0, "Insert", kActionKeyType, false},
{"HOME", KEYCODE_HOME, 0, "Home", kActionKeyType, false},
{"END", KEYCODE_END, 0, "End", kActionKeyType, false},
{"PAGEUP", KEYCODE_PAGEUP, 0, "PgUp", kActionKeyType, false},
{"PAGEDOWN", KEYCODE_PAGEDOWN, 0, "PgDn", kActionKeyType, false},
// Function keys
{"F1", KEYCODE_F1, ASCII_F1, "F1", kActionKeyType, false},
{"F2", KEYCODE_F2, ASCII_F2, "F2", kActionKeyType, false},
{"F3", KEYCODE_F3, ASCII_F3, "F3", kActionKeyType, false},
{"F4", KEYCODE_F4, ASCII_F4, "F4", kActionKeyType, false},
{"F5", KEYCODE_F5, ASCII_F5, "F5", kActionKeyType, false},
{"F6", KEYCODE_F6, ASCII_F6, "F6", kActionKeyType, false},
{"F7", KEYCODE_F7, ASCII_F7, "F7", kActionKeyType, false},
{"F8", KEYCODE_F8, ASCII_F8, "F8", kActionKeyType, false},
{"F9", KEYCODE_F9, ASCII_F9, "F9", kActionKeyType, false},
{"F10", KEYCODE_F10, ASCII_F10, "F10", kActionKeyType, false},
{"F11", KEYCODE_F11, ASCII_F11, "F11", kActionKeyType, false},
{"F12", KEYCODE_F12, ASCII_F12, "F12", kActionKeyType, false},
{"F13", KEYCODE_F13, 0, "F13", kActionKeyType, false},
{"F14", KEYCODE_F14, 0, "F14", kActionKeyType, false},
{"F15", KEYCODE_F15, 0, "F15", kActionKeyType, false},
// Miscellaneous function keys
{"HELP", KEYCODE_HELP, 0, "Help", kActionKeyType, false},
{"PRINT", KEYCODE_PRINT, 0, "Print", kActionKeyType, false},
{"SYSREQ", KEYCODE_SYSREQ, 0, "SysRq", kActionKeyType, false},
{"BREAK", KEYCODE_BREAK, 0, "Break", kActionKeyType, false},
{"MENU", KEYCODE_MENU, 0, "Menu", kActionKeyType, false},
// Power Macintosh power key
{"POWER", KEYCODE_POWER, 0, "Power", kActionKeyType, false},
// Some european keyboards
{"EURO", KEYCODE_EURO, 0, "Euro", kActionKeyType, false},
// Atari keyboard has Undo
{"UNDO", KEYCODE_UNDO, 0, "Undo", kActionKeyType, false},
{0, KEYCODE_INVALID, 0, 0, kGenericKeyType, false}
};
struct Mod {
byte flag;
const char *id;
const char *desc;
bool shiftable;
};
static const Mod modifiers[] = {
{ 0, "", "", false },
{ KBD_CTRL, "C+", "Ctrl+", false },
{ KBD_ALT, "A+", "Alt+", false },
{ KBD_SHIFT, "", "", true },
{ KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", false },
{ KBD_SHIFT | KBD_CTRL, "S+C+", "Shift+Ctrl+", true },
{ KBD_SHIFT | KBD_CTRL | KBD_ALT, "C+A+", "Ctrl+Alt+", true },
{ 0, 0, 0, false }
};
#endif
Common::HardwareKeySet *OSystem_SDL::getHardwareKeySet() {
#ifdef ENABLE_KEYMAPPER
HardwareKeySet *keySet = new HardwareKeySet();
const Key *key;
const Mod *mod;
char fullKeyId[50];
char fullKeyDesc[100];
uint16 ascii;
for (mod = modifiers; mod->id; mod++) {
for (key = keys; key->hwId; key++) {
ascii = key->ascii;
if (mod->shiftable && key->shiftable) {
snprintf(fullKeyId, 50, "%s%c", mod->id, toupper(key->hwId[0]));
snprintf(fullKeyDesc, 100, "%s%c", mod->desc, toupper(key->desc[0]));
ascii = toupper(key->ascii);
} else if (mod->shiftable) {
snprintf(fullKeyId, 50, "S+%s%s", mod->id, key->hwId);
snprintf(fullKeyDesc, 100, "Shift+%s%s", mod->desc, key->desc);
} else {
snprintf(fullKeyId, 50, "%s%s", mod->id, key->hwId);
snprintf(fullKeyDesc, 100, "%s%s", mod->desc, key->desc);
}
keySet->addHardwareKey(new HardwareKey(fullKeyId, KeyState(key->keycode, ascii, mod->flag), fullKeyDesc, key->preferredAction ));
}
}
return keySet;
#else
return 0;
#endif
}

View File

@ -1,6 +1,7 @@
MODULE := backends/platform/sdl
MODULE_OBJS := \
hardwarekeys.o \
sdl_driver.o
MODULE_DIRS += \

View File

@ -217,6 +217,11 @@ void OSystem_SDL::warpMouse(int x, int y) {
SDL_WarpMouse(x, y);
}
void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) {
if (w == 0 || h == 0)
return;
}
bool OSystem_SDL::pollEvent(Common::Event &event) {
SDL_Event ev;
int axis;
@ -537,19 +542,7 @@ OSystem_SDL::OSystem_SDL() {
OSystem_SDL::~OSystem_SDL() {
SDL_RemoveTimer(_timerID);
closeMixer();
if (_overlayscreen) {
SDL_FreeSurface(_overlayscreen);
_overlayscreen = NULL;
#ifdef USE_OPENGL
if (_overlayNumTex > 0) {
glDeleteTextures(_overlayNumTex, _overlayTexIds);
delete[] _overlayTexIds;
_overlayNumTex = 0;
}
#endif
}
closeOverlay();
delete _fsFactory;
}
@ -615,10 +608,31 @@ void OSystem_SDL::initBackend() {
}
}
void OSystem_SDL::closeOverlay() {
if (_overlayscreen) {
SDL_FreeSurface(_overlayscreen);
_overlayscreen = NULL;
#ifdef USE_OPENGL
if (_overlayNumTex > 0) {
glDeleteTextures(_overlayNumTex, _overlayTexIds);
delete[] _overlayTexIds;
_overlayNumTex = 0;
}
#endif
}
}
void OSystem_SDL::launcherInitSize(uint w, uint h) {
closeOverlay();
setupScreen(w, h, false, false);
}
byte *OSystem_SDL::setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) {
uint32 sdlflags;
int bpp;
closeOverlay();
#ifdef USE_OPENGL
_opengl = accel3d;
#endif
@ -1076,22 +1090,18 @@ void OSystem_SDL::setWindowCaption(const char *caption) {
bool OSystem_SDL::hasFeature(Feature f) {
return
(f == kFeatureFullscreenMode) ||
#ifdef USE_OPENGL
(f == kFeatureOpenGL) ||
(f == kFeatureOpenGL);
#else
false;
#endif
(f == kFeatureIconifyWindow);
}
void OSystem_SDL::setFeatureState(Feature f, bool enable) {
switch (f) {
case kFeatureIconifyWindow:
if (enable)
SDL_WM_IconifyWindow();
break;
/* switch (f) {
default:
break;
}
}*/
}
bool OSystem_SDL::getFeatureState(Feature f) {

View File

@ -50,6 +50,9 @@ public:
virtual void initBackend();
// Set the size of the video bitmap.
virtual void launcherInitSize(uint w, uint h);
virtual byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d);
// Update the dirty areas of the screen
@ -63,6 +66,9 @@ public:
// actually moves the cursor to the specified position.
virtual void warpMouse(int x, int y);
// Set the bitmap that's used when drawing the cursor.
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale); // overloaded by CE backend (FIXME)
// Get the number of milliseconds since the program was started.
uint32 getMillis();
@ -148,6 +154,8 @@ private:
int _overlayNumTex;
GLuint *_overlayTexIds;
void closeOverlay();
// Audio
int _samplesPerSec;

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#if !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#if !defined(BACKEND_SAVES_DEFAULT_H) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#if defined(UNIX) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#if !defined(BACKEND_POSIX_SAVES_H) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER)

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifdef __PSP__

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef BACKEND_PSP_SAVES_H

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/util.h"

View File

@ -32,6 +32,8 @@
#include "common/system.h"
#include "common/fs.h"
#include "gui/ThemeEngine.h"
namespace Base {
#ifndef DISABLE_COMMAND_LINE
@ -61,17 +63,20 @@ static const char HELP_STRING[] =
" -f, --fullscreen Force full-screen mode\n"
" -q, --language=LANG Select language (en,de,fr,it,pt,es,jp,zh,kr,se,gb,\n"
" hb,ru,cz)\n"
" --gui-theme=THEME Select GUI theme\n"
" --themepath=PATH Path to where GUI themes are stored\n"
" --list-themes Display list of all usable GUI themes\n"
" -m, --music-volume=NUM Set the music volume, 0-127 (default: 127)\n"
" -s, --sfx-volume=NUM Set the sfx volume, 0-127 (default: 127)\n"
" -r, --speech-volume=NUM Set the speech volume, 0-127 (default: 127)\n"
" --speech-mode=NUM Set the mode of speech 1-Text only, 2-Voice Only, 3-Voice and Text\n"
" --soft-renderer=BOOL Set the turn on/off software 3D renderer: TRUE/FALSE\n"
" --speech-mode=NUM Set the mode of speech 1-Text only, 2-Speech Only, 3-Speech and Text\n"
" --soft-renderer=BOOL Set the turn on/off software 3D renderer: true/false\n"
" -d, --debuglevel=NUM Set debug verbosity level\n"
" --debugflags=FLAGS Enables engine specific debug flags\n"
" --savepath=PATH Path to where savegames are stored\n"
" --extrapath=PATH Extra path to additional game data\n"
" --output-rate=RATE Select output sample rate in Hz (e.g. 22050)\n"
" --show-fps=BOOL Set the turn on/off display FPS info: TRUE/FALSE\n"
" --show-fps=BOOL Set the turn on/off display FPS info: true/false\n"
"\n"
;
#endif
@ -104,14 +109,14 @@ void registerDefaults() {
ConfMan.registerDefault("music_volume", 127);
ConfMan.registerDefault("sfx_volume", 127);
ConfMan.registerDefault("voice_volume", 127);
ConfMan.registerDefault("speech_volume", 127);
ConfMan.registerDefault("speech_mode", "3");
ConfMan.registerDefault("path", ".");
ConfMan.registerDefault("soft_renderer", "TRUE");
ConfMan.registerDefault("fullscreen", "FALSE");
ConfMan.registerDefault("show_fps", "FALSE");
ConfMan.registerDefault("soft_renderer", "true");
ConfMan.registerDefault("fullscreen", "false");
ConfMan.registerDefault("show_fps", "false");
ConfMan.registerDefault("disable_sdl_parachute", false);
@ -251,7 +256,7 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
DO_OPTION('s', "sfx-volume")
END_OPTION
DO_OPTION('r', "voice-volume")
DO_OPTION('r', "speech-volume")
END_OPTION
DO_OPTION('q', "language")
@ -306,6 +311,21 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
}
END_OPTION
DO_LONG_OPTION("gui-theme")
END_OPTION
DO_LONG_OPTION("themepath")
Common::FSNode path(option);
if (!path.exists()) {
usage("Non-existent theme path '%s'", option);
} else if (!path.isReadable()) {
usage("Non-readable theme path '%s'", option);
}
END_OPTION
DO_LONG_COMMAND("list-themes")
END_OPTION
DO_LONG_OPTION("text-speed")
END_OPTION
@ -381,6 +401,18 @@ static void listTargets() {
}
}
/** Lists all usable themes */
static void listThemes() {
typedef Common::List<GUI::ThemeEngine::ThemeDescriptor> ThList;
ThList thList;
GUI::ThemeEngine::listUsableThemes(thList);
printf("Theme Description\n");
printf("-------------- ------------------------------------------------\n");
for (ThList::const_iterator i = thList.begin(); i != thList.end(); ++i)
printf("%-14s %s\n", i->id.c_str(), i->name.c_str());
}
#else // DISABLE_COMMAND_LINE
@ -406,6 +438,9 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
} else if (command == "list-games") {
listGames();
return false;
} else if (command == "list-themes") {
listThemes();
return false;
} else if (command == "version") {
printf("%s\n", gResidualFullVersion);
printf("Features compiled in: %s\n", gResidualFeatures);
@ -417,15 +452,13 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
#endif // DISABLE_COMMAND_LINE
Common::String gameId;
if (command.empty())
gameId = ConfMan.get("gameid", Common::ConfigManager::kApplicationDomain);
else
gameId = command;
if (!gameId.empty()) {
GameDescriptor gd = EngineMan.findGame(gameId);
if (ConfMan.hasGameDomain(gameId) || !gd.gameid().empty()) {
// If a target was specified, check whether there is either a game
// domain (i.e. a target) matching this argument, or alternatively
// whether there is a gameid matching that name.
if (!command.empty()) {
GameDescriptor gd = EngineMan.findGame(command);
if (ConfMan.hasGameDomain(command) || !gd.gameid().empty()) {
bool idCameFromCommandLine = false;
// WORKAROUND: Fix for bug #1719463: "DETECTOR: Launching
@ -434,11 +467,11 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
// We designate gameids which come strictly from command line
// so AdvancedDetector will not save config file with invalid
// gameid in case target autoupgrade was performed
if (!ConfMan.hasGameDomain(gameId)) {
if (!ConfMan.hasGameDomain(command)) {
idCameFromCommandLine = true;
}
ConfMan.setActiveDomain(gameId);
ConfMan.setActiveDomain(command);
if (idCameFromCommandLine)
ConfMan.set("id_came_from_command_line", "1");
@ -446,15 +479,8 @@ bool processSettings(Common::String &command, Common::StringMap &settings) {
} else {
#ifndef DISABLE_COMMAND_LINE
usage("Unrecognized game target '%s'", command.c_str());
#else
return false;
#endif // DISABLE_COMMAND_LINE
}
} else {
#ifndef DISABLE_COMMAND_LINE
printf(HELP_STRING, s_appName);
#endif // DISABLE_COMMAND_LINE
return false;
}

View File

@ -1 +1,5 @@
#define RESIDUAL_VERSION "0.0.6svn"
#ifndef RESIDUAL_SVN_REVISION
#define RESIDUAL_SVN_REVISION
#endif
#define RESIDUAL_VERSION "0.0.6svn" RESIDUAL_SVN_REVISION

View File

@ -1 +1,5 @@
#define RESIDUAL_VERSION "@VERSION@"
#ifndef RESIDUAL_SVN_REVISION
#define RESIDUAL_SVN_REVISION
#endif
#define RESIDUAL_VERSION "@VERSION@" RESIDUAL_SVN_REVISION

View File

@ -44,7 +44,36 @@
#include "common/file.h"
#include "common/fs.h"
#include "common/system.h"
#include "gui/GuiManager.h"
#include "gui/message.h"
#include "backends/keymapper/keymapper.h"
#if defined(_WIN32_WCE)
#include "backends/platform/wince/CELauncherDialog.h"
#elif defined(__DC__)
#include "backends/platform/dc/DCLauncherDialog.h"
#else
#include "gui/launcher.h"
#endif
static bool launcherDialog() {
// Discard any command line options. Those that affect the graphics
// mode and the others (like bootparam etc.) should not
// blindly be passed to the first game launched from the launcher.
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
#if defined(_WIN32_WCE)
CELauncherDialog dlg;
#elif defined(__DC__)
DCLauncherDialog dlg;
#else
GUI::LauncherDialog dlg;
#endif
return (dlg.runModal() != -1);
}
static const EnginePlugin *detectPlugin() {
const EnginePlugin *plugin = 0;
@ -100,6 +129,10 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
// Check for errors
if (!engine || err != Common::kNoError) {
// TODO: Show an error dialog or so?
// TODO: Also take 'err' into consideration...
//GUI::MessageDialog alert("ScummVM could not find any game in the specified directory!");
//alert.runModal();
const char *errMsg = 0;
switch (err) {
case Common::kInvalidPathError:
@ -118,6 +151,17 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
ConfMan.getActiveDomainName().c_str(),
dir.getPath().c_str()
);
// Autoadded is set only when no path was provided and
// the game is run from command line.
//
// Thus, we remove this garbage entry
//
// Fixes bug #1544799
if (ConfMan.hasKey("autoadded")) {
ConfMan.removeGameDomain(ConfMan.getActiveDomainName().c_str());
}
return err;
}
@ -183,6 +227,60 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const
return result;
}
static void setupGraphics(OSystem &system) {
system.launcherInitSize(320, 200);
// When starting up launcher for the first time, the user might have specified
// a --gui-theme option, to allow that option to be working, we need to initialize
// GUI here.
// FIXME: Find a nicer way to allow --gui-theme to be working
GUI::GuiManager::instance();
// Set initial window caption
system.setWindowCaption(gResidualFullVersion);
}
static void setupKeymapper(OSystem &system) {
#ifdef ENABLE_KEYMAPPER
using namespace Common;
Keymapper *mapper = system.getEventManager()->getKeymapper();
Keymap *globalMap = new Keymap("global");
Action *act;
HardwareKeySet *keySet;
keySet = system.getHardwareKeySet();
// Query backend for hardware keys and register them
mapper->registerHardwareKeySet(keySet);
// Now create the global keymap
act = new Action(globalMap, "MENU", "Menu", kGenericActionType, kSelectKeyType);
act->addKeyEvent(KeyState(KEYCODE_F5, ASCII_F5, 0));
act = new Action(globalMap, "SKCT", "Skip", kGenericActionType, kActionKeyType);
act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
act = new Action(globalMap, "PAUS", "Pause", kGenericActionType, kStartKeyType);
act->addKeyEvent(KeyState(KEYCODE_SPACE, ' ', 0));
act = new Action(globalMap, "SKLI", "Skip line", kGenericActionType, kActionKeyType);
act->addKeyEvent(KeyState(KEYCODE_PERIOD, '.', 0));
act = new Action(globalMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType);
act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
act = new Action(globalMap, "REMP", "Remap keys", kKeyRemapActionType);
act->addKeyEvent(KeyState(KEYCODE_F8, ASCII_F8, 0));
mapper->addGlobalKeymap(globalMap);
mapper->pushKeymap("global");
#endif
}
extern "C" int residual_main(int argc, const char * const argv[]) {
Common::String specialDebug;
Common::String command;
@ -237,49 +335,69 @@ extern "C" int residual_main(int argc, const char * const argv[]) {
// the command line params) was read.
system.initBackend();
// Init the event manager. As the virtual keyboard is loaded here, it must
setupGraphics(system);
// Init the event manager. As the virtual keyboard is loaded here, it must
// take place after the backend is initiated and the screen has been setup
system.getEventManager()->init();
// Try to find a plugin which feels responsible for the specified game.
const EnginePlugin *plugin = detectPlugin();
if (plugin) {
// Unload all plugins not needed for this game,
// to save memory
PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin);
// Now as the event manager is created, setup the keymapper
setupKeymapper(system);
// Try to run the game
Common::Error result = runGame(plugin, system, specialDebug);
// Unless a game was specified, show the launcher dialog
if (0 == ConfMan.getActiveDomain())
launcherDialog();
// Did an error occur ?
if (result != Common::kNoError) {
// TODO: Show an informative error dialog if starting the selected game failed.
// FIXME: We're now looping the launcher. This, of course, doesn't
// work as well as it should. In theory everything should be destroyed
// cleanly, so this is now enabled to encourage people to fix bits :)
while (0 != ConfMan.getActiveDomain()) {
// Try to find a plugin which feels responsible for the specified game.
const EnginePlugin *plugin = detectPlugin();
if (plugin) {
// Unload all plugins not needed for this game,
// to save memory
PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, plugin);
// Try to run the game
Common::Error result = runGame(plugin, system, specialDebug);
// Did an error occur ?
if (result != Common::kNoError) {
// TODO: Show an informative error dialog if starting the selected game failed.
}
// Quit unless an error occurred, or Return to launcher was requested
if (result == 0 && !g_system->getEventManager()->shouldRTL())
break;
// Reset RTL flag in case we want to load another engine
g_system->getEventManager()->resetRTL();
// Discard any command line options. It's unlikely that the user
// wanted to apply them to *all* games ever launched.
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
// Clear the active config domain
ConfMan.setActiveDomain("");
// PluginManager::instance().unloadPlugins();
PluginManager::instance().loadPlugins();
} else {
// A dialog would be nicer, but we don't have any
// screen to draw on yet.
warning("Could not find any engine capable of running the selected game");
}
// Quit unless an error occurred
if (result == 0)
goto exit;
// Discard any command line options. It's unlikely that the user
// wanted to apply them to *all* games ever launched.
ConfMan.getDomain(Common::ConfigManager::kTransientDomain)->clear();
// Clear the active config domain
ConfMan.setActiveDomain("");
// PluginManager::instance().unloadPlugins();
PluginManager::instance().loadPlugins();
} else {
// A dialog would be nicer, but we don't have any
// screen to draw on yet.
warning("Could not find any engine capable of running the selected game");
// reset the graphics to default
setupGraphics(system);
launcherDialog();
}
exit:
PluginManager::instance().unloadPlugins();
PluginManager::destroy();
Common::ConfigManager::destroy();
Common::SearchManager::destroy();
GUI::GuiManager::destroy();
return 0;
}

View File

@ -4,14 +4,19 @@
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
* This library is distributed in the hope that it will be useful,
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_ALGORITHM_H

View File

@ -8,18 +8,19 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/archive.h"

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_ARRAY_H

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#include "common/debug.h"

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_DEBUG_H

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#include "common/util.h"

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_FS_H

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_FUNC_H

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_HASH_STR_H

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_LIST_H

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_LIST_INTERN_H

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
/*

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_MD5_H

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -14,8 +14,10 @@ MODULE_OBJS := \
mutex.o \
str.o \
stream.o \
util.o \
system.o \
util.o
unzip.o \
xmlparser.o
# Include common rules
include $(srcdir)/rules.mk

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -65,10 +65,16 @@ StackLock::~StackLock() {
}
void StackLock::lock() {
if (_mutexName != NULL)
debug(6, "Locking mutex %s", _mutexName);
g_system->lockMutex(_mutex);
}
void StackLock::unlock() {
if (_mutexName != NULL)
debug(6, "Unlocking mutex %s", _mutexName);
g_system->unlockMutex(_mutex);
}

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_PTR_H

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_QUEUE_H

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

126
common/stack.h Normal file
View File

@ -0,0 +1,126 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_STACK_H
#define COMMON_STACK_H
#include "common/sys.h"
#include "common/array.h"
namespace Common {
/**
* Extremly simple fixed size stack class.
*/
template<class T, int MAX_SIZE = 10>
class FixedStack {
protected:
T _stack[MAX_SIZE];
int _size;
public:
FixedStack<T, MAX_SIZE>() : _size(0) {}
bool empty() const {
return _size <= 0;
}
void clear() {
_size = 0;
}
void push(const T &x) {
assert(_size < MAX_SIZE);
_stack[_size++] = x;
}
const T &top() const {
assert(_size > 0);
return _stack[_size - 1];
}
T &top() {
assert(_size > 0);
return _stack[_size - 1];
}
T pop() {
T tmp = top();
--_size;
return tmp;
}
int size() const {
return _size;
}
T &operator[](int i) {
assert(0 <= i && i < MAX_SIZE);
return _stack[i];
}
const T &operator[](int i) const {
assert(0 <= i && i < MAX_SIZE);
return _stack[i];
}
};
/**
* Variable size stack class, implemented using our Array class.
*/
template<class T>
class Stack {
private:
Array<T> _stack;
public:
Stack<T>() {}
Stack<T>(const Array<T> &stackContent) : _stack(stackContent) {}
bool empty() const {
return _stack.empty();
}
void clear() {
_stack.clear();
}
void push(const T &x) {
_stack.push_back(x);
}
T &top() {
return _stack.back();
}
const T &top() const {
return _stack.back();
}
T pop() {
T tmp = _stack.back();
_stack.pop_back();
return tmp;
}
int size() const {
return _stack.size();
}
T &operator[](int i) {
return _stack[i];
}
const T &operator[](int i) const {
return _stack[i];
}
};
} // End of namespace Common
#endif

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#include "common/str.h"

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_STRING_H

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -50,6 +50,7 @@ namespace Common {
class TimerManager;
class SeekableReadStream;
class WriteStream;
class HardwareKeySet;
}
class FilesystemFactory;
@ -93,6 +94,8 @@ public:
* A feature in this context means an ability of the backend which can be
* either on or off. Examples include:
* - fullscreen mode
* - aspect ration correction
* - a virtual keyboard for text entry (on PDAs)
*/
enum Feature {
/**
@ -100,9 +103,45 @@ public:
* then this feature flag can be used to switch between the two.
*/
kFeatureFullscreenMode,
kFeatureFullscreenModeSwitch,
/**
* Control aspect ratio correction. Aspect ratio correction is used to
* correct games running at 320x200 (i.e with an aspect ratio of 8:5),
* but which on their original hardware were displayed with the
* standard 4:3 ratio (that is, the original graphics used non-square
* pixels). When the backend support this, then games running at
* 320x200 pixels should be scaled up to 320x240 pixels. For all other
* resolutions, ignore this feature flag.
* @note You can find utility functions in common/scaler.h which can
* be used to implement aspect ratio correction. In particular,
* stretch200To240() can stretch a rect, including (very fast)
* interpolation, and works in-place.
*/
kFeatureAspectRatioCorrection,
/**
* Determine whether a virtual keyboard is too be shown or not.
* This would mostly be implemented by backends for hand held devices,
* like PocketPC, Palms, Symbian phones like the P800, Zaurus, etc.
*/
kFeatureVirtualKeyboard,
kFeatureIconifyWindow,
kFeatureOpenGL
kFeatureOpenGL,
/**
* This feature, set to true, is a hint toward the backend to disable all
* key filtering/mapping, in cases where it would be beneficial to do so.
* As an example case, this is used in the agi engine's predictive dialog.
* When the dialog is displayed this feature is set so that backends with
* phone-like keypad temporarily unmap all user actions which leads to
* comfortable word entry. Conversely, when the dialog exits the feature
* is set to false.
* TODO: Fingolfin suggests that the way the feature is used can be
* generalized in this sense: Have a keyboard mapping feature, which the
* engine queries for to assign keys to actions ("Here's my default key
* map for these actions, what do you want them set to?").
*/
kFeatureDisableKeyFiltering
};
/**
@ -138,8 +177,17 @@ public:
//@{
/**
* Set the size of the launcher virtual screen.
*
* @param width the new virtual screen width
* @param height the new virtual screen height
*/
virtual void launcherInitSize(uint width, uint height) = 0;
/**
* Set the size of the screen.
*
* @param width the new screen width
* @param height the new screen height
@ -147,6 +195,22 @@ public:
*/
virtual byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) = 0;
int getScreenChangeID() const { return 0; }
/**
* Returns the currently set virtual screen height.
* @see initSize
* @return the currently set virtual screen height
*/
virtual int16 getHeight() = 0;
/**
* Returns the currently set virtual screen width.
* @see initSize
* @return the currently set virtual screen width
*/
virtual int16 getWidth() = 0;
/**
* Flush the whole screen, that is render the current content of the screen
* framebuffer to the display.
@ -231,7 +295,11 @@ public:
/** @name Mouse */
/** @name Mouse
* This is the lower level implementation as provided by the
* backends. The engines should use the Graphics::CursorManager
* class instead of using it directly.
*/
//@{
/** Show or hide the mouse cursor. */
@ -245,6 +313,18 @@ public:
*/
virtual void warpMouse(int x, int y) = 0;
/**
* Set the bitmap used for drawing the cursor.
*
* @param buf the pixmap data to be used (8bit/pixel)
* @param w width of the mouse cursor
* @param h height of the mouse cursor
* @param hotspotX horizontal offset from the left side to the hotspot
* @param hotspotY vertical offset from the top side to the hotspot
* @param keycolor transparency color index
* @param cursorTargetScale scale factor which cursor is designed for
*/
virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1) = 0;
//@}
@ -277,6 +357,15 @@ public:
*/
virtual Common::EventManager *getEventManager() = 0;
/**
* Register hardware keys with keymapper
*
* @return HardwareKeySet with all keys and recommended mappings
*
* See keymapper documentation for further reference.
*/
virtual Common::HardwareKeySet *getHardwareKeySet() { return 0; }
//@}

View File

@ -20,7 +20,6 @@
*
* $URL$
* $Id$
*
*/
#ifndef COMMON_TIMER_H

1456
common/unzip.cpp Normal file

File diff suppressed because it is too large Load Diff

72
common/unzip.h Normal file
View File

@ -0,0 +1,72 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef COMMON_UNZIP_H
#define COMMON_UNZIP_H
#ifdef USE_ZLIB
#include "common/sys.h"
#include "common/archive.h"
typedef void *unzFile;
namespace Common {
class ZipArchive : public Archive {
void *_zipFile;
public:
/**
* Open the .zip archive with the given file name.
*/
ZipArchive(const String &name);
/**
* Open the .zip archive to which the given FSNode refers to.
*/
ZipArchive(const FSNode &node);
/**
* Open a .zip file from a stream. This takes ownership of the stream,
* in particular, it is closed when the ZipArchive is deleted.
*/
ZipArchive(SeekableReadStream *stream);
~ZipArchive();
bool isOpen() const;
virtual bool hasFile(const String &name);
virtual int listMembers(ArchiveMemberList &list);
virtual ArchiveMemberPtr getMember(const String &name);
virtual SeekableReadStream *createReadStreamForMember(const String &name) const;
};
} // End of namespace Common
#endif // USE_ZLIB
#endif /* _unz_H */

View File

@ -24,7 +24,7 @@
#include "common/util.h"
#include "common/system.h"
#include "common/str.h"
#include "gui/debugger.h"
#include "engines/engine.h"
#include <stdarg.h> // For va_list etc.
@ -461,7 +461,13 @@ void NORETURN error(const char *s, ...) {
vsnprintf(buf_input, STRINGBUFLEN, s, va);
va_end(va);
strncpy(buf_output, buf_input, STRINGBUFLEN);
// Next, give the active engine (if any) a chance to augment the message
if (g_engine) {
g_engine->errorString(buf_input, buf_output, STRINGBUFLEN);
} else {
strncpy(buf_output, buf_input, STRINGBUFLEN);
}
buf_output[STRINGBUFLEN-3] = '\0';
buf_output[STRINGBUFLEN-2] = '\0';
@ -472,6 +478,20 @@ void NORETURN error(const char *s, ...) {
// Print the error message to stderr
fputs(buf_output, stderr);
// Unless this error -originated- within the debugger itself, we
// now invoke the debugger, if available / supported.
if (g_engine) {
GUI::Debugger *debugger = g_engine->getDebugger();
#ifdef _WIN32_WCE
if (isSmartphone())
debugger = 0;
#endif
if (debugger && !debugger->isAttached()) {
debugger->attach(buf_output);
debugger->onFrame();
}
}
#if defined( USE_WINDBG )
#if defined( _WIN32_WCE )

412
common/xmlparser.cpp Normal file
View File

@ -0,0 +1,412 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "common/xmlparser.h"
#include "common/util.h"
#include "common/archive.h"
#include "common/fs.h"
namespace Common {
bool XMLParser::loadFile(const Common::String &filename) {
_stream = SearchMan.createReadStreamForMember(filename);
if (!_stream)
return false;
_fileName = filename;
return true;
}
bool XMLParser::loadFile(const FSNode &node) {
_stream = node.createReadStream();
if (!_stream)
return false;
_fileName = node.getName();
return true;
}
bool XMLParser::loadBuffer(const byte *buffer, uint32 size, bool disposable) {
_stream = new MemoryReadStream(buffer, size, disposable);
_fileName = "Memory Stream";
return true;
}
bool XMLParser::loadStream(Common::SeekableReadStream *stream) {
_stream = stream;
_fileName = "File Stream";
return true;
}
void XMLParser::close() {
delete _stream;
_stream = 0;
}
bool XMLParser::parserError(const char *errorString, ...) {
_state = kParserError;
const int startPosition = _stream->pos();
int currentPosition = startPosition;
int lineCount = 1;
char c = 0;
_stream->seek(0, SEEK_SET);
while (currentPosition--) {
c = _stream->readByte();
if (c == '\n' || c == '\r')
lineCount++;
}
assert(_stream->pos() == startPosition);
currentPosition = startPosition;
int keyOpening = 0;
int keyClosing = 0;
while (currentPosition-- && keyOpening == 0) {
_stream->seek(-2, SEEK_CUR);
c = _stream->readByte();
if (c == '<')
keyOpening = currentPosition - 1;
else if (c == '>')
keyClosing = currentPosition;
}
_stream->seek(startPosition, SEEK_SET);
currentPosition = startPosition;
while (keyClosing == 0 && c && currentPosition++) {
c = _stream->readByte();
if (c == '>')
keyClosing = currentPosition;
}
fprintf(stderr, "\n File <%s>, line %d:\n", _fileName.c_str(), lineCount);
currentPosition = (keyClosing - keyOpening);
_stream->seek(keyOpening, SEEK_SET);
while (currentPosition--)
fprintf(stderr, "%c", _stream->readByte());
fprintf(stderr, "\n\nParser error: ");
va_list args;
va_start(args, errorString);
vfprintf(stderr, errorString, args);
va_end(args);
fprintf(stderr, "\n\n");
return false;
}
bool XMLParser::parseXMLHeader(ParserNode *node) {
assert(node->header);
if (_activeKey.size() != 1)
return parserError("XML Header is expected in the global scope.");
if (!node->values.contains("version"))
return parserError("Missing XML version in XML header.");
if (node->values["version"] != "1.0")
return parserError("Unsupported XML version.");
return true;
}
bool XMLParser::parseActiveKey(bool closed) {
bool ignore = false;
assert(_activeKey.empty() == false);
ParserNode *key = _activeKey.top();
if (key->name == "xml" && key->header == true) {
assert(closed);
return parseXMLHeader(key) && closeKey();
}
XMLKeyLayout *layout = (_activeKey.size() == 1) ? _XMLkeys : getParentNode(key)->layout;
if (layout->children.contains(key->name)) {
key->layout = layout->children[key->name];
Common::StringMap localMap = key->values;
int keyCount = localMap.size();
for (Common::List<XMLKeyLayout::XMLKeyProperty>::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) {
if (i->required && !localMap.contains(i->name))
return parserError("Missing required property '%s' inside key '%s'", i->name.c_str(), key->name.c_str());
else if (localMap.contains(i->name))
keyCount--;
}
if (keyCount > 0)
return parserError("Unhandled property inside key '%s'.", key->name.c_str());
} else {
return parserError("Unexpected key in the active scope ('%s').", key->name.c_str());
}
// check if any of the parents must be ignored.
// if a parent is ignored, all children are too.
for (int i = _activeKey.size() - 1; i >= 0; --i) {
if (_activeKey[i]->ignore)
ignore = true;
}
if (ignore == false && keyCallback(key) == false) {
// HACK: People may be stupid and overlook the fact that
// when keyCallback() fails, a parserError() must be set.
// We set it manually in that case.
if (_state != kParserError)
parserError("Unhandled exception when parsing '%s' key.", key->name.c_str());
return false;
}
if (closed)
return closeKey();
return true;
}
bool XMLParser::parseKeyValue(Common::String keyName) {
assert(_activeKey.empty() == false);
if (_activeKey.top()->values.contains(keyName))
return false;
_token.clear();
char stringStart;
if (_char == '"' || _char == '\'') {
stringStart = _char;
_char = _stream->readByte();
while (_char && _char != stringStart) {
_token += _char;
_char = _stream->readByte();
}
if (_char == 0)
return false;
_char = _stream->readByte();
} else if (!parseToken()) {
return false;
}
_activeKey.top()->values[keyName] = _token;
return true;
}
bool XMLParser::closeKey() {
bool ignore = false;
bool result = true;
for (int i = _activeKey.size() - 1; i >= 0; --i) {
if (_activeKey[i]->ignore)
ignore = true;
}
if (ignore == false)
result = closedKeyCallback(_activeKey.top());
freeNode(_activeKey.pop());
return result;
}
bool XMLParser::parse() {
if (_stream == 0)
return parserError("XML stream not ready for reading.");
if (_XMLkeys == 0)
buildLayout();
while (!_activeKey.empty())
freeNode(_activeKey.pop());
cleanup();
bool activeClosure = false;
bool activeHeader = false;
bool selfClosure;
_state = kParserNeedHeader;
_activeKey.clear();
_char = _stream->readByte();
while (_char && _state != kParserError) {
if (skipSpaces())
continue;
if (skipComments())
continue;
switch (_state) {
case kParserNeedHeader:
case kParserNeedKey:
if (_char != '<') {
parserError("Parser expecting key start.");
break;
}
if ((_char = _stream->readByte()) == 0) {
parserError("Unexpected end of file.");
break;
}
if (_state == kParserNeedHeader) {
if (_char != '?') {
parserError("Expecting XML header.");
break;
}
_char = _stream->readByte();
activeHeader = true;
} else if (_char == '/') {
_char = _stream->readByte();
activeClosure = true;
} else if (_char == '?') {
parserError("Unexpected header. There may only be one XML header per file.");
break;
}
_state = kParserNeedKeyName;
break;
case kParserNeedKeyName:
if (!parseToken()) {
parserError("Invalid key name.");
break;
}
if (activeClosure) {
if (_activeKey.empty() || _token != _activeKey.top()->name) {
parserError("Unexpected closure.");
break;
}
} else {
ParserNode *node = allocNode(); //new ParserNode;
node->name = _token;
node->ignore = false;
node->header = activeHeader;
node->depth = _activeKey.size();
node->layout = 0;
_activeKey.push(node);
}
_state = kParserNeedPropertyName;
break;
case kParserNeedPropertyName:
if (activeClosure) {
if (!closeKey()) {
parserError("Missing data when closing key '%s'.", _activeKey.top()->name.c_str());
break;
}
activeClosure = false;
if (_char != '>')
parserError("Invalid syntax in key closure.");
else
_state = kParserNeedKey;
_char = _stream->readByte();
break;
}
selfClosure = false;
if (_char == '/' || (_char == '?' && activeHeader)) {
selfClosure = true;
_char = _stream->readByte();
}
if (_char == '>') {
if (activeHeader && !selfClosure) {
parserError("XML Header must be self-closed.");
} else if (parseActiveKey(selfClosure)) {
_char = _stream->readByte();
_state = kParserNeedKey;
}
activeHeader = false;
break;
}
if (selfClosure)
parserError("Expecting key closure after '/' symbol.");
else if (!parseToken())
parserError("Error when parsing key value.");
else
_state = kParserNeedPropertyOperator;
break;
case kParserNeedPropertyOperator:
if (_char != '=')
parserError("Syntax error after key name.");
else
_state = kParserNeedPropertyValue;
_char = _stream->readByte();
break;
case kParserNeedPropertyValue:
if (!parseKeyValue(_token))
parserError("Invalid key value.");
else
_state = kParserNeedPropertyName;
break;
default:
break;
}
}
if (_state == kParserError)
return false;
if (_state != kParserNeedKey || !_activeKey.empty())
return parserError("Unexpected end of file.");
return true;
}
}

453
common/xmlparser.h Normal file
View File

@ -0,0 +1,453 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef XML_PARSER_H
#define XML_PARSER_H
#include "common/sys.h"
#include "common/stream.h"
#include "common/list.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "common/stack.h"
namespace Common {
class FSNode;
/*
XMLParser.cpp/h -- Generic XML Parser
=====================================
External documentation available at:
http://www.smartlikearoboc.com/scummvm_doc/xmlparser_doc.html
*/
#define MAX_XML_DEPTH 8
#define XML_KEY(keyName) {\
lay = new CustomXMLKeyLayout;\
lay->callback = (&kLocalParserName::parserCallback_##keyName);\
layout.top()->children[#keyName] = lay;\
layout.push(lay); \
_layoutList.push_back(lay);
#define XML_KEY_RECURSIVE(keyName) {\
layout.top()->children[#keyName] = layout.top();\
layout.push(layout.top());\
}
#define KEY_END() layout.pop(); }
#define XML_PROP(propName, req) {\
prop.name = #propName; \
prop.required = req; \
layout.top()->properties.push_back(prop); }
#define CUSTOM_XML_PARSER(parserName) \
protected: \
typedef parserName kLocalParserName; \
bool keyCallback(ParserNode *node) {return node->layout->doCallback(this, node); }\
struct CustomXMLKeyLayout : public XMLKeyLayout {\
typedef bool (parserName::*ParserCallback)(ParserNode *node);\
ParserCallback callback;\
bool doCallback(XMLParser *parent, ParserNode *node) {return ((kLocalParserName*)parent->*callback)(node);} };\
virtual void buildLayout() { \
Common::Stack<XMLKeyLayout*> layout; \
CustomXMLKeyLayout *lay = 0; \
XMLKeyLayout::XMLKeyProperty prop; \
_XMLkeys = new CustomXMLKeyLayout; \
layout.push(_XMLkeys);
#define PARSER_END() layout.clear(); }
/**
* The base XMLParser class implements generic functionality for parsing
* XML-like files.
*
* In order to use it, it must be inherited with a child class that implements
* the XMLParser::keyCallback() function.
*
* @see XMLParser::keyCallback()
*/
class XMLParser {
static const int kErrorMessageWidth = 512;
public:
/**
* Parser constructor.
*/
XMLParser() : _XMLkeys(0), _stream(0) {}
virtual ~XMLParser() {
while (!_activeKey.empty())
freeNode(_activeKey.pop());
delete _XMLkeys;
delete _stream;
for (Common::List<XMLKeyLayout*>::iterator i = _layoutList.begin();
i != _layoutList.end(); ++i)
delete *i;
_layoutList.clear();
}
/** Active state for the parser */
enum ParserState {
kParserNeedHeader,
kParserNeedKey,
kParserNeedKeyName,
kParserNeedPropertyName,
kParserNeedPropertyOperator,
kParserNeedPropertyValue,
kParserError
};
struct XMLKeyLayout;
struct ParserNode;
typedef Common::HashMap<Common::String, XMLParser::XMLKeyLayout*, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ChildMap;
/** nested struct representing the layout of the XML file */
struct XMLKeyLayout {
struct XMLKeyProperty {
Common::String name;
bool required;
};
Common::List<XMLKeyProperty> properties;
ChildMap children;
virtual bool doCallback(XMLParser *parent, ParserNode *node) = 0;
virtual ~XMLKeyLayout() {
properties.clear();
}
};
XMLKeyLayout *_XMLkeys;
/** Struct representing a parsed node */
struct ParserNode {
Common::String name;
Common::StringMap values;
bool ignore;
bool header;
int depth;
XMLKeyLayout *layout;
};
ObjectPool<ParserNode, MAX_XML_DEPTH> _nodePool;
ParserNode *allocNode() {
return new (_nodePool) ParserNode;
}
void freeNode(ParserNode *node) {
_nodePool.deleteChunk(node);
}
/**
* Loads a file into the parser.
* Used for the loading of Theme Description files
* straight from the filesystem.
*
* @param filename Name of the file to load.
*/
bool loadFile(const Common::String &filename);
bool loadFile(const FSNode &node);
/**
* Loads a memory buffer into the parser.
* Used for loading the default theme fallback directly
* from memory if no themes can be found.
*
* @param buffer Pointer to the buffer.
* @param size Size of the buffer
* @param disposable Sets if the XMLParser owns the buffer,
* i.e. if it can be freed safely after it's
* no longer needed by the parser.
*/
bool loadBuffer(const byte *buffer, uint32 size, bool disposable = false);
bool loadStream(Common::SeekableReadStream *stream);
void close();
/**
* The actual parsing function.
* Parses the loaded data stream, returns true if successful.
*/
bool parse();
/**
* Returns the active node being parsed (the one on top of
* the node stack).
*/
ParserNode *getActiveNode() {
if (!_activeKey.empty())
return _activeKey.top();
return 0;
}
/**
* Returns the parent of a given node in the stack.
*/
ParserNode *getParentNode(ParserNode *child) {
return child->depth > 0 ? _activeKey[child->depth - 1] : 0;
}
protected:
/**
* The buildLayout function builds the layout for the parser to use
* based on a series of helper macros. This function is automatically
* generated by the CUSTOM_XML_PARSER() macro on custom parsers.
*
* See the documentation regarding XML layouts.
*/
virtual void buildLayout() = 0;
/**
* The keycallback function is automatically overloaded on custom parsers
* when using the CUSTOM_XML_PARSER() macro.
*
* Its job is to call the corresponding Callback function for the given node.
* A function for each key type must be declared separately. See the custom
* parser creation instructions.
*
* When parsing a key in such function, one may chose to skip it, e.g. because it's not needed
* on the current configuration. In order to ignore a key, you must set
* the "ignore" field of its KeyNode struct to "true": The key and all its children
* will then be automatically ignored by the parser.
*
* The callback function must return true if the key was properly handled (this includes the case when the
* key is being ignored). False otherwise. The return of keyCallback() is the same as
* the callback function's.
* See the sample implementation in GUI::ThemeParser.
*/
virtual bool keyCallback(ParserNode *node) = 0;
/**
* The closed key callback function MAY be overloaded by inheriting classes to
* implement parser-specific functions.
*
* The closedKeyCallback is issued once a key has been finished parsing, to let
* the parser verify that all the required subkeys, etc, were included.
*
* Unlike the keyCallbacks(), there's just a closedKeyCallback() for all keys.
* Use "node->name" to distinguish between each key type.
*
* Returns true if the key was properly closed, false otherwise.
* By default, all keys are properly closed.
*/
virtual bool closedKeyCallback(ParserNode *node) {
return true;
}
/**
* Called when a node is closed. Manages its cleanup and calls the
* closing callback function if needed.
*/
bool closeKey();
/**
* Parses the value of a given key. There's no reason to overload this.
*/
bool parseKeyValue(Common::String keyName);
/**
* Called once a key has been parsed. It handles the closing/cleanup of the
* node stack and calls the keyCallback.
*/
bool parseActiveKey(bool closed);
/**
* Prints an error message when parsing fails and stops the parser.
* Parser error always returns "false" so we can pass the return value directly
* and break down the parsing.
*/
bool parserError(const char *errorString, ...) GCC_PRINTF(2, 3);
/**
* Skips spaces/whitelines etc. Returns true if any spaces were skipped.
*/
bool skipSpaces() {
if (!isspace(_char))
return false;
while (_char && isspace(_char))
_char = _stream->readByte();
return true;
}
/**
* Skips comment blocks and comment lines.
* Returns true if any comments were skipped.
* Overload this if you want to disable comments on your XML syntax
* or to change the commenting syntax.
*/
virtual bool skipComments() {
if (_char == '<') {
_char = _stream->readByte();
if (_char != '!') {
_stream->seek(-1, SEEK_CUR);
_char = '<';
return false;
}
if (_stream->readByte() != '-' || _stream->readByte() != '-')
return parserError("Malformed comment syntax.");
_char = _stream->readByte();
while (_char) {
if (_char == '-') {
if (_stream->readByte() == '-') {
if (_stream->readByte() != '>')
return parserError("Malformed comment (double-hyphen inside comment body).");
_char = _stream->readByte();
return true;
}
}
_char = _stream->readByte();
}
return parserError("Comment has no closure.");
}
return false;
}
/**
* Check if a given character can be part of a KEY or VALUE name.
* Overload this if you want to support keys with strange characters
* in their name.
*/
virtual inline bool isValidNameChar(char c) {
return isalnum(c) || c == '_';
}
/**
* Parses a the first textual token found.
* There's no reason to overload this.
*/
bool parseToken() {
_token.clear();
while (isValidNameChar(_char)) {
_token += _char;
_char = _stream->readByte();
}
return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/';
}
/**
* Parses the values inside an integer key.
* The count parameter specifies the number of values inside
* the key, which are expected to be separated with commas.
*
* Sample usage:
* parseIntegerKey("255, 255, 255", 3, &red, &green, &blue);
* [will parse each field into its own integer]
*
* parseIntegerKey("1234", 1, &number);
* [will parse the single number into the variable]
*
* @param key String containing the integers to be parsed.
* @param count Number of comma-separated ints in the string.
* @param ... Integer variables to store the parsed ints, passed
* by reference.
* @returns True if the parsing succeeded.
*/
bool parseIntegerKey(const char *key, int count, ...) {
char *parseEnd;
int *num_ptr;
va_list args;
va_start(args, count);
while (count--) {
while (isspace(*key))
key++;
num_ptr = va_arg(args, int*);
*num_ptr = strtol(key, &parseEnd, 10);
key = parseEnd;
while (isspace(*key))
key++;
if (count && *key++ != ',')
return false;
}
va_end(args);
return (*key == 0);
}
bool parseXMLHeader(ParserNode *node);
/**
* Overload if your parser needs to support parsing the same file
* several times, so you can clean up the internal state of the
* parser before each parse.
*/
virtual void cleanup() {}
Common::List<XMLKeyLayout*> _layoutList;
private:
char _char;
SeekableReadStream *_stream;
Common::String _fileName;
ParserState _state; /** Internal state of the parser */
Common::String _error; /** Current error message */
Common::String _token; /** Current text token */
Common::Stack<ParserNode*> _activeKey; /** Node stack of the parsed keys */
};
}
#endif

32
configure vendored
View File

@ -77,6 +77,9 @@ _vorbis=auto
_tremor=auto
_flac=auto
_mad=auto
# Default vkeybd/keymapper options
_vkeybd=no
_keymapper=no
# Default platform settings
_backend=sdl
_endian=unknown
@ -490,7 +493,7 @@ Usage: $0 [OPTIONS]...
Configuration:
-h, --help display this help and exit
--backend=BACKEND backend to build (sdl, morphos, dc, gp2x, iphone, wii, psp, null) [sdl]
--backend=BACKEND backend to build (sdl, morphos, dc, gp2x, gp2xwiz, iphone, wii, psp, null) [sdl]
Installation directories:
--prefix=DIR use this prefix for installing Residual [/usr/local]
@ -566,6 +569,10 @@ for ac_option in $@; do
--enable-plugins) _dynamic_modules=yes ;;
--enable-verbose-build) _verbose_build=yes ;;
--default-dynamic) _plugins_default=dynamic ;;
--enable-vkeybd) _vkeybd=yes ;;
--disable-vkeybd) _vkeybd=no ;;
--enable-keymapper) _keymapper=yes ;;
--disable-keymapper) _keymapper=no ;;
--with-ogg-prefix=*)
arg=`echo $ac_option | cut -d '=' -f 2`
OGG_CFLAGS="-I$arg/include"
@ -1041,6 +1048,10 @@ case $_host_os in
LIBS="$LIBS -lmingw32 -lopengl32 -lglu32"
OBJS="$OBJS residualico.o"
;;
cygwin*)
echo ERROR: Cygwin building is not supported by ScummVM anymore. Consider using MinGW.
exit 0
;;
os2-emx*)
DEFINES="$DEFINES -DUNIX"
;;
@ -1611,6 +1622,16 @@ echo "$_zlib"
rm -rf $TMPC $TMPO$EXEEXT $TMPO.dSYM
#
# Enable vkeybd / keymapper
#
if test "$_vkeybd" = yes ; then
DEFINES="$DEFINES -DENABLE_VKEYBD"
fi
if test "$_keymapper" = yes ; then
DEFINES="$DEFINES -DENABLE_KEYMAPPER"
fi
#
# Figure out installation directories
#
@ -1626,6 +1647,15 @@ DEFINES="$DEFINES -DPLUGIN_DIRECTORY=\\\"$_libdir/residual\\\""
echo_n "Backend... "
echo_n "$_backend"
echo
if test "$_vkeybd" = yes ; then
echo_n ", virtual keyboard"
fi
if test "$_keymapper" = yes ; then
echo ", keymapper"
else
echo
fi
#
# Backend related stuff

View File

@ -348,6 +348,10 @@
RelativePath="..\..\common\singleton.h"
>
</File>
<File
RelativePath="..\..\common\stack.h"
>
</File>
<File
RelativePath="..\..\common\str.cpp"
>
@ -380,6 +384,14 @@
RelativePath="..\..\common\timer.h"
>
</File>
<File
RelativePath="..\..\common\unzip.cpp"
>
</File>
<File
RelativePath="..\..\common\unzip.h"
>
</File>
<File
RelativePath="..\..\common\util.cpp"
>
@ -388,6 +400,14 @@
RelativePath="..\..\common\util.h"
>
</File>
<File
RelativePath="..\..\common\xmlparser.cpp"
>
</File>
<File
RelativePath="..\..\common\xmlparser.h"
>
</File>
</Filter>
<Filter
Name="dists"
@ -408,6 +428,14 @@
RelativePath="..\..\engines\advancedDetector.h"
>
</File>
<File
RelativePath="..\..\engines\dialogs.cpp"
>
</File>
<File
RelativePath="..\..\engines\dialogs.h"
>
</File>
<File
RelativePath="..\..\engines\engine.cpp"
>
@ -589,10 +617,154 @@
</File>
</Filter>
</Filter>
<Filter
Name="keymapper"
>
<File
RelativePath="..\..\backends\keymapper\action.cpp"
>
</File>
<File
RelativePath="..\..\backends\keymapper\action.h"
>
</File>
<File
RelativePath="..\..\backends\keymapper\hardware-key.h"
>
</File>
<File
RelativePath="..\..\backends\keymapper\keymap.cpp"
>
</File>
<File
RelativePath="..\..\backends\keymapper\keymap.h"
>
</File>
<File
RelativePath="..\..\backends\keymapper\keymapper.cpp"
>
</File>
<File
RelativePath="..\..\backends\keymapper\keymapper.h"
>
</File>
<File
RelativePath="..\..\backends\keymapper\remap-dialog.cpp"
>
</File>
<File
RelativePath="..\..\backends\keymapper\remap-dialog.h"
>
</File>
<File
RelativePath="..\..\backends\keymapper\types.h"
>
</File>
</Filter>
<Filter
Name="vkeybd"
>
<File
RelativePath="..\..\backends\vkeybd\image-map.cpp"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\image-map.h"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\keycode-descriptions.h"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\polygon.cpp"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\polygon.h"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.cpp"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\virtual-keyboard-gui.h"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.cpp"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\virtual-keyboard-parser.h"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\virtual-keyboard.cpp"
>
</File>
<File
RelativePath="..\..\backends\vkeybd\virtual-keyboard.h"
>
</File>
</Filter>
<Filter
Name="plugins"
>
<File
RelativePath="..\..\backends\plugins\dynamic-plugin.h"
>
</File>
<File
RelativePath="..\..\backends\plugins\win32\win32-provider.cpp"
>
</File>
<File
RelativePath="..\..\backends\plugins\win32\win32-provider.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="graphics"
>
<File
RelativePath="..\..\graphics\colormasks.h"
>
</File>
<File
RelativePath="..\..\graphics\cursorman.cpp"
>
</File>
<File
RelativePath="..\..\graphics\cursorman.h"
>
</File>
<File
RelativePath="..\..\graphics\font.cpp"
>
</File>
<File
RelativePath="..\..\graphics\font.h"
>
</File>
<File
RelativePath="..\..\graphics\fontman.cpp"
>
</File>
<File
RelativePath="..\..\graphics\fontman.h"
>
</File>
<File
RelativePath="..\..\graphics\imagedec.cpp"
>
</File>
<File
RelativePath="..\..\graphics\imagedec.h"
>
</File>
<File
RelativePath="..\..\graphics\matrix3.cpp"
>
@ -609,10 +781,58 @@
RelativePath="..\..\graphics\matrix4.h"
>
</File>
<File
RelativePath="..\..\graphics\pixelformat.h"
>
</File>
<File
RelativePath="..\..\graphics\primitives.cpp"
>
</File>
<File
RelativePath="..\..\graphics\primitives.h"
>
</File>
<File
RelativePath="..\..\graphics\scaler.h"
>
</File>
<File
RelativePath="..\..\graphics\surface.cpp"
>
</File>
<File
RelativePath="..\..\graphics\surface.h"
>
</File>
<File
RelativePath="..\..\graphics\thumbnail.cpp"
>
</File>
<File
RelativePath="..\..\graphics\thumbnail.h"
>
</File>
<File
RelativePath="..\..\graphics\vector3d.h"
>
</File>
<File
RelativePath="..\..\graphics\VectorRenderer.cpp"
>
</File>
<File
RelativePath="..\..\graphics\VectorRenderer.h"
>
</File>
<File
RelativePath="..\..\graphics\VectorRendererSpec.cpp"
>
</File>
<File
RelativePath="..\..\graphics\VectorRendererSpec.h"
>
</File>
<Filter
Name="tinygl"
>
@ -733,6 +953,34 @@
>
</File>
</Filter>
<Filter
Name="fonts"
>
<File
RelativePath="..\..\graphics\fonts\consolefont.cpp"
>
</File>
<File
RelativePath="..\..\graphics\fonts\newfont.cpp"
>
</File>
<File
RelativePath="..\..\graphics\fonts\newfont_big.cpp"
>
</File>
<File
RelativePath="..\..\graphics\fonts\scummfont.cpp"
>
</File>
</Filter>
<Filter
Name="scaler"
>
<File
RelativePath="..\..\graphics\scaler\intern.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="base"
@ -774,6 +1022,238 @@
>
</File>
</Filter>
<Filter
Name="gui"
>
<File
RelativePath="..\..\gui\about.cpp"
>
</File>
<File
RelativePath="..\..\gui\about.h"
>
</File>
<File
RelativePath="..\..\gui\Actions.cpp"
>
</File>
<File
RelativePath="..\..\gui\Actions.h"
>
</File>
<File
RelativePath="..\..\gui\browser.cpp"
>
</File>
<File
RelativePath="..\..\gui\browser.h"
>
</File>
<File
RelativePath="..\..\gui\chooser.cpp"
>
</File>
<File
RelativePath="..\..\gui\chooser.h"
>
</File>
<File
RelativePath="..\..\gui\console.cpp"
>
</File>
<File
RelativePath="..\..\gui\console.h"
>
</File>
<File
RelativePath="..\..\gui\credits.h"
>
</File>
<File
RelativePath="..\..\gui\debugger.cpp"
>
</File>
<File
RelativePath="..\..\gui\debugger.h"
>
</File>
<File
RelativePath="..\..\gui\dialog.cpp"
>
</File>
<File
RelativePath="..\..\gui\dialog.h"
>
</File>
<File
RelativePath="..\..\gui\editable.cpp"
>
</File>
<File
RelativePath="..\..\gui\editable.h"
>
</File>
<File
RelativePath="..\..\gui\EditTextWidget.cpp"
>
</File>
<File
RelativePath="..\..\gui\EditTextWidget.h"
>
</File>
<File
RelativePath="..\..\gui\GuiManager.cpp"
>
</File>
<File
RelativePath="..\..\gui\GuiManager.h"
>
</File>
<File
RelativePath="..\..\gui\Key.cpp"
>
</File>
<File
RelativePath="..\..\gui\Key.h"
>
</File>
<File
RelativePath="..\..\gui\KeysDialog.cpp"
>
</File>
<File
RelativePath="..\..\gui\KeysDialog.h"
>
</File>
<File
RelativePath="..\..\gui\launcher.cpp"
>
</File>
<File
RelativePath="..\..\gui\launcher.h"
>
</File>
<File
RelativePath="..\..\gui\ListWidget.cpp"
>
</File>
<File
RelativePath="..\..\gui\ListWidget.h"
>
</File>
<File
RelativePath="..\..\gui\massadd.cpp"
>
</File>
<File
RelativePath="..\..\gui\massadd.h"
>
</File>
<File
RelativePath="..\..\gui\message.cpp"
>
</File>
<File
RelativePath="..\..\gui\message.h"
>
</File>
<File
RelativePath="..\..\gui\object.cpp"
>
</File>
<File
RelativePath="..\..\gui\object.h"
>
</File>
<File
RelativePath="..\..\gui\options.cpp"
>
</File>
<File
RelativePath="..\..\gui\options.h"
>
</File>
<File
RelativePath="..\..\gui\PopUpWidget.cpp"
>
</File>
<File
RelativePath="..\..\gui\PopUpWidget.h"
>
</File>
<File
RelativePath="..\..\gui\saveload.cpp"
>
</File>
<File
RelativePath="..\..\gui\saveload.h"
>
</File>
<File
RelativePath="..\..\gui\ScrollBarWidget.cpp"
>
</File>
<File
RelativePath="..\..\gui\ScrollBarWidget.h"
>
</File>
<File
RelativePath="..\..\gui\TabWidget.cpp"
>
</File>
<File
RelativePath="..\..\gui\TabWidget.h"
>
</File>
<File
RelativePath="..\..\gui\themebrowser.cpp"
>
</File>
<File
RelativePath="..\..\gui\themebrowser.h"
>
</File>
<File
RelativePath="..\..\gui\ThemeEngine.cpp"
>
</File>
<File
RelativePath="..\..\gui\ThemeEngine.h"
>
</File>
<File
RelativePath="..\..\gui\ThemeEval.cpp"
>
</File>
<File
RelativePath="..\..\gui\ThemeEval.h"
>
</File>
<File
RelativePath="..\..\gui\ThemeLayout.cpp"
>
</File>
<File
RelativePath="..\..\gui\ThemeLayout.h"
>
</File>
<File
RelativePath="..\..\gui\ThemeParser.cpp"
>
</File>
<File
RelativePath="..\..\gui\ThemeParser.h"
>
</File>
<File
RelativePath="..\..\gui\widget.cpp"
>
</File>
<File
RelativePath="..\..\gui\widget.h"
>
</File>
</Filter>
<File
RelativePath="..\..\README"
>

327
engines/dialogs.cpp Normal file
View File

@ -0,0 +1,327 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "base/version.h"
#include "common/config-manager.h"
#include "common/savefile.h"
#include "common/system.h"
#include "common/events.h"
#include "gui/about.h"
#include "gui/GuiManager.h"
#include "gui/launcher.h"
#include "gui/ListWidget.h"
#include "gui/ThemeEval.h"
#include "gui/saveload.h"
#include "engines/dialogs.h"
#include "engines/engine.h"
#include "engines/metaengine.h"
#ifdef SMALL_SCREEN_DEVICE
#include "gui/KeysDialog.h"
#endif
using GUI::CommandSender;
using GUI::StaticTextWidget;
using GUI::kCloseCmd;
using GUI::WIDGET_ENABLED;
typedef GUI::OptionsDialog GUI_OptionsDialog;
typedef GUI::Dialog GUI_Dialog;
enum {
kSaveCmd = 'SAVE',
kLoadCmd = 'LOAD',
kPlayCmd = 'PLAY',
kOptionsCmd = 'OPTN',
kHelpCmd = 'HELP',
kAboutCmd = 'ABOU',
kQuitCmd = 'QUIT',
kRTLCmd = 'RTL ',
kChooseCmd = 'CHOS'
};
MainMenuDialog::MainMenuDialog(Engine *engine)
: GUI::Dialog("GlobalMenu"), _engine(engine) {
_backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial;
#ifndef DISABLE_FANCY_THEMES
_logo = 0;
if (g_gui.xmlEval()->getVar("Globals.ShowGlobalMenuLogo", 0) == 1 && g_gui.theme()->supportsImages()) {
_logo = new GUI::GraphicsWidget(this, "GlobalMenu.Logo");
_logo->useThemeTransparency(true);
_logo->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageLogoSmall));
} else {
StaticTextWidget *title = new StaticTextWidget(this, "GlobalMenu.Title", "Residual");
title->setAlign(Graphics::kTextAlignCenter);
}
#else
StaticTextWidget *title = new StaticTextWidget(this, "GlobalMenu.Title", "Residual");
title->setAlign(Graphics::kTextAlignCenter);
#endif
StaticTextWidget *version = new StaticTextWidget(this, "GlobalMenu.Version", gResidualVersionDate);
version->setAlign(Graphics::kTextAlignCenter);
new GUI::ButtonWidget(this, "GlobalMenu.Resume", "Resume", kPlayCmd, 'P');
_loadButton = new GUI::ButtonWidget(this, "GlobalMenu.Load", "Load", kLoadCmd, 'L');
// TODO: setEnabled -> setVisible
_loadButton->setEnabled(_engine->hasFeature(Engine::kSupportsLoadingDuringRuntime));
_saveButton = new GUI::ButtonWidget(this, "GlobalMenu.Save", "Save", kSaveCmd, 'S');
// TODO: setEnabled -> setVisible
_saveButton->setEnabled(_engine->hasFeature(Engine::kSupportsSavingDuringRuntime));
new GUI::ButtonWidget(this, "GlobalMenu.Options", "Options", kOptionsCmd, 'O');
new GUI::ButtonWidget(this, "GlobalMenu.About", "About", kAboutCmd, 'A');
_rtlButton = new GUI::ButtonWidget(this, "GlobalMenu.RTL", "Return to Launcher", kRTLCmd, 'R');
_rtlButton->setEnabled(_engine->hasFeature(Engine::kSupportsRTL));
new GUI::ButtonWidget(this, "GlobalMenu.Quit", "Quit", kQuitCmd, 'Q');
_aboutDialog = new GUI::AboutDialog();
_optionsDialog = new ConfigDialog(_engine->hasFeature(Engine::kSupportsSubtitleOptions));
_loadDialog = new GUI::SaveLoadChooser("Load game:", "Load");
_loadDialog->setSaveMode(false);
_saveDialog = new GUI::SaveLoadChooser("Save game:", "Save");
_saveDialog->setSaveMode(true);
}
MainMenuDialog::~MainMenuDialog() {
delete _aboutDialog;
delete _optionsDialog;
delete _loadDialog;
delete _saveDialog;
}
void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kPlayCmd:
close();
break;
case kLoadCmd:
{
Common::String gameId = ConfMan.get("gameid");
const EnginePlugin *plugin = 0;
EngineMan.findGame(gameId, &plugin);
int slot = _loadDialog->runModal(plugin, ConfMan.getActiveDomainName());
if (slot >= 0) {
// FIXME: For now we just ignore the return
// value, which is quite bad since it could
// be a fatal loading error, which renders
// the engine unusable.
_engine->loadGameState(slot);
close();
}
}
break;
case kSaveCmd:
{
Common::String gameId = ConfMan.get("gameid");
const EnginePlugin *plugin = 0;
EngineMan.findGame(gameId, &plugin);
int slot = _saveDialog->runModal(plugin, ConfMan.getActiveDomainName());
if (slot >= 0) {
Common::String result(_saveDialog->getResultString());
if (result.empty()) {
// If the user was lazy and entered no save name, come up with a default name.
char buf[20];
snprintf(buf, 20, "Save %d", slot + 1);
_engine->saveGameState(slot, buf);
} else {
_engine->saveGameState(slot, result.c_str());
}
close();
}
}
break;
case kOptionsCmd:
_optionsDialog->runModal();
break;
case kAboutCmd:
_aboutDialog->runModal();
break;
case kRTLCmd: {
Common::Event eventRTL;
eventRTL.type = Common::EVENT_RTL;
g_system->getEventManager()->pushEvent(eventRTL);
close();
}
break;
case kQuitCmd: {
Common::Event eventQ;
eventQ.type = Common::EVENT_QUIT;
g_system->getEventManager()->pushEvent(eventQ);
close();
}
break;
default:
GUI::Dialog::handleCommand(sender, cmd, data);
}
}
void MainMenuDialog::reflowLayout() {
if (_engine->hasFeature(Engine::kSupportsLoadingDuringRuntime))
_loadButton->setEnabled(_engine->canLoadGameStateCurrently());
if (_engine->hasFeature(Engine::kSupportsSavingDuringRuntime))
_saveButton->setEnabled(_engine->canSaveGameStateCurrently());
#ifndef DISABLE_FANCY_THEMES
if (g_gui.xmlEval()->getVar("Globals.ShowGlobalMenuLogo", 0) == 1 && g_gui.theme()->supportsImages()) {
if (!_logo)
_logo = new GUI::GraphicsWidget(this, "GlobalMenu.Logo");
_logo->useThemeTransparency(true);
_logo->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageLogoSmall));
GUI::StaticTextWidget *title = (StaticTextWidget *)findWidget("GlobalMenu.Title");
if (title) {
removeWidget(title);
title->setNext(0);
delete title;
}
} else {
GUI::StaticTextWidget *title = (StaticTextWidget *)findWidget("GlobalMenu.Title");
if (!title) {
title = new StaticTextWidget(this, "GlobalMenu.Title", "ScummVM");
title->setAlign(Graphics::kTextAlignCenter);
}
if (_logo) {
removeWidget(_logo);
_logo->setNext(0);
delete _logo;
_logo = 0;
}
}
#endif
Dialog::reflowLayout();
}
enum {
kOKCmd = 'ok '
};
enum {
kKeysCmd = 'KEYS'
};
// FIXME: We use the empty string as domain name here. This tells the
// ConfigManager to use the 'default' domain for all its actions. We do that
// to get as close as possible to editing the 'active' settings.
//
// However, that requires bad & evil hacks in the ConfigManager code,
// and even then still doesn't work quite correctly.
// For example, if the transient domain contains 'false' for the 'fullscreen'
// flag, but the user used a hotkey to switch to windowed mode, then the dialog
// will display the wrong value anyway.
//
// Proposed solution consisting of multiple steps:
// 1) Add special code to the open() code that reads out everything stored
// in the transient domain that is controlled by this dialog, and updates
// the dialog accordingly.
// 2) Even more code is added to query the backend for current settings, like
// the fullscreen mode flag etc., and also updates the dialog accordingly.
// 3) The domain being edited is set to the active game domain.
// 4) If the dialog is closed with the "OK" button, then we remove everything
// stored in the transient domain (or at least everything corresponding to
// switches in this dialog.
// If OTOH the dialog is closed with "Cancel" we do no such thing.
//
// These changes will achieve two things at once: Allow us to get rid of using
// "" as value for the domain, and in fact provide a somewhat better user
// experience at the same time.
ConfigDialog::ConfigDialog(bool subtitleControls)
: GUI::OptionsDialog("", "ScummConfig") {
//
// Sound controllers
//
addVolumeControls(this, "ScummConfig.");
setVolumeSettingsState(true); // could disable controls by GUI options
//
// Subtitle speed and toggle controllers
//
if (subtitleControls) {
// Global talkspeed range of 0-255
addSubtitleControls(this, "ScummConfig.", 255);
setSubtitleSettingsState(true); // could disable controls by GUI options
}
//
// Add the buttons
//
new GUI::ButtonWidget(this, "ScummConfig.Ok", "OK", GUI::OptionsDialog::kOKCmd, 'O');
new GUI::ButtonWidget(this, "ScummConfig.Cancel", "Cancel", kCloseCmd, 'C');
#ifdef SMALL_SCREEN_DEVICE
new GUI::ButtonWidget(this, "ScummConfig.Keys", "Keys", kKeysCmd, 'K');
_keysDialog = NULL;
#endif
}
ConfigDialog::~ConfigDialog() {
#ifdef SMALL_SCREEN_DEVICE
delete _keysDialog;
#endif
}
void ConfigDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kKeysCmd:
#ifdef SMALL_SCREEN_DEVICE
//
// Create the sub dialog(s)
//
_keysDialog = new GUI::KeysDialog();
_keysDialog->runModal();
delete _keysDialog;
_keysDialog = NULL;
#endif
break;
default:
GUI_OptionsDialog::handleCommand (sender, cmd, data);
}
}

75
engines/dialogs.h Normal file
View File

@ -0,0 +1,75 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef GLOBAL_DIALOGS_H
#define GLOBAL_DIALOGS_H
#include "common/str.h"
#include "gui/dialog.h"
#include "gui/options.h"
class Engine;
namespace GUI {
class ButtonWidget;
class GraphicsWidget;
class SaveLoadChooser;
}
class MainMenuDialog : public GUI::Dialog {
public:
MainMenuDialog(Engine *engine);
~MainMenuDialog();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
virtual void reflowLayout();
protected:
Engine *_engine;
GUI::GraphicsWidget *_logo;
GUI::ButtonWidget *_rtlButton;
GUI::ButtonWidget *_loadButton;
GUI::ButtonWidget *_saveButton;
GUI::Dialog *_aboutDialog;
GUI::Dialog *_optionsDialog;
GUI::SaveLoadChooser *_loadDialog;
GUI::SaveLoadChooser *_saveDialog;
};
class ConfigDialog : public GUI::OptionsDialog {
protected:
#ifdef SMALL_SCREEN_DEVICE
GUI::Dialog *_keysDialog;
#endif
public:
ConfigDialog(bool subtitleControls);
~ConfigDialog();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
};
#endif

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -36,13 +36,20 @@
#include "common/timer.h"
#include "common/savefile.h"
#include "common/system.h"
#include "gui/message.h"
#include "gui/GuiManager.h"
#include "sound/mixer.h"
#include "engines/dialogs.h"
#include "engines/metaengine.h"
#ifdef _WIN32_WCE
extern bool isSmartphone(void);
#endif
// FIXME: HACK for MidiEmu & error()
Engine *g_engine = 0;
Engine::Engine(OSystem *syst)
: _system(syst),
_mixer(_system->getMixer()),
@ -51,7 +58,10 @@ Engine::Engine(OSystem *syst)
_saveFileMan(_system->getSavefileManager()),
_targetName(ConfMan.getActiveDomainName()),
_gameDataDir(ConfMan.get("path")),
_pauseLevel(0) {
_pauseLevel(0),
_mainMenuDialog(NULL) {
g_engine = this;
// FIXME: Get rid of the following again. It is only here temporarily.
// We really should never run with a non-working Mixer, so ought to handle
@ -66,6 +76,85 @@ Engine::Engine(OSystem *syst)
Engine::~Engine() {
_mixer->stopAll();
delete _mainMenuDialog;
g_engine = NULL;
}
void GUIErrorMessage(const Common::String msg) {
g_system->setWindowCaption("Error");
g_system->launcherInitSize(320, 200);
GUI::MessageDialog dialog(msg);
dialog.runModal();
error("%s", msg.c_str());
}
void Engine::checkCD() {
#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
// It is a known bug under Windows that games that play CD audio cause
// ScummVM to crash if the data files are read from the same CD. Check
// if this appears to be the case and issue a warning.
// If we can find a compressed audio track, then it should be ok even
// if it's running from CD.
#ifdef USE_VORBIS
if (Common::File::exists("track1.ogg") ||
Common::File::exists("track01.ogg"))
return;
#endif
#ifdef USE_FLAC
if (Common::File::exists("track1.fla") ||
Common::File::exists("track1.flac") ||
Common::File::exists("track01.fla") ||
Common::File::exists("track01.flac"))
return;
#endif
#ifdef USE_MAD
if (Common::File::exists("track1.mp3") ||
Common::File::exists("track01.mp3"))
return;
#endif
char buffer[MAXPATHLEN];
int i;
if (_gameDataDir.getPath().empty()) {
// That's it! I give up!
if (getcwd(buffer, MAXPATHLEN) == NULL)
return;
} else
strncpy(buffer, _gameDataDir.getPath().c_str(), MAXPATHLEN);
for (i = 0; i < MAXPATHLEN - 1; i++) {
if (buffer[i] == '\\')
break;
}
buffer[i + 1] = 0;
if (GetDriveType(buffer) == DRIVE_CDROM) {
GUI::MessageDialog dialog(
"You appear to be playing this game directly\n"
"from the CD. This is known to cause problems,\n"
"and it is therefore recommended that you copy\n"
"the data files to your hard disk instead.\n"
"See the README file for details.", "OK");
dialog.runModal();
} else {
// If we reached here, the game has audio tracks,
// it's not ran from the CD and the tracks have not
// been ripped.
GUI::MessageDialog dialog(
"This game has audio tracks in its disk. These\n"
"tracks need to be ripped from the disk using\n"
"an appropriate CD audio extracting tool in\n"
"order to listen to the game's music.\n"
"See the README file for details.", "OK");
dialog.runModal();
}
#endif
}
bool Engine::shouldPerformAutoSave(int lastSaveTime) {
@ -74,6 +163,12 @@ bool Engine::shouldPerformAutoSave(int lastSaveTime) {
return autosavePeriod != 0 && diff > autosavePeriod * 1000;
}
void Engine::errorString(const char *buf1, char *buf2, int size) {
strncpy(buf2, buf1, size);
if (size > 0)
buf2[size-1] = '\0';
}
void Engine::pauseEngine(bool pause) {
assert((pause && _pauseLevel >= 0) || (!pause && _pauseLevel));
@ -94,6 +189,21 @@ void Engine::pauseEngineIntern(bool pause) {
_mixer->pauseAll(pause);
}
void Engine::openMainMenuDialog() {
if (!_mainMenuDialog)
_mainMenuDialog = new MainMenuDialog(this);
runDialog(*_mainMenuDialog);
syncSoundSettings();
}
int Engine::runDialog(GUI::Dialog &dialog) {
pauseEngine(true);
int result = dialog.runModal();
pauseEngine(false);
return result;
}
void Engine::syncSoundSettings() {
// Sync the engine with the config manager
@ -151,7 +261,7 @@ void Engine::quitGame() {
bool Engine::shouldQuit() {
Common::EventManager *eventMan = g_system->getEventManager();
return (eventMan->shouldQuit());
return (eventMan->shouldQuit() || eventMan->shouldRTL());
}
/*

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -40,6 +40,15 @@ namespace Common {
class SaveFileManager;
class TimerManager;
}
namespace GUI {
class Debugger;
class Dialog;
}
/**
* Initializes graphics and shows error message.
*/
void GUIErrorMessage(const Common::String msg);
class Engine {
public:
@ -51,6 +60,9 @@ protected:
Common::EventManager *_eventMan;
Common::SaveFileManager *_saveFileMan;
GUI::Dialog *_mainMenuDialog;
virtual int runDialog(GUI::Dialog &dialog);
const Common::String _targetName; // target name for saves
const Common::FSNode _gameDataDir; // FIXME: Get rid of this
@ -120,6 +132,17 @@ public:
*/
virtual Common::Error run() = 0;
/**
* Prepare an error string, which is printed by the error() function.
*/
virtual void errorString(const char *buf_input, char *buf_output, int buf_output_size);
/**
* Return the engine's debugger instance, if any. Used by error() to
* invoke the debugger when a severe error is reported.
*/
virtual GUI::Debugger *getDebugger() { return 0; }
/**
* Determine whether the engine supports the specified feature.
*/
@ -207,6 +230,12 @@ public:
* Return whether the engine is currently paused or not.
*/
bool isPaused() const { return _pauseLevel != 0; }
/**
* Run the Global Main Menu Dialog
*/
void openMainMenuDialog();
inline Common::TimerManager *getTimerManager() { return _timer; }
inline Common::EventManager *getEventManager() { return _eventMan; }
inline Common::SaveFileManager *getSaveFileManager() { return _saveFileMan; }

View File

@ -25,6 +25,7 @@
#include "engines/game.h"
#include "base/plugins.h"
#include "graphics/surface.h"
const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list) {
@ -103,6 +104,13 @@ void GameDescriptor::updateDesc(const char *extra) {
}
}
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
if (_thumbnail.get() == t)
return;
_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter());
}
bool SaveStateDescriptor::getBool(const Common::String &key) const {
if (contains(key)) {
Common::String value = getVal(key);

View File

@ -31,6 +31,9 @@
#include "common/hash-str.h"
#include "common/ptr.h"
namespace Graphics {
struct Surface;
}
/**
* A simple structure used to map gameids (like "monkey", "sword1", ...) to
@ -119,21 +122,22 @@ public:
*/
class SaveStateDescriptor : public Common::StringMap {
protected:
Common::SharedPtr<Graphics::Surface> _thumbnail; // can be 0
public:
SaveStateDescriptor() {
SaveStateDescriptor() : _thumbnail() {
setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
setVal("description", "");
}
SaveStateDescriptor(int s, const Common::String &d) {
SaveStateDescriptor(int s, const Common::String &d) : _thumbnail() {
char buf[16];
sprintf(buf, "%d", s);
setVal("save_slot", buf);
setVal("description", d);
}
SaveStateDescriptor(const Common::String &s, const Common::String &d) {
SaveStateDescriptor(const Common::String &s, const Common::String &d) : _thumbnail() {
setVal("save_slot", s);
setVal("description", d);
}
@ -173,6 +177,21 @@ public:
*/
void setWriteProtectedFlag(bool state);
/**
* Return a thumbnail graphics surface representing the savestate visually.
* This is usually a scaled down version of the game graphics. The size
* should be either 160x100 or 160x120 pixels, depending on the aspect
* ratio of the game. If another ratio is required, contact the core team.
*/
const Graphics::Surface *getThumbnail() const { return _thumbnail.get(); }
/**
* Set a thumbnail graphics surface representing the savestate visually.
* Ownership of the surface is transferred to the SaveStateDescriptor.
* Hence the caller must not delete the surface.
*/
void setThumbnail(Graphics::Surface *t);
/**
* Sets the 'save_date' key properly, based on the given values.
*/

View File

@ -239,8 +239,8 @@ GrimEngine::GrimEngine(OSystem *syst, int gameFlags) :
g_smush = NULL;
g_imuse = NULL;
_showFps = (tolower(g_registry->get("show_fps", "FALSE")[0]) == 't');
_softRenderer = (tolower(g_registry->get("soft_renderer", "FALSE")[0]) == 't');
_showFps = (tolower(g_registry->get("show_fps", "false")[0]) == 't');
_softRenderer = (tolower(g_registry->get("soft_renderer", "false")[0]) == 't');
_mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, 127);
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
@ -337,7 +337,7 @@ Common::Error GrimEngine::run() {
g_smush = new Smush();
g_imuse = new Imuse(20);
bool fullscreen = (tolower(g_registry->get("fullscreen", "FALSE")[0]) == 't');
bool fullscreen = (tolower(g_registry->get("fullscreen", "false")[0]) == 't');
if (!_softRenderer && !g_system->hasFeature(OSystem::kFeatureOpenGL))
error("gfx backend doesn't support hardware rendering");

View File

@ -904,9 +904,9 @@ static void SetHardwareState() {
// changing only in config setup (software/hardware rendering)
bool accel = getbool(1);
if (accel)
g_registry->set("soft_renderer", "FALSE");
g_registry->set("soft_renderer", "false");
else
g_registry->set("soft_renderer", "TRUE");
g_registry->set("soft_renderer", "true");
}
static void SetVideoDevices() {

View File

@ -58,7 +58,7 @@ Registry::Registry() : _dirty(true) {
_lastSet = ConfMan.get("last_set");
_musicVolume = ConfMan.get("music_volume");
_sfxVolume = ConfMan.get("sfx_volume");
_voiceVolume = ConfMan.get("voice_volume");
_voiceVolume = ConfMan.get("speech_volume");
_lastSavedGame = ConfMan.get("last_saved_game");
_gamma = ConfMan.get("gamma");
_voiceEffects = ConfMan.get("voice_effects");
@ -191,10 +191,10 @@ void Registry::save() {
ConfMan.set("last_set", _lastSet);
ConfMan.set("music_volume", _musicVolume);
ConfMan.set("sfx_volume", _sfxVolume);
ConfMan.set("voice_volume", _voiceVolume);
ConfMan.set("speech_volume", _voiceVolume);
ConfMan.set("last_saved_game", _lastSavedGame);
ConfMan.set("gamma", _gamma);
ConfMan.set("voice_effects", _voiceEffects);
ConfMan.set("speech_effects", _voiceEffects);
ConfMan.set("text_speed", _textSpeed);
ConfMan.set("speech_mode", _speechMode);
ConfMan.set("movement", _movement);

View File

@ -8,12 +8,12 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

View File

@ -2,6 +2,7 @@ MODULE := engines
MODULE_OBJS := \
advancedDetector.o \
dialogs.o \
engine.o \
game.o

149
graphics/VectorRenderer.cpp Normal file
View File

@ -0,0 +1,149 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "common/util.h"
#include "common/system.h"
#include "common/events.h"
#include "graphics/surface.h"
#include "graphics/colormasks.h"
#include "gui/ThemeEngine.h"
#include "graphics/VectorRenderer.h"
#define VECTOR_RENDERER_FAST_TRIANGLES
namespace Graphics {
/********************************************************************
* DRAWSTEP handling functions
********************************************************************/
void VectorRenderer::drawStep(const Common::Rect &area, const DrawStep &step, uint32 extra) {
if (step.bgColor.set)
setBgColor(step.bgColor.r, step.bgColor.g, step.bgColor.b);
if (step.fgColor.set)
setFgColor(step.fgColor.r, step.fgColor.g, step.fgColor.b);
if (step.bevelColor.set)
setBevelColor(step.bevelColor.r, step.bevelColor.g, step.bevelColor.b);
if (step.gradColor1.set && step.gradColor2.set)
setGradientColors(step.gradColor1.r, step.gradColor1.g, step.gradColor1.b,
step.gradColor2.r, step.gradColor2.g, step.gradColor2.b);
setShadowOffset(_disableShadows ? 0 : step.shadow);
setBevel(step.bevel);
setGradientFactor(step.factor);
setStrokeWidth(step.stroke);
setFillMode((FillMode)step.fillMode);
_dynamicData = extra;
(this->*(step.drawingCall))(area, step);
}
int VectorRenderer::stepGetRadius(const DrawStep &step, const Common::Rect &area) {
int radius = 0;
if (step.radius == 0xFF)
radius = MIN(area.width(), area.height()) / 2;
else
radius = step.radius;
if (step.scale != (1 << 16) && step.scale != 0)
radius = (radius * step.scale) >> 16;
return radius;
}
void VectorRenderer::stepGetPositions(const DrawStep &step, const Common::Rect &area, uint16 &in_x, uint16 &in_y, uint16 &in_w, uint16 &in_h) {
if (!step.autoWidth) {
in_w = step.w == -1 ? area.height() : step.w;
switch(step.xAlign) {
case Graphics::DrawStep::kVectorAlignManual:
if (step.x >= 0) in_x = area.left + step.x;
else in_x = area.left + area.width() + step.x; // value relative to the opposite corner.
break;
case Graphics::DrawStep::kVectorAlignCenter:
in_x = area.left + (area.width() / 2) - (in_w / 2);
break;
case Graphics::DrawStep::kVectorAlignLeft:
in_x = area.left;
break;
case Graphics::DrawStep::kVectorAlignRight:
in_x = area.left + area.width() - in_w;
break;
default:
error("Vertical alignment in horizontal data.");
}
} else {
in_x = area.left;
in_w = area.width();
}
if (!step.autoHeight) {
in_h = step.h == -1 ? area.width() : step.h;
switch(step.yAlign) {
case Graphics::DrawStep::kVectorAlignManual:
if (step.y >= 0) in_y = area.top + step.y;
else in_y = area.top + area.height() + step.y; // relative
break;
case Graphics::DrawStep::kVectorAlignCenter:
in_y = area.top + (area.height() / 2) - (in_h / 2);
break;
case Graphics::DrawStep::kVectorAlignTop:
in_y = area.top;
break;
case Graphics::DrawStep::kVectorAlignBottom:
in_y = area.top + area.height() - in_h;
break;
default:
error("Horizontal alignment in vertical data.");
}
} else {
in_y = area.top;
in_h = area.height();
}
if (step.scale != (1 << 16) && step.scale != 0) {
in_x = (in_x * step.scale) >> 16;
in_y = (in_y * step.scale) >> 16;
in_w = (in_w * step.scale) >> 16;
in_h = (in_h * step.scale) >> 16;
}
}
} // end of namespace Graphics

491
graphics/VectorRenderer.h Normal file
View File

@ -0,0 +1,491 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef VECTOR_RENDERER_H
#define VECTOR_RENDERER_H
#include "common/sys.h"
#include "common/system.h"
#include "graphics/surface.h"
#include "graphics/pixelformat.h"
#include "gui/ThemeEngine.h"
namespace Graphics {
class VectorRenderer;
struct DrawStep {
struct Color {
uint8 r, g, b;
bool set;
};
Color fgColor; /**< Foreground color */
Color bgColor; /**< background color */
Color gradColor1; /**< gradient start*/
Color gradColor2; /**< gradient end */
Color bevelColor;
bool autoWidth, autoHeight;
int16 x, y, w, h; /**< width, height and position, if not measured automatically.
negative values mean counting from the opposite direction */
enum VectorAlignment {
kVectorAlignManual,
kVectorAlignLeft,
kVectorAlignRight,
kVectorAlignBottom,
kVectorAlignTop,
kVectorAlignCenter
} xAlign, yAlign;
uint8 shadow, stroke, factor, radius, bevel; /**< Misc options... */
uint8 fillMode; /**< active fill mode */
uint32 extraData; /**< Generic parameter for extra options (orientation/bevel) */
uint32 scale; /**< scale of all the coordinates in FIXED POINT with 16 bits mantissa */
void (VectorRenderer::*drawingCall)(const Common::Rect &, const DrawStep &); /** Pointer to drawing function */
Graphics::Surface *blitSrc;
};
VectorRenderer *createRenderer(int mode);
/**
* VectorRenderer: The core Vector Renderer Class
*
* This virtual class exposes the API with all the vectorial
* rendering functions that may be used to draw on a given Surface.
*
* This class must be instantiated as one of its children, which implement
* the actual rendering functionality for each Byte Depth / Byte Format
* combination, and may also contain platform specific code.
*
* When specifying define DISABLE_FANCY_THEMES eye candy related code
* gets stripped off. This is especially useful for small devices like NDS.
*
* TODO: Expand documentation.
*
* @see VectorRendererSpec
* @see VectorRendererAA
*/
class VectorRenderer {
public:
VectorRenderer() : _activeSurface(NULL), _fillMode(kFillDisabled), _shadowOffset(0),
_disableShadows(false), _strokeWidth(1), _gradientFactor(1) {
}
virtual ~VectorRenderer() {}
/** Specifies the way in which a shape is filled */
enum FillMode {
kFillDisabled = 0,
kFillForeground = 1,
kFillBackground = 2,
kFillGradient = 3
};
enum TriangleOrientation {
kTriangleAuto = 0,
kTriangleUp,
kTriangleDown,
kTriangleLeft,
kTriangleRight
};
/**
* Draws a line by considering the special cases for optimization.
*
* @param x1 Horizontal (X) coordinate for the line start
* @param x2 Horizontal (X) coordinate for the line end
* @param y1 Vertical (Y) coordinate for the line start
* @param y2 Vertical (Y) coordinate for the line end
*/
virtual void drawLine(int x1, int y1, int x2, int y2) = 0;
/**
* Draws a circle centered at (x,y) with radius r.
*
* @param x Horizontal (X) coordinate for the center of the circle
* @param y Vertical (Y) coordinate for the center of the circle
* @param r Radius of the circle.
*/
virtual void drawCircle(int x, int y, int r) = 0;
/**
* Draws a square starting at (x,y) with the given width and height.
*
* @param x Horizontal (X) coordinate for the center of the square
* @param y Vertical (Y) coordinate for the center of the square
* @param w Width of the square.
* @param h Height of the square
*/
virtual void drawSquare(int x, int y, int w, int h) = 0;
/**
* Draws a rounded square starting at (x,y) with the given width and height.
* The corners of the square are rounded with the given radius.
*
* @param x Horizontal (X) coordinate for the center of the square
* @param y Vertical (Y) coordinate for the center of the square
* @param w Width of the square.
* @param h Height of the square
* @param r Radius of the corners.
*/
virtual void drawRoundedSquare(int x, int y, int r, int w, int h) = 0;
/**
* Draws a triangle starting at (x,y) with the given base and height.
* The triangle will always be isosceles, with the given base and height.
* The orientation parameter controls the position of the base of the triangle.
*
* @param x Horizontal (X) coordinate for the top left corner of the triangle
* @param y Vertical (Y) coordinate for the top left corner of the triangle
* @param base Width of the base of the triangle
* @param h Height of the triangle
* @param orient Orientation of the triangle.
*/
virtual void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient) = 0;
/**
* Draws a beveled square like the ones in the Classic GUI themes.
* Beveled squares are always drawn with a transparent background. Draw them on top
* of a standard square to fill it.
*
* @param x Horizontal (X) coordinate for the center of the square
* @param y Vertical (Y) coordinate for the center of the square
* @param w Width of the square.
* @param h Height of the square
* @param bevel Amount of bevel. Must be positive.
*/
virtual void drawBeveledSquare(int x, int y, int w, int h, int bevel) = 0;
/**
* Draws a tab-like shape, specially thought for the Tab widget.
* If a radius is given, the tab will have rounded corners. Otherwise,
* the tab will be squared.
*
* @param x Horizontal (X) coordinate for the tab
* @param y Vertical (Y) coordinate for the tab
* @param w Width of the tab
* @param h Height of the tab
* @param r Radius of the corners of the tab (0 for squared tabs).
*/
virtual void drawTab(int x, int y, int r, int w, int h) = 0;
/**
* Simple helper function to draw a cross.
*/
virtual void drawCross(int x, int y, int w, int h) {
drawLine(x, y, x + w, y + w);
drawLine(x + w, y, x, y + h);
}
/**
* Set the active foreground painting color for the renderer.
* All the foreground drawing from then on will be done with that color, unless
* specified otherwise.
*
* Foreground drawing means all outlines and basic shapes.
*
* @param r value of the red color byte
* @param g value of the green color byte
* @param b value of the blue color byte
*/
virtual void setFgColor(uint8 r, uint8 g, uint8 b) = 0;
/**
* Set the active background painting color for the renderer.
* All the background drawing from then on will be done with that color, unless
* specified otherwise.
*
* Background drawing means all the shape filling.
*
* @param r value of the red color byte
* @param g value of the green color byte
* @param b value of the blue color byte
*/
virtual void setBgColor(uint8 r, uint8 g, uint8 b) = 0;
virtual void setBevelColor(uint8 r, uint8 g, uint8 b) = 0;
/**
* Set the active gradient color. All shapes drawn using kFillGradient
* as their fill mode will use this VERTICAL gradient as their fill color.
*
* @param r1 value of the red color byte for the start color
* @param g1 value of the green color byte for the start color
* @param b1 value of the blue color byte for the start color
* @param r2 value of the red color byte for the end color
* @param g2 value of the green color byte for the end color
* @param b2 value of the blue color byte for the end color
*/
virtual void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2) = 0;
/**
* Sets the active drawing surface. All drawing from this
* point on will be done on that surface.
*
* @param surface Pointer to a Surface object.
*/
virtual void setSurface(Surface *surface) {
_activeSurface = surface;
}
/**
* Fills the active surface with the specified fg/bg color or the active gradient.
* Defaults to using the active Foreground color for filling.
*
* @param mode Fill mode (bg, fg or gradient) used to fill the surface
*/
virtual void fillSurface() = 0;
/**
* Clears the active surface.
*/
virtual void clearSurface() {
byte *src = (byte *)_activeSurface->pixels;
memset(src, 0, _activeSurface->pitch * _activeSurface->h);
}
/**
* Sets the active fill mode for all shapes.
*
* @see VectorRenderer::FillMode
* @param mode Specified fill mode.
*/
virtual void setFillMode(FillMode mode) {
_fillMode = mode;
}
/**
* Sets the stroke width. All shapes drawn with a stroke will
* have that width. Pass 0 to disable shape stroking.
*
* @param width Width of the stroke in pixels.
*/
virtual void setStrokeWidth(int width) {
_strokeWidth = width;
}
/**
* Enables adding shadows to all drawn primitives.
* Shadows are drawn automatically under the shapes. The given offset
* controls their intensity and size (the higher the offset, the
* bigger the shadows). If the offset is 0, no shadows are drawn.
*
* @param offset Shadow offset.
*/
virtual void setShadowOffset(int offset) {
if (offset >= 0)
_shadowOffset = offset;
}
virtual void setBevel(int amount) {
if (amount >= 0)
_bevel = amount;
}
/**
* Sets the multiplication factor of the active gradient.
*
* @see _gradientFactor
* @param factor Multiplication factor.
*/
virtual void setGradientFactor(int factor) {
if (factor > 0)
_gradientFactor = factor;
}
/**
* Translates the position data inside a DrawStep into actual
* screen drawing positions.
*/
void stepGetPositions(const DrawStep &step, const Common::Rect &area, uint16 &in_x, uint16 &in_y, uint16 &in_w, uint16 &in_h);
/**
* Translates the radius data inside a drawstep into the real radius
* for the shape. Used for automatic radius calculations.
*/
int stepGetRadius(const DrawStep &step, const Common::Rect &area);
/**
* DrawStep callback functions for each drawing feature
*/
void drawCallback_CIRCLE(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h, radius;
radius = stepGetRadius(step, area);
stepGetPositions(step, area, x, y, w, h);
drawCircle(x + radius, y + radius, radius);
}
void drawCallback_SQUARE(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawSquare(x, y, w, h);
}
void drawCallback_LINE(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawLine(x, y, x + w, y + w);
}
void drawCallback_ROUNDSQ(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawRoundedSquare(x, y, stepGetRadius(step, area), w, h);
}
void drawCallback_FILLSURFACE(const Common::Rect &area, const DrawStep &step) {
fillSurface();
}
void drawCallback_TRIANGLE(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawTriangle(x, y, w, h, (TriangleOrientation)step.extraData);
}
void drawCallback_BEVELSQ(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawBeveledSquare(x, y, w, h, _bevel);
}
void drawCallback_TAB(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawTab(x, y, stepGetRadius(step, area), w, h);
}
void drawCallback_BITMAP(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
blitAlphaBitmap(step.blitSrc, Common::Rect(x, y, x + w, y + h));
}
void drawCallback_CROSS(const Common::Rect &area, const DrawStep &step) {
uint16 x, y, w, h;
stepGetPositions(step, area, x, y, w, h);
drawCross(x, y, w, h);
}
void drawCallback_VOID(const Common::Rect &area, const DrawStep &step) {}
/**
* Draws the specified draw step on the screen.
*
* @see DrawStep
* @param area Zone to paint on
* @param step Pointer to a DrawStep struct.
*/
virtual void drawStep(const Common::Rect &area, const DrawStep &step, uint32 extra = 0);
/**
* Copies the part of the current frame to the system overlay.
*
* @param sys Pointer to the global System class
* @param r Zone of the surface to copy into the overlay.
*/
virtual void copyFrame(OSystem *sys, const Common::Rect &r) = 0;
/**
* Copies the current surface to the system overlay
*
* @param sys Pointer to the global System class
*/
virtual void copyWholeFrame(OSystem *sys) = 0;
/**
* Blits a given graphics surface on top of the current drawing surface.
*
* Note that the source surface and the active
* surface are expected to be of the same size, hence the area delimited
* by "r" in the source surface will be blitted into the area delimited by
* "r" on the current surface.
*
* If you wish to blit a smaller surface into the active drawing area, use
* VectorRenderer::blitSubSurface().
*
* @param source Surface to blit into the drawing surface.
* @param r Position in the active drawing surface to do the blitting.
*/
virtual void blitSurface(const Graphics::Surface *source, const Common::Rect &r) = 0;
/**
* Blits a given graphics surface into a small area of the current drawing surface.
*
* Note that the given surface is expected to be smaller than the
* active drawing surface, hence the WHOLE source surface will be
* blitted into the active surface, at the position specified by "r".
*/
virtual void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r) = 0;
virtual void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r) = 0;
/**
* Draws a string into the screen. Wrapper for the Graphics::Font string drawing
* method.
*/
virtual void drawString(const Graphics::Font *font, const Common::String &text,
const Common::Rect &area, Graphics::TextAlign alignH,
GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool useEllipsis) = 0;
/**
* Allows to temporarily enable/disable all shadows drawing.
* i.e. for performance issues, blitting, etc
*/
virtual void disableShadows() { _disableShadows = true; }
virtual void enableShadows() { _disableShadows = false; }
/**
* Applies a whole-screen shading effect, used before opening a new dialog.
* Currently supports screen dimmings and luminance (b&w).
*/
virtual void applyScreenShading(GUI::ThemeEngine::ShadingStyle) = 0;
protected:
Surface *_activeSurface; /**< Pointer to the surface currently being drawn */
FillMode _fillMode; /**< Defines in which way (if any) are filled the drawn shapes */
int _shadowOffset; /**< offset for drawn shadows */
int _bevel; /**< amount of fake bevel */
bool _disableShadows; /**< Disables temporarily shadow drawing for overlayed images. */
int _strokeWidth; /**< Width of the stroke of all drawn shapes */
uint32 _dynamicData; /**< Dynamic data from the GUI Theme that modifies the drawing of the current shape */
int _gradientFactor; /**< Multiplication factor of the active gradient */
int _gradientBytes[3]; /**< Color bytes of the active gradient, used to speed up calculation */
};
} // end of namespace Graphics
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,279 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef VECTOR_RENDERER_SPEC_H
#define VECTOR_RENDERER_SPEC_H
#include "graphics/VectorRenderer.h"
namespace Graphics {
/**
* VectorRendererSpec: Specialized Vector Renderer Class
*
* This templated class implements the basic subset of vector operations for
* all platforms by allowing the user to provide the actual Pixel Type and
* pixel information structs.
*
* This class takes two template parameters:
*
* @param PixelType Defines a type which may hold the color value of a single
* pixel, such as "byte" or "uint16" for 8 and 16 BPP respectively.
*
* TODO: Expand documentation.
*
* @see VectorRenderer
*/
template<typename PixelType>
class VectorRendererSpec : public VectorRenderer {
typedef VectorRenderer Base;
public:
VectorRendererSpec(PixelFormat format);
void drawLine(int x1, int y1, int x2, int y2);
void drawCircle(int x, int y, int r);
void drawSquare(int x, int y, int w, int h);
void drawRoundedSquare(int x, int y, int r, int w, int h);
void drawTriangle(int x, int y, int base, int height, TriangleOrientation orient);
void drawTab(int x, int y, int r, int w, int h);
void drawBeveledSquare(int x, int y, int w, int h, int bevel) {
drawBevelSquareAlg(x, y, w, h, bevel, _bevelColor, _fgColor, Base::_fillMode != kFillDisabled);
}
void drawString(const Graphics::Font *font, const Common::String &text,
const Common::Rect &area, Graphics::TextAlign alignH,
GUI::ThemeEngine::TextAlignVertical alignV, int deltax, bool elipsis);
void setFgColor(uint8 r, uint8 g, uint8 b) { _fgColor = _format.RGBToColor(r, g, b); }
void setBgColor(uint8 r, uint8 g, uint8 b) { _bgColor = _format.RGBToColor(r, g, b); }
void setBevelColor(uint8 r, uint8 g, uint8 b) { _bevelColor = _format.RGBToColor(r, g, b); }
void setGradientColors(uint8 r1, uint8 g1, uint8 b1, uint8 r2, uint8 g2, uint8 b2);
void copyFrame(OSystem *sys, const Common::Rect &r);
void copyWholeFrame(OSystem *sys) { copyFrame(sys, Common::Rect(0, 0, _activeSurface->w, _activeSurface->h)); }
void fillSurface();
void blitSurface(const Graphics::Surface *source, const Common::Rect &r);
void blitSubSurface(const Graphics::Surface *source, const Common::Rect &r);
void blitAlphaBitmap(const Graphics::Surface *source, const Common::Rect &r);
void applyScreenShading(GUI::ThemeEngine::ShadingStyle shadingStyle);
protected:
/**
* Draws a single pixel on the surface with the given coordinates and
* the given color.
*
* @param x Horizontal coordinate of the pixel.
* @param y Vertical coordinate of the pixel.
* @param color Color of the pixel
*/
inline void putPixel(int x, int y, PixelType color) {
PixelType *ptr = (PixelType *)_activeSurface->getBasePtr(x, y);
*ptr = color;
}
/**
* Blends a single pixel on the surface with the given coordinates, color
* and Alpha intensity.
*
* @param x Horizontal coordinate of the pixel.
* @param y Vertical coordinate of the pixel.
* @param color Color of the pixel
* @param alpha Alpha intensity of the pixel (0-255)
*/
inline void blendPixel(int x, int y, PixelType color, uint8 alpha) {
blendPixelPtr((PixelType*)Base::_activeSurface->getBasePtr(x, y), color, alpha);
}
/**
* Blends a single pixel on the surface in the given pixel pointer, using supplied color
* and Alpha intensity.
*
* This is implemented to prevent blendPixel() to calculate the surface pointer on each call.
* Optimized drawing algorithms should call this function when possible.
*
* @see blendPixel
* @param ptr Pointer to the pixel to blend on top of
* @param color Color of the pixel
* @param alpha Alpha intensity of the pixel (0-255)
*/
inline void blendPixelPtr(PixelType *ptr, PixelType color, uint8 alpha);
/**
* PRIMITIVE DRAWING ALGORITHMS
*
* Generic algorithms for drawing all kinds of aliased primitive shapes.
* These may be overloaded in inheriting classes to implement platform-specific
* optimizations or improve looks.
*
* @see VectorRendererAA
* @see VectorRendererAA::drawLineAlg
* @see VectorRendererAA::drawCircleAlg
*/
virtual void drawLineAlg(int x1, int y1, int x2, int y2,
int dx, int dy, PixelType color);
virtual void drawCircleAlg(int x, int y, int r,
PixelType color, FillMode fill_m);
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h,
PixelType color, FillMode fill_m);
virtual void drawSquareAlg(int x, int y, int w, int h,
PixelType color, FillMode fill_m);
virtual void drawTriangleVertAlg(int x, int y, int w, int h,
bool inverted, PixelType color, FillMode fill_m);
virtual void drawTriangleFast(int x, int y, int size,
bool inverted, PixelType color, FillMode fill_m);
virtual void drawBevelSquareAlg(int x, int y, int w, int h,
int bevel, PixelType top_color, PixelType bottom_color, bool fill);
virtual void drawTabAlg(int x, int y, int w, int h, int r,
PixelType color, VectorRenderer::FillMode fill_m,
int baseLeft = 0, int baseRight = 0);
virtual void drawBevelTabAlg(int x, int y, int w, int h,
int bevel, PixelType topColor, PixelType bottomColor,
int baseLeft = 0, int baseRight = 0);
/**
* SHADOW DRAWING ALGORITHMS
*
* Optimized versions of the primitive drawing algorithms with alpha blending
* for shadow drawing.
* There functions may be overloaded in inheriting classes to improve performance
* in the slowest platforms where pixel alpha blending just doesn't cut it.
*
* @param blur Intensity/size of the shadow.
*/
virtual void drawSquareShadow(int x, int y, int w, int h, int blur);
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur);
virtual void drawRoundedSquareFakeBevel(int x, int y, int r, int w, int h, int amount);
/**
* Calculates the color gradient on a given point.
* This function assumes that the gradient start/end colors have been set
* beforehand from the API function call.
*
* @param pos Progress of the gradient.
* @param max Maximum amount of the progress.
* @return Composite color of the gradient at the given "progress" amount.
*/
inline PixelType calcGradient(uint32 pos, uint32 max);
/**
* Fills several pixels in a row with a given color and the specified alpha blending.
*
* @see blendPixelPtr
* @see blendPixel
* @param first Pointer to the first pixel to fill.
* @param last Pointer to the last pixel to fill.
* @param color Color of the pixel
* @param alpha Alpha intensity of the pixel (0-255)
*/
inline void blendFill(PixelType *first, PixelType *last, PixelType color, uint8 alpha) {
while (first != last) blendPixelPtr(first++, color, alpha);
}
const PixelFormat _format;
const PixelType _redMask, _greenMask, _blueMask, _alphaMask;
PixelType _fgColor; /**< Foreground color currently being used to draw on the renderer */
PixelType _bgColor; /**< Background color currently being used to draw on the renderer */
PixelType _gradientStart; /**< Start color for the fill gradient */
PixelType _gradientEnd; /**< End color for the fill gradient */
PixelType _bevelColor;
PixelType _bitmapAlphaColor;
};
#ifndef DISABLE_FANCY_THEMES
/**
* VectorRendererAA: Anti-Aliased Vector Renderer Class
*
* This templated class inherits all the functionality of the VectorRendererSpec
* class but uses better looking yet slightly slower AA algorithms for drawing
* most primitives. May be used in faster platforms.
*
* TODO: Expand documentation.
*
* @see VectorRenderer
* @see VectorRendererSpec
*/
template<typename PixelType>
class VectorRendererAA : public VectorRendererSpec<PixelType> {
typedef VectorRendererSpec<PixelType> Base;
public:
VectorRendererAA(PixelFormat format) : VectorRendererSpec<PixelType>(format) {
}
protected:
/**
* "Wu's Line Antialiasing Algorithm" as published by Xiaolin Wu, July 1991
* Based on the implementation found in Michael Abrash's Graphics Programming Black Book.
*
* Generic line drawing algorithm for the Antialiased renderer. Optimized with no
* floating point operations, assumes no special cases.
*
* @see VectorRenderer::drawLineAlg()
*/
virtual void drawLineAlg(int x1, int y1, int x2, int y2, int dx, int dy, PixelType color);
/**
* "Wu's Circle Antialiasing Algorithm" as published by Xiaolin Wu, July 1991
* Based on the theoretical concept of the algorithm.
*
* Implementation of Wu's algorithm for circles using fixed point arithmetics.
* Could be quite fast.
*
* @see VectorRenderer::drawCircleAlg()
*/
virtual void drawCircleAlg(int x, int y, int r, PixelType color, VectorRenderer::FillMode fill_m);
/**
* "Wu's Circle Antialiasing Algorithm" as published by Xiaolin Wu, July 1991,
* modified with corner displacement to allow drawing of squares with rounded
* corners.
*
* @see VectorRenderer::drawRoundedAlg()
*/
virtual void drawRoundedSquareAlg(int x1, int y1, int r, int w, int h, PixelType color, VectorRenderer::FillMode fill_m);
virtual void drawRoundedSquareShadow(int x, int y, int r, int w, int h, int blur) {
Base::drawRoundedSquareShadow(x, y, r, w, h, blur);
// VectorRenderer::applyConvolutionMatrix(VectorRenderer::kConvolutionHardBlur,
// Common::Rect(x, y, x + w + blur * 2, y + h + blur * 2));
}
};
#endif
}
#endif

View File

@ -8,19 +8,18 @@
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#ifndef GRAPHICS_COLORMASKS_H

145
graphics/cursorman.cpp Normal file
View File

@ -0,0 +1,145 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "graphics/cursorman.h"
#include "common/system.h"
#include "common/stack.h"
DECLARE_SINGLETON(Graphics::CursorManager);
namespace Graphics {
static bool g_initialized = false;
CursorManager::CursorManager() {
if (!g_initialized) {
g_initialized = true;
_cursorStack.clear();
_cursorPaletteStack.clear();
}
}
bool CursorManager::isVisible() {
if (_cursorStack.empty())
return false;
return _cursorStack.top()->_visible;
}
bool CursorManager::showMouse(bool visible) {
if (_cursorStack.empty())
return false;
_cursorStack.top()->_visible = visible;
// Should work, even if there's just a dummy cursor on the stack.
return g_system->showMouse(visible);
}
void CursorManager::pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) {
Cursor *cur = new Cursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale);
cur->_visible = isVisible();
_cursorStack.push(cur);
if (buf) {
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
}
}
void CursorManager::popCursor() {
if (_cursorStack.empty())
return;
Cursor *cur = _cursorStack.pop();
delete cur;
if (!_cursorStack.empty()) {
cur = _cursorStack.top();
g_system->setMouseCursor(cur->_data, cur->_width, cur->_height, cur->_hotspotX, cur->_hotspotY, cur->_keycolor, cur->_targetScale);
}
g_system->showMouse(isVisible());
}
void CursorManager::popAllCursors() {
while (!_cursorStack.empty()) {
Cursor *cur = _cursorStack.pop();
delete cur;
}
g_system->showMouse(isVisible());
}
void CursorManager::replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int targetScale) {
if (_cursorStack.empty()) {
pushCursor(buf, w, h, hotspotX, hotspotY, keycolor, targetScale);
return;
}
Cursor *cur = _cursorStack.top();
uint size = w * h;
if (cur->_size < size) {
delete[] cur->_data;
cur->_data = new byte[size];
cur->_size = size;
}
if (buf && cur->_data)
memcpy(cur->_data, buf, size);
cur->_width = w;
cur->_height = h;
cur->_hotspotX = hotspotX;
cur->_hotspotY = hotspotY;
cur->_keycolor = keycolor;
cur->_targetScale = targetScale;
g_system->setMouseCursor(cur->_data, w, h, hotspotX, hotspotY, keycolor, targetScale);
}
bool CursorManager::supportsCursorPalettes() {
return false;
}
void CursorManager::disableCursorPalette(bool disable) {
return;
}
void CursorManager::pushCursorPalette(const byte *colors, uint start, uint num) {
return;
}
void CursorManager::popCursorPalette() {
return;
}
void CursorManager::replaceCursorPalette(const byte *colors, uint start, uint num) {
return;
}
} // End of namespace Graphics

214
graphics/cursorman.h Normal file
View File

@ -0,0 +1,214 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef GRAPHICS_CURSORMAN_H
#define GRAPHICS_CURSORMAN_H
#include "common/sys.h"
#include "common/stack.h"
#include "common/singleton.h"
namespace Graphics {
class CursorManager : public Common::Singleton<CursorManager> {
public:
/** Query whether the mouse cursor is visible. */
bool isVisible();
/** Show or hide the mouse cursor. */
bool showMouse(bool visible);
/**
* Push a new cursor onto the stack, and set it in the backend. A local
* copy will be made of the cursor data, so the original buffer can be
* safely freed afterwards.
*
* @param buf the new cursor data
* @param w the width
* @param h the height
* @param hotspotX the hotspot X coordinate
* @param hotspotY the hotspot Y coordinate
* @param keycolor the index for the transparent color
* @param targetScale the scale for which the cursor is designed
*
* @note It is ok for the buffer to be a NULL pointer. It is sometimes
* useful to push a "dummy" cursor and modify it later. The
* cursor will be added to the stack, but not to the backend.
*/
void pushCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1);
/**
* Pop a cursor from the stack, and restore the previous one to the
* backend. If there is no previous cursor, the cursor is hidden.
*/
void popCursor();
/**
* Replace the current cursor on the stack. If the stack is empty, the
* cursor is pushed instead. It's a slightly more optimized way of
* popping the old cursor before pushing the new one.
*
* @param buf the new cursor data
* @param w the width
* @param h the height
* @param hotspotX the hotspot X coordinate
* @param hotspotY the hotspot Y coordinate
* @param keycolor the index for the transparent color
* @param targetScale the scale for which the cursor is designed
*/
void replaceCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1);
/**
* Pop all of the cursors and cursor palettes from their respective stacks.
* The purpose is to ensure that all unecessary cursors are removed from the
* stack when returning to the launcher from an engine.
*
*/
void popAllCursors();
/**
* Test whether cursor palettes are supported.
*
* This is just an convenience wrapper for checking for
* OSystem::kFeatureCursorHasPalette to be supported by OSystem.
*
* @see OSystem::kFeatureCursorHasPalette
* @see OSystem::hasFeature
*/
bool supportsCursorPalettes();
/**
* Enable/Disable the current cursor palette.
*
* @param disable
*/
void disableCursorPalette(bool disable);
/**
* Push a new cursor palette onto the stack, and set it in the backend.
* The palette entries from 'start' till (start+num-1) will be replaced
* so a full palette updated is accomplished via start=0, num=256.
*
* The palette data is specified in the same interleaved RGBA format as
* used by all backends.
*
* @param colors the new palette data, in interleaved RGB format
* @param start the first palette entry to be updated
* @param num the number of palette entries to be updated
*
* @note If num is zero, the cursor palette is disabled.
*/
void pushCursorPalette(const byte *colors, uint start, uint num);
/**
* Pop a cursor palette from the stack, and restore the previous one to
* the backend. If there is no previous palette, the cursor palette is
* disabled instead.
*/
void popCursorPalette();
/**
* Replace the current cursor palette on the stack. If the stack is
* empty, the palette is pushed instead. It's a slightly more optimized
* way of popping the old palette before pushing the new one.
*
* @param colors the new palette data, in interleaved RGB format
* @param start the first palette entry to be updated
* @param num the number of palette entries to be updated
*
* @note If num is zero, the cursor palette is disabled.
*/
void replaceCursorPalette(const byte *colors, uint start, uint num);
private:
friend class Common::Singleton<SingletonBaseType>;
CursorManager();
struct Cursor {
byte *_data;
bool _visible;
uint _width;
uint _height;
int _hotspotX;
int _hotspotY;
byte _keycolor;
byte _targetScale;
uint _size;
Cursor(const byte *data, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int targetScale = 1) {
_size = w * h;
_data = new byte[_size];
if (data && _data)
memcpy(_data, data, _size);
_width = w;
_height = h;
_hotspotX = hotspotX;
_hotspotY = hotspotY;
_keycolor = keycolor;
_targetScale = targetScale;
}
~Cursor() {
delete[] _data;
}
};
struct Palette {
byte *_data;
uint _start;
uint _num;
uint _size;
bool _disabled;
Palette(const byte *colors, uint start, uint num) {
_start = start;
_num = num;
_size = 4 * num;
if (num) {
_data = new byte[_size];
memcpy(_data, colors, _size);
} else {
_data = NULL;
}
_disabled = false;
}
~Palette() {
delete[] _data;
}
};
Common::Stack<Cursor *> _cursorStack;
Common::Stack<Palette *> _cursorPaletteStack;
};
} // End of namespace Graphics
#define CursorMan (::Graphics::CursorManager::instance())
#endif

940
graphics/font.cpp Normal file
View File

@ -0,0 +1,940 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "common/stream.h"
#include "common/file.h"
#include "common/endian.h"
#include "graphics/font.h"
namespace Graphics {
void free_font(NewFontData* pf);
NewFont::~NewFont() {
if (font) {
free_font(font);
}
}
int NewFont::getCharWidth(byte chr) const {
// If no width table is specified, return the maximum width
if (!desc.width)
return desc.maxwidth;
// If this character is not included in the font, use the default char.
if (chr < desc.firstchar || desc.firstchar + desc.size < chr) {
chr = desc.defaultchar;
}
return desc.width[chr - desc.firstchar];
}
template <typename PixelType>
void drawCharIntern(byte *ptr, uint pitch, const bitmap_t *src, int h, int minX, int maxX, const PixelType color) {
const bitmap_t maxXMask = ~((1 << (16-maxX)) - 1);
while (h-- > 0) {
bitmap_t buffer = READ_UINT16(src);
src++;
buffer &= maxXMask;
buffer <<= minX;
PixelType *tmp = (PixelType *)ptr;
while (buffer != 0) {
if ((buffer & 0x8000) != 0)
*tmp = color;
tmp++;
buffer <<= 1;
}
ptr += pitch;
}
}
void NewFont::drawChar(Surface *dst, byte chr, const int tx, const int ty, const uint32 color) const {
assert(dst != 0);
assert(desc.bits != 0 && desc.maxwidth <= 16);
assert(dst->bytesPerPixel == 1 || dst->bytesPerPixel == 2);
// If this character is not included in the font, use the default char.
if (chr < desc.firstchar || chr >= desc.firstchar + desc.size) {
chr = desc.defaultchar;
}
chr -= desc.firstchar;
int bbw, bbh, bbx, bby;
// Get the bounding box of the character
if (!desc.bbx) {
bbw = desc.fbbw;
bbh = desc.fbbh;
bbx = desc.fbbx;
bby = desc.fbby;
} else {
bbw = desc.bbx[chr].w;
bbh = desc.bbx[chr].h;
bbx = desc.bbx[chr].x;
bby = desc.bbx[chr].y;
}
byte *ptr = (byte *)dst->getBasePtr(tx + bbx, ty + desc.ascent - bby - bbh);
const bitmap_t *tmp = desc.bits + (desc.offset ? desc.offset[chr] : (chr * desc.fbbh));
int y = MIN(bbh, ty + desc.ascent - bby);
tmp += bbh - y;
y -= MAX(0, ty + desc.ascent - bby - dst->h);
if (dst->bytesPerPixel == 1)
drawCharIntern<byte>(ptr, dst->pitch, tmp, y, MAX(0, -(tx + bbx)), MIN(bbw, dst->w - tx - bbx), color);
else if (dst->bytesPerPixel == 2)
drawCharIntern<uint16>(ptr, dst->pitch, tmp, y, MAX(0, -(tx + bbx)), MIN(bbw, dst->w - tx - bbx), color);
}
#pragma mark -
/* BEGIN font.h*/
/* bitmap_t helper macros*/
#define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
/* builtin C-based proportional/fixed font structure */
/* based on The Microwindows Project http://microwindows.org */
struct NewFontData {
char * name; /* font name*/
int maxwidth; /* max width in pixels*/
int height; /* height in pixels*/
int ascent; /* ascent (baseline) height*/
int firstchar; /* first character in bitmap*/
int size; /* font size in glyphs*/
bitmap_t* bits; /* 16-bit right-padded bitmap data*/
unsigned long* offset; /* offsets into bitmap data*/
unsigned char* width; /* character widths or NULL if fixed*/
BBX* bbx; /* character bounding box or NULL if fixed */
int defaultchar; /* default char (not glyph index)*/
long bits_size; /* # words of bitmap_t bits*/
/* unused by runtime system, read in by convbdf*/
char * facename; /* facename of font*/
char * copyright; /* copyright info for loadable fonts*/
int pixel_size;
int descent;
int fbbw, fbbh, fbbx, fbby;
};
/* END font.h*/
#define isprefix(buf,str) (!strncmp(buf, str, strlen(str)))
#define strequal(s1,s2) (!strcmp(s1, s2))
#define EXTRA 300
int start_char = 0;
int limit_char = 255;
NewFontData* bdf_read_font(Common::SeekableReadStream &fp);
int bdf_read_header(Common::SeekableReadStream &fp, NewFontData* pf);
int bdf_read_bitmaps(Common::SeekableReadStream &fp, NewFontData* pf);
char * bdf_getline(Common::SeekableReadStream &fp, char *buf, int len);
bitmap_t bdf_hexval(unsigned char *buf);
void free_font(NewFontData* pf) {
if (!pf)
return;
free(pf->name);
free(pf->facename);
free(pf->bits);
free(pf->offset);
free(pf->width);
free(pf->bbx);
free(pf);
}
/* build incore structure from .bdf file*/
NewFontData* bdf_read_font(Common::SeekableReadStream &fp) {
NewFontData* pf;
uint32 pos = fp.pos();
pf = (NewFontData*)calloc(1, sizeof(NewFontData));
if (!pf)
goto errout;
if (!bdf_read_header(fp, pf)) {
warning("Error reading font header");
goto errout;
}
fp.seek(pos, SEEK_SET);
if (!bdf_read_bitmaps(fp, pf)) {
warning("Error reading font bitmaps");
goto errout;
}
return pf;
errout:
free_font(pf);
return NULL;
}
/* read bdf font header information, return 0 on error*/
int bdf_read_header(Common::SeekableReadStream &fp, NewFontData* pf) {
int encoding = 0;
int nchars = 0, maxwidth, maxheight;
int firstchar = 65535;
int lastchar = -1;
char buf[256];
char facename[256];
char copyright[256];
/* set certain values to errors for later error checking*/
pf->defaultchar = -1;
pf->ascent = -1;
pf->descent = -1;
for (;;) {
if (!bdf_getline(fp, buf, sizeof(buf))) {
warning("Error: EOF on file");
return 0;
}
if (isprefix(buf, "FONT ")) { /* not required*/
if (sscanf(buf, "FONT %[^\n]", facename) != 1) {
warning("Error: bad 'FONT'");
return 0;
}
pf->facename = strdup(facename);
continue;
}
if (isprefix(buf, "COPYRIGHT ")) { /* not required*/
if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) {
warning("Error: bad 'COPYRIGHT'");
return 0;
}
pf->copyright = strdup(copyright);
continue;
}
if (isprefix(buf, "DEFAULT_CHAR ")) { /* not required*/
if (sscanf(buf, "DEFAULT_CHAR %d", &pf->defaultchar) != 1) {
warning("Error: bad 'DEFAULT_CHAR'");
return 0;
}
}
if (isprefix(buf, "FONT_DESCENT ")) {
if (sscanf(buf, "FONT_DESCENT %d", &pf->descent) != 1) {
warning("Error: bad 'FONT_DESCENT'");
return 0;
}
continue;
}
if (isprefix(buf, "FONT_ASCENT ")) {
if (sscanf(buf, "FONT_ASCENT %d", &pf->ascent) != 1) {
warning("Error: bad 'FONT_ASCENT'");
return 0;
}
continue;
}
if (isprefix(buf, "FONTBOUNDINGBOX ")) {
if (sscanf(buf, "FONTBOUNDINGBOX %d %d %d %d",
&pf->fbbw, &pf->fbbh, &pf->fbbx, &pf->fbby) != 4) {
warning("Error: bad 'FONTBOUNDINGBOX'");
return 0;
}
continue;
}
if (isprefix(buf, "CHARS ")) {
if (sscanf(buf, "CHARS %d", &nchars) != 1) {
warning("Error: bad 'CHARS'");
return 0;
}
continue;
}
/*
* Reading ENCODING is necessary to get firstchar/lastchar
* which is needed to pre-calculate our offset and widths
* array sizes.
*/
if (isprefix(buf, "ENCODING ")) {
if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
warning("Error: bad 'ENCODING'");
return 0;
}
if (encoding >= 0 &&
encoding <= limit_char &&
encoding >= start_char) {
if (firstchar > encoding)
firstchar = encoding;
if (lastchar < encoding)
lastchar = encoding;
}
continue;
}
if (strequal(buf, "ENDFONT"))
break;
}
/* calc font height*/
if (pf->ascent < 0 || pf->descent < 0 || firstchar < 0) {
warning("Error: Invalid BDF file, requires FONT_ASCENT/FONT_DESCENT/ENCODING");
return 0;
}
pf->height = pf->ascent + pf->descent;
/* calc default char*/
if (pf->defaultchar < 0 ||
pf->defaultchar < firstchar ||
pf->defaultchar > limit_char )
pf->defaultchar = firstchar;
/* calc font size (offset/width entries)*/
pf->firstchar = firstchar;
pf->size = lastchar - firstchar + 1;
/* use the font boundingbox to get initial maxwidth*/
/*maxwidth = pf->fbbw - pf->fbbx;*/
maxwidth = pf->fbbw;
maxheight = pf->fbbh;
/* initially use font bounding box for bits allocation*/
pf->bits_size = nchars * BITMAP_WORDS(maxwidth) * maxheight;
/* allocate bits, offset, and width arrays*/
pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
pf->offset = (unsigned long *)malloc(pf->size * sizeof(unsigned long));
pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
pf->bbx = (BBX *)malloc(pf->size * sizeof(BBX));
if (!pf->bits || !pf->offset || !pf->width) {
warning("Error: no memory for font load");
return 0;
}
return 1;
}
/* read bdf font bitmaps, return 0 on error*/
int bdf_read_bitmaps(Common::SeekableReadStream &fp, NewFontData* pf) {
long ofs = 0;
int maxwidth = 0;
int i, k, encoding = 0, width = 0;
int bbw = 0, bbh = 0, bbx = 0, bby = 0;
int proportional = 0;
int need_bbx = 0;
int encodetable = 0;
long l;
char buf[256];
/* initially mark offsets as not used*/
for (i = 0; i < pf->size; ++i)
pf->offset[i] = (unsigned long)-1;
for (;;) {
if (!bdf_getline(fp, buf, sizeof(buf))) {
warning("Error: EOF on file");
return 0;
}
if (isprefix(buf, "STARTCHAR")) {
encoding = width = bbw = bbh = bbx = bby = -1;
continue;
}
if (isprefix(buf, "ENCODING ")) {
if (sscanf(buf, "ENCODING %d", &encoding) != 1) {
warning("Error: bad 'ENCODING'");
return 0;
}
if (encoding < start_char || encoding > limit_char)
encoding = -1;
continue;
}
if (isprefix(buf, "DWIDTH ")) {
if (sscanf(buf, "DWIDTH %d", &width) != 1) {
warning("Error: bad 'DWIDTH'");
return 0;
}
/* use font boundingbox width if DWIDTH <= 0*/
if (width <= 0)
width = pf->fbbw - pf->fbbx;
continue;
}
if (isprefix(buf, "BBX ")) {
if (sscanf(buf, "BBX %d %d %d %d", &bbw, &bbh, &bbx, &bby) != 4) {
warning("Error: bad 'BBX'");
return 0;
}
continue;
}
if (strequal(buf, "BITMAP")) {
bitmap_t *ch_bitmap = pf->bits + ofs;
int ch_words;
if (encoding < 0)
continue;
/* set bits offset in encode map*/
if (pf->offset[encoding-pf->firstchar] != (unsigned long)-1) {
warning("Error: duplicate encoding for character %d (0x%02x), ignoring duplicate",
encoding, encoding);
continue;
}
pf->offset[encoding-pf->firstchar] = ofs;
pf->width[encoding-pf->firstchar] = width;
pf->bbx[encoding-pf->firstchar].w = bbw;
pf->bbx[encoding-pf->firstchar].h = bbh;
pf->bbx[encoding-pf->firstchar].x = bbx;
pf->bbx[encoding-pf->firstchar].y = bby;
if (width > maxwidth)
maxwidth = width;
/* clear bitmap*/
memset(ch_bitmap, 0, BITMAP_BYTES(bbw) * bbh);
ch_words = BITMAP_WORDS(bbw);
/* read bitmaps*/
for (i = 0; i < bbh; ++i) {
if (!bdf_getline(fp, buf, sizeof(buf))) {
warning("Error: EOF reading BITMAP data");
return 0;
}
if (isprefix(buf, "ENDCHAR"))
break;
for (k = 0; k < ch_words; ++k) {
bitmap_t value;
value = bdf_hexval((unsigned char *)buf);
if (bbw > 8) {
WRITE_UINT16(ch_bitmap, value);
} else {
WRITE_UINT16(ch_bitmap, value << 8);
}
ch_bitmap++;
}
}
ofs += ch_words * bbh;
continue;
}
if (strequal(buf, "ENDFONT"))
break;
}
/* set max width*/
pf->maxwidth = maxwidth;
/* change unused offset/width values to default char values*/
for (i = 0; i < pf->size; ++i) {
int defchar = pf->defaultchar - pf->firstchar;
if (pf->offset[i] == (unsigned long)-1) {
pf->offset[i] = pf->offset[defchar];
pf->width[i] = pf->width[defchar];
pf->bbx[i].w = pf->bbx[defchar].w;
pf->bbx[i].h = pf->bbx[defchar].h;
pf->bbx[i].x = pf->bbx[defchar].x;
pf->bbx[i].y = pf->bbx[defchar].y;
}
}
/* determine whether font doesn't require encode table*/
l = 0;
for (i = 0; i < pf->size; ++i) {
if (pf->offset[i] != (unsigned long)l) {
encodetable = 1;
break;
}
l += BITMAP_WORDS(pf->bbx[i].w) * pf->bbx[i].h;
}
if (!encodetable) {
free(pf->offset);
pf->offset = NULL;
}
/* determine whether font is fixed-width*/
for (i = 0; i < pf->size; ++i) {
if (pf->width[i] != maxwidth) {
proportional = 1;
break;
}
}
if (!proportional) {
free(pf->width);
pf->width = NULL;
}
/* determine if the font needs a bbx table */
for (i = 0; i < pf->size; ++i) {
if (pf->bbx[i].w != pf->fbbw || pf->bbx[i].h != pf->fbbh || pf->bbx[i].x != pf->fbbx || pf->bbx[i].y != pf->fbby) {
need_bbx = 1;
break;
}
}
if (!need_bbx) {
free(pf->bbx);
pf->bbx = NULL;
}
/* reallocate bits array to actual bits used*/
if (ofs < pf->bits_size) {
pf->bits = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t));
pf->bits_size = ofs;
}
else {
if (ofs > pf->bits_size) {
warning("Warning: DWIDTH spec > max FONTBOUNDINGBOX");
if (ofs > pf->bits_size+EXTRA) {
warning("Error: Not enough bits initially allocated");
return 0;
}
pf->bits_size = ofs;
}
}
return 1;
}
/* read the next non-comment line, returns buf or NULL if EOF*/
// TODO: Can we use SeekableReadStream::readLine resp. readLine_NEW instead?
char *bdf_getline(Common::SeekableReadStream &fp, char *buf, int len) {
int c;
char *b;
for (;;) {
b = buf;
while (!fp.eos()) {
c = fp.readByte();
if (c == '\r')
continue;
if (c == '\n')
break;
if (b - buf >= (len - 1))
break;
*b++ = c;
}
*b = '\0';
if (fp.eos() && b == buf)
return NULL;
if (b != buf && !isprefix(buf, "COMMENT"))
break;
}
return buf;
}
/* return hex value of buffer */
bitmap_t bdf_hexval(unsigned char *buf) {
bitmap_t val = 0;
for (unsigned char *ptr = buf; *ptr; ptr++) {
int c = *ptr;
if (c >= '0' && c <= '9')
c -= '0';
else if (c >= 'A' && c <= 'F')
c = c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
c = c - 'a' + 10;
else
c = 0;
val = (val << 4) | c;
}
return val;
}
NewFont *NewFont::loadFont(Common::SeekableReadStream &stream) {
NewFontData *data = bdf_read_font(stream);
if (!data)
return 0;
FontDesc desc;
desc.name = data->name;
desc.maxwidth = data->maxwidth;
desc.height = data->height;
desc.fbbw = data->fbbw;
desc.fbbh = data->fbbh;
desc.fbbx = data->fbbx;
desc.fbby = data->fbby;
desc.ascent = data->ascent;
desc.firstchar = data->firstchar;
desc.size = data->size;
desc.bits = data->bits;
desc.offset = data->offset;
desc.width = data->width;
desc.bbx = data->bbx;
desc.defaultchar = data->defaultchar;
desc.bits_size = data->bits_size;
return new NewFont(desc, data);
}
bool NewFont::cacheFontData(const NewFont &font, const Common::String &filename) {
Common::DumpFile cacheFile;
if (!cacheFile.open(filename)) {
warning("Couldn't open file '%s' for writing", filename.c_str());
return false;
}
cacheFile.writeUint16BE(font.desc.maxwidth);
cacheFile.writeUint16BE(font.desc.height);
cacheFile.writeUint16BE(font.desc.fbbw);
cacheFile.writeUint16BE(font.desc.fbbh);
cacheFile.writeUint16BE(font.desc.fbbx);
cacheFile.writeUint16BE(font.desc.fbby);
cacheFile.writeUint16BE(font.desc.ascent);
cacheFile.writeUint16BE(font.desc.firstchar);
cacheFile.writeUint16BE(font.desc.size);
cacheFile.writeUint16BE(font.desc.defaultchar);
cacheFile.writeUint32BE(font.desc.bits_size);
for (long i = 0; i < font.desc.bits_size; ++i) {
cacheFile.writeUint16BE(font.desc.bits[i]);
}
if (font.desc.offset) {
cacheFile.writeByte(1);
for (int i = 0; i < font.desc.size; ++i) {
cacheFile.writeUint32BE(font.desc.offset[i]);
}
} else {
cacheFile.writeByte(0);
}
if (font.desc.width) {
cacheFile.writeByte(1);
for (int i = 0; i < font.desc.size; ++i) {
cacheFile.writeByte(font.desc.width[i]);
}
} else {
cacheFile.writeByte(0);
}
if (font.desc.bbx) {
cacheFile.writeByte(1);
for (int i = 0; i < font.desc.size; ++i) {
cacheFile.writeByte(font.desc.bbx[i].w);
cacheFile.writeByte(font.desc.bbx[i].h);
cacheFile.writeByte(font.desc.bbx[i].x);
cacheFile.writeByte(font.desc.bbx[i].y);
}
} else {
cacheFile.writeByte(0);
}
return !cacheFile.err();
}
NewFont *NewFont::loadFromCache(Common::SeekableReadStream &stream) {
NewFont *font = 0;
NewFontData *data = (NewFontData *)malloc(sizeof(NewFontData));
if (!data)
return 0;
memset(data, 0, sizeof(NewFontData));
data->maxwidth = stream.readUint16BE();
data->height = stream.readUint16BE();
data->fbbw = stream.readUint16BE();
data->fbbh = stream.readUint16BE();
data->fbbx = stream.readUint16BE();
data->fbby = stream.readUint16BE();
data->ascent = stream.readUint16BE();
data->firstchar = stream.readUint16BE();
data->size = stream.readUint16BE();
data->defaultchar = stream.readUint16BE();
data->bits_size = stream.readUint32BE();
data->bits = (bitmap_t*)malloc(sizeof(bitmap_t)*data->bits_size);
if (!data->bits) {
free(data);
return 0;
}
for (long i = 0; i < data->bits_size; ++i) {
data->bits[i] = stream.readUint16BE();
}
bool hasOffsetTable = (stream.readByte() != 0);
if (hasOffsetTable) {
data->offset = (unsigned long*)malloc(sizeof(unsigned long)*data->size);
if (!data->offset) {
free(data->bits);
free(data);
return 0;
}
for (int i = 0; i < data->size; ++i) {
data->offset[i] = stream.readUint32BE();
}
}
bool hasWidthTable = (stream.readByte() != 0);
if (hasWidthTable) {
data->width = (unsigned char*)malloc(sizeof(unsigned char)*data->size);
if (!data->width) {
free(data->bits);
free(data->offset);
free(data);
return 0;
}
for (int i = 0; i < data->size; ++i) {
data->width[i] = stream.readByte();
}
}
bool hasBBXTable = (stream.readByte() != 0);
if (hasBBXTable) {
data->bbx = (BBX *)malloc(sizeof(BBX)*data->size);
if (!data->bbx) {
free(data->bits);
free(data->offset);
free(data->width);
free(data);
return 0;
}
for (int i = 0; i < data->size; ++i) {
data->bbx[i].w = (int8)stream.readByte();
data->bbx[i].h = (int8)stream.readByte();
data->bbx[i].x = (int8)stream.readByte();
data->bbx[i].y = (int8)stream.readByte();
}
}
FontDesc desc;
desc.name = data->name;
desc.maxwidth = data->maxwidth;
desc.height = data->height;
desc.fbbw = data->fbbw;
desc.fbbh = data->fbbh;
desc.fbbx = data->fbbx;
desc.fbby = data->fbby;
desc.ascent = data->ascent;
desc.firstchar = data->firstchar;
desc.size = data->size;
desc.bits = data->bits;
desc.offset = data->offset;
desc.width = data->width;
desc.bbx = data->bbx;
desc.defaultchar = data->defaultchar;
desc.bits_size = data->bits_size;
font = new NewFont(desc, data);
if (!font || stream.ioFailed()) {
free(data->bits);
free(data->offset);
free(data->width);
free(data);
return 0;
}
return font;
}
#pragma mark -
int Font::getStringWidth(const Common::String &str) const {
int space = 0;
for (uint i = 0; i < str.size(); ++i)
space += getCharWidth(str[i]);
return space;
}
void Font::drawString(Surface *dst, const Common::String &s, int x, int y, int w, uint32 color, TextAlign align, int deltax, bool useEllipsis) const {
assert(dst != 0);
const int leftX = x, rightX = x + w;
uint i;
int width = getStringWidth(s);
Common::String str;
if (useEllipsis && width > w) {
// String is too wide. So we shorten it "intellegently", 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.
const int ellipsisWidth = getStringWidth("...");
// 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) {
int charWidth = getCharWidth(s[i]);
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) {
skip -= getCharWidth(s[i]);
}
// Append the remaining chars, if any
for (; i < s.size(); ++i) {
str += s[i];
}
width = getStringWidth(str);
} else {
str = s;
}
if (align == kTextAlignCenter)
x = x + (w - width)/2;
else if (align == kTextAlignRight)
x = x + w - width;
x += deltax;
for (i = 0; i < str.size(); ++i) {
w = getCharWidth(str[i]);
if (x+w > rightX)
break;
if (x >= leftX)
drawChar(dst, str[i], x, y, color);
x += w;
}
}
struct WordWrapper {
Common::StringList &lines;
int actualMaxLineWidth;
WordWrapper(Common::StringList &l) : lines(l), actualMaxLineWidth(0) {
}
void add(Common::String &line, int &w) {
if (actualMaxLineWidth < w)
actualMaxLineWidth = w;
lines.push_back(line);
line.clear();
w = 0;
}
};
int Font::wordWrapText(const Common::String &str, int maxWidth, Common::StringList &lines) const {
WordWrapper wrapper(lines);
Common::String line;
Common::String tmpStr;
int lineWidth = 0;
int tmpWidth = 0;
// The rough idea behind this algorithm is as follows:
// We accumulate characters into the string tmpStr. Whenever a full word
// has been gathered together this way, we 'commit' it to the line buffer
// 'line', i.e. we add tmpStr to the end of line, then clear it. Before
// we do that, we check whether it would cause 'line' to exceed maxWidth;
// in that case, we first add line to lines, then reset it.
//
// If a newline character is read, then we also add line to lines and clear it.
//
// Special care has to be taken to account for 'words' that exceed the width
// of a line. If we encounter such a word, we have to wrap it over multiple
// lines.
for (Common::String::const_iterator x = str.begin(); x != str.end(); ++x) {
const byte c = *x;
const int w = getCharWidth(c);
const bool wouldExceedWidth = (lineWidth + tmpWidth + w > maxWidth);
// If this char is a whitespace, then it represents a potential
// 'wrap point' where wrapping could take place. Everything that
// came before it can now safely be added to the line, as we know
// that it will not have to be wrapped.
if (isspace(c)) {
line += tmpStr;
lineWidth += tmpWidth;
tmpStr.clear();
tmpWidth = 0;
// If we encounter a line break (\n), or if the new space would
// cause the line to overflow: start a new line
if (c == '\n' || wouldExceedWidth) {
wrapper.add(line, lineWidth);
continue;
}
}
// If the max line width would be exceeded by adding this char,
// insert a line break.
if (wouldExceedWidth) {
// Commit what we have so far, *if* we have anything.
// If line is empty, then we are looking at a word
// which exceeds the maximum line width.
if (lineWidth > 0) {
wrapper.add(line, lineWidth);
// Trim left side
while (tmpStr.size() && isspace(tmpStr[0])) {
tmpWidth -= getCharWidth(tmpStr[0]);
tmpStr.deleteChar(0);
}
} else {
wrapper.add(tmpStr, tmpWidth);
}
}
tmpWidth += w;
tmpStr += c;
}
// If some text is left over, add it as the final line
line += tmpStr;
lineWidth += tmpWidth;
if (lineWidth > 0) {
wrapper.add(line, lineWidth);
}
return wrapper.actualMaxLineWidth;
}
} // End of namespace Graphics

157
graphics/font.h Normal file
View File

@ -0,0 +1,157 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef GRAPHICS_FONT_H
#define GRAPHICS_FONT_H
#include "common/str.h"
#include "graphics/surface.h"
namespace Common {
class SeekableReadStream;
}
namespace Graphics {
/** Text alignment modes */
enum TextAlign {
kTextAlignInvalid,
kTextAlignLeft, //!< Text should be aligned to the left
kTextAlignCenter, //!< Text should be centered
kTextAlignRight //!< Text should be aligned to the right
};
/**
* Instances of this class represent a distinct font, with a built-in renderer.
* @todo Maybe move the high-level methods (drawString etc.) to a separate
* FontRenderer class? That way, we could have different variants... ?
*/
class Font {
public:
Font() {}
virtual ~Font() {}
virtual int getFontHeight() const = 0;
virtual int getMaxCharWidth() const = 0;
virtual int getCharWidth(byte chr) const = 0;
virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const = 0;
void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const;
/**
* Compute and return the width the string str has when rendered using this font.
*/
int getStringWidth(const Common::String &str) const;
/**
* Take a text (which may contain newlines characters) and word wrap it so thata
* no text line is wider than maxWidth pixels. If necessary, additional line breaks
* are generated, preferably between words (i.e. were whitespaces are).
* The resulting lines are appended to the string list lines.
* It returns the maximal width of any of the new lines (i.e. a value which is less
* or equal to maxWidth).
*
* @param str the string to word wrap
* @param maxWidth the maximum width a line may have
* @param lines the string list to which the text lines from str are appended
* @return the maximal width of any of the lines added to lines
*/
int wordWrapText(const Common::String &str, int maxWidth, Common::StringList &lines) const;
};
class ScummFont : public Font {
public:
virtual int getFontHeight() const { return 8; }
virtual int getMaxCharWidth() const { return 8; }
virtual int getCharWidth(byte chr) const;
virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
};
typedef uint16 bitmap_t; /* bitmap image unit size*/
struct BBX {
int8 w;
int8 h;
int8 x;
int8 y;
};
/* builtin C-based proportional/fixed font structure */
/* based on The Microwindows Project http://microwindows.org */
struct FontDesc {
const char * name; /* font name*/
int maxwidth; /* max width in pixels*/
int height; /* height in pixels*/
int fbbw, fbbh, fbbx, fbby; /* max bounding box */
int ascent; /* ascent (baseline) height*/
int firstchar; /* first character in bitmap*/
int size; /* font size in glyphs*/
const bitmap_t* bits; /* 16-bit right-padded bitmap data*/
const unsigned long* offset; /* offsets into bitmap data*/
const unsigned char* width; /* character widths or NULL if fixed*/
const BBX* bbx; /* character bounding box or NULL if fixed */
int defaultchar; /* default char (not glyph index)*/
long bits_size; /* # words of bitmap_t bits*/
};
struct NewFontData;
class NewFont : public Font {
protected:
FontDesc desc;
NewFontData *font;
public:
NewFont(const FontDesc &d, NewFontData *font_ = 0) : desc(d), font(font_) {}
~NewFont();
virtual int getFontHeight() const { return desc.height; }
virtual int getMaxCharWidth() const { return desc.maxwidth; }
virtual int getCharWidth(byte chr) const;
virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const;
static NewFont *loadFont(Common::SeekableReadStream &stream);
static bool cacheFontData(const NewFont &font, const Common::String &filename);
static NewFont *loadFromCache(Common::SeekableReadStream &stream);
};
#if (defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
# define DEFINE_FONT(n) \
const NewFont *n; \
void create_##n() { \
n = new NewFont(desc); \
}
# define INIT_FONT(n) \
extern void create_##n(); \
create_##n();
#endif
} // End of namespace Graphics
#endif

96
graphics/fontman.cpp Normal file
View File

@ -0,0 +1,96 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "graphics/fontman.h"
//#include "gui/consolefont.h"
DECLARE_SINGLETON(Graphics::FontManager);
namespace Graphics {
#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
const ScummFont g_scummfont;
extern const NewFont g_sysfont;
extern const NewFont g_sysfont_big;
extern const NewFont g_consolefont;
FontManager::FontManager() {
}
#else
const ScummFont *g_scummfont;
extern const NewFont *g_sysfont;
extern const NewFont *g_sysfont_big;
extern const NewFont *g_consolefont;
static bool g_initialized = false;
void initfonts() {
if (!g_initialized) {
// FIXME : this need to be freed
g_initialized = true;
g_scummfont = new ScummFont;
INIT_FONT(g_sysfont)
INIT_FONT(g_sysfont_big)
INIT_FONT(g_consolefont)
}
}
FontManager::FontManager() {
initfonts();
}
#endif
const Font *FontManager::getFontByName(const Common::String &name) const {
if (!_fontMap.contains(name))
return 0;
return _fontMap[name];
}
const Font *FontManager::getFontByUsage(FontUsage usage) const {
switch (usage) {
#if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__))
case kOSDFont:
return &g_scummfont;
case kConsoleFont:
return &g_consolefont;
case kGUIFont:
return &g_sysfont;
case kBigGUIFont:
return &g_sysfont_big;
#else
case kOSDFont:
return g_scummfont;
case kConsoleFont:
return g_consolefont;
case kGUIFont:
return g_sysfont;
case kBigGUIFont:
return g_sysfont_big;
#endif
}
return 0;
}
} // End of namespace Graphics

96
graphics/fontman.h Normal file
View File

@ -0,0 +1,96 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#ifndef GRAPHICS_FONTMAN_H
#define GRAPHICS_FONTMAN_H
#include "common/sys.h"
#include "common/singleton.h"
#include "common/str.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
#include "graphics/font.h"
namespace Graphics {
class FontManager : public Common::Singleton<FontManager> {
public:
enum FontUsage {
kOSDFont,
kConsoleFont,
kGUIFont,
kBigGUIFont
};
/**
* Retrieve a font object based on its 'name'.
*
* @param name the name of the font to be retrieved.
* @return a pointer to a font, or 0 if no suitable font was found.
*/
const Font *getFontByName(const Common::String &name) const;
/**
* Associates a font object with an 'name'
*
* @param name the name of the font
* @param font the font object
* @return true on success, false on failure
*/
bool assignFontToName(const Common::String &name, const Font *font) { _fontMap[name] = font; return true; }
/**
* Removes binding from name to font
*
* @param name name which should be removed
*/
void removeFontName(const Common::String &name) { _fontMap.erase(name); }
/**
* Retrieve a font object based on what it is supposed
* to be used for
*
* @param usage a FontUsage enum value indicating what the font will be used for.
* @return a pointer to a font, or 0 if no suitable font was found.
*/
const Font *getFontByUsage(FontUsage usage) const;
//const Font *getFontBySize(int size???) const;
private:
friend class Common::Singleton<SingletonBaseType>;
FontManager();
Common::HashMap<Common::String, const Font *> _fontMap;
};
} // End of namespace Graphics
/** Shortcut for accessing the font manager. */
#define FontMan (Graphics::FontManager::instance())
#endif

File diff suppressed because it is too large Load Diff

7444
graphics/fonts/newfont.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,315 @@
/* Residual - A 3D game interpreter
*
* Residual is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the AUTHORS
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*/
#include "graphics/font.h"
namespace Graphics {
// Built-in font
static const byte guifont[] = {
// Header
0, 0, 99, 1, 226, 8,
// Character width table
4, 8, 6, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
8, 2, 1, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
4, 3, 7, 8, 7, 7, 8, 4, 5, 5, 8, 7, 4, 7, 3, 8,
7, 7, 7, 7, 8, 7, 7, 7, 7, 7, 3, 4, 7, 5, 7, 7,
8, 7, 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 8, 7, 7,
7, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 5, 8, 5, 8, 8,
7, 7, 7, 6, 7, 7, 7, 7, 7, 5, 6, 7, 5, 8, 7, 7,
7, 7, 7, 7, 7, 7, 7, 8, 7, 7, 7, 5, 3, 5, 7, 8,
7, 7, 7, 7, 7, 7, 0, 6, 7, 7, 7, 5, 5, 5, 7, 0,
6, 8, 8, 7, 7, 7, 7, 7, 0, 7, 7, 0, 0, 0, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 7,
// Character table
0, 0, 0, 0, 0, 0, 0, 0, // 0
1, 3, 6, 12, 24, 62, 3, 0, // 1
128, 192, 96, 48, 24, 124, 192, 0, // 2
0, 3, 62, 24, 12, 6, 3, 1, // 3
0, 192, 124, 24, 48, 96, 192, 128, // 4
0, 0, 0, 0, 0, 0, 0, 0, // 5
0, 0, 0, 0, 0, 0, 0, 0, // 6
0, 0, 0, 0, 0, 0, 0, 0, // 7
0, 0, 0, 0, 0, 0, 0, 0, // 8
0, 0, 0, 0, 0, 0, 0, 0, // 9
0, 0, 0, 0, 0, 0, 0, 0, // 10
0, 0, 0, 0, 0, 0, 0, 0, // 11
0, 0, 0, 0, 0, 0, 0, 0, // 12
0, 0, 0, 0, 0, 0, 0, 0, // 13
0, 0, 0, 0, 0, 0, 0, 0, // 14
0, 0, 0, 0, 0, 0, 0, 0, // 15
237, 74, 72, 0, 0, 0, 0, 0, // 16
128, 128, 128, 0, 0, 0, 0, 0, // 17
0, 0, 0, 0, 0, 0, 0, 0, // 18
60, 66, 153, 161, 161, 153, 66, 60, // 19
0, 0, 0, 0, 0, 0, 0, 0, // 20
0, 0, 0, 0, 0, 0, 0, 0, // 21
0, 0, 0, 0, 0, 0, 0, 0, // 22
0, 0, 0, 0, 0, 0, 0, 0, // 23
0, 0, 0, 0, 0, 0, 0, 0, // 24
0, 0, 0, 0, 0, 0, 0, 0, // 25
0, 0, 0, 0, 0, 0, 0, 0, // 26
0, 0, 0, 0, 0, 0, 0, 0, // 27
0, 0, 0, 0, 0, 0, 0, 0, // 28
0, 0, 0, 0, 0, 0, 0, 0, // 29
0, 0, 0, 0, 0, 0, 0, 0, // 30
0, 0, 0, 0, 0, 0, 0, 0, // 31
0, 0, 0, 0, 0, 0, 0, 0, // 32
96, 96, 96, 96, 0, 0, 96, 0, // 33
102, 102, 102, 0, 0, 0, 0, 0, // 34
102, 102, 255, 102, 255, 102, 102, 0, // 35
24, 62, 96, 60, 6, 124, 24, 0, // 36
98, 102, 12, 24, 48, 102, 70, 0, // 37
60, 102, 60, 56, 103, 102, 63, 0, // 38
96, 48, 16, 0, 0, 0, 0, 0, // 39
24, 48, 96, 96, 96, 48, 24, 0, // 40
96, 48, 24, 24, 24, 48, 96, 0, // 41
0, 102, 60, 255, 60, 102, 0, 0, // 42
0, 24, 24, 126, 24, 24, 0, 0, // 43
0, 0, 0, 0, 0, 48, 48, 96, // 44
0, 0, 0, 126, 0, 0, 0, 0, // 45
0, 0, 0, 0, 0, 96, 96, 0, // 46
0, 3, 6, 12, 24, 48, 96, 0, // 47
60, 102, 102, 102, 102, 102, 60, 0, // 48
24, 24, 56, 24, 24, 24, 126, 0, // 49
60, 102, 6, 12, 48, 96, 126, 0, // 50
60, 102, 6, 28, 6, 102, 60, 0, // 51
6, 14, 30, 102, 127, 6, 6, 0, // 52
126, 96, 124, 6, 6, 102, 60, 0, // 53
60, 102, 96, 124, 102, 102, 60, 0, // 54
126, 102, 12, 24, 24, 24, 24, 0, // 55
60, 102, 102, 60, 102, 102, 60, 0, // 56
60, 102, 102, 62, 6, 102, 60, 0, // 57
0, 0, 96, 0, 0, 96, 0, 0, // 58
0, 0, 48, 0, 0, 48, 48, 96, // 59
14, 24, 48, 96, 48, 24, 14, 0, // 60
0, 0, 120, 0, 120, 0, 0, 0, // 61
112, 24, 12, 6, 12, 24, 112, 0, // 62
60, 102, 6, 12, 24, 0, 24, 0, // 63
0, 0, 0, 255, 255, 0, 0, 0, // 64
24, 60, 102, 126, 102, 102, 102, 0, // 65
124, 102, 102, 124, 102, 102, 124, 0, // 66
60, 102, 96, 96, 96, 102, 60, 0, // 67
120, 108, 102, 102, 102, 108, 120, 0, // 68
126, 96, 96, 120, 96, 96, 126, 0, // 69
126, 96, 96, 120, 96, 96, 96, 0, // 70
60, 102, 96, 110, 102, 102, 60, 0, // 71
102, 102, 102, 126, 102, 102, 102, 0, // 72
120, 48, 48, 48, 48, 48, 120, 0, // 73
30, 12, 12, 12, 12, 108, 56, 0, // 74
102, 108, 120, 112, 120, 108, 102, 0, // 75
96, 96, 96, 96, 96, 96, 126, 0, // 76
99, 119, 127, 107, 99, 99, 99, 0, // 77
102, 118, 126, 126, 110, 102, 102, 0, // 78
60, 102, 102, 102, 102, 102, 60, 0, // 79
124, 102, 102, 124, 96, 96, 96, 0, // 80
60, 102, 102, 102, 102, 60, 14, 0, // 81
124, 102, 102, 124, 120, 108, 102, 0, // 82
60, 102, 96, 60, 6, 102, 60, 0, // 83
126, 24, 24, 24, 24, 24, 24, 0, // 84
102, 102, 102, 102, 102, 102, 60, 0, // 85
102, 102, 102, 102, 102, 60, 24, 0, // 86
99, 99, 99, 107, 127, 119, 99, 0, // 87
102, 102, 60, 24, 60, 102, 102, 0, // 88
102, 102, 102, 60, 24, 24, 24, 0, // 89
126, 6, 12, 24, 48, 96, 126, 0, // 90
120, 96, 96, 96, 96, 96, 120, 0, // 91
3, 6, 12, 24, 48, 96, 192, 0, // 92
120, 24, 24, 24, 24, 24, 120, 0, // 93
0, 0, 0, 0, 0, 219, 219, 0, // 94
0, 0, 0, 0, 0, 0, 0, 255, // 95
102, 102, 102, 0, 0, 0, 0, 0, // 96
0, 0, 60, 6, 62, 102, 62, 0, // 97
0, 96, 96, 124, 102, 102, 124, 0, // 98
0, 0, 60, 96, 96, 96, 60, 0, // 99
0, 6, 6, 62, 102, 102, 62, 0, // 100
0, 0, 60, 102, 126, 96, 60, 0, // 101
0, 14, 24, 62, 24, 24, 24, 0, // 102
0, 0, 62, 102, 102, 62, 6, 124, // 103
0, 96, 96, 124, 102, 102, 102, 0, // 104
0, 48, 0, 112, 48, 48, 120, 0, // 105
0, 12, 0, 12, 12, 12, 12, 120, // 106
0, 96, 96, 108, 120, 108, 102, 0, // 107
0, 112, 48, 48, 48, 48, 120, 0, // 108
0, 0, 102, 127, 127, 107, 99, 0, // 109
0, 0, 124, 102, 102, 102, 102, 0, // 110
0, 0, 60, 102, 102, 102, 60, 0, // 111
0, 0, 124, 102, 102, 124, 96, 96, // 112
0, 0, 62, 102, 102, 62, 6, 6, // 113
0, 0, 124, 102, 96, 96, 96, 0, // 114
0, 0, 62, 96, 60, 6, 124, 0, // 115
0, 24, 126, 24, 24, 24, 14, 0, // 116
0, 0, 102, 102, 102, 102, 62, 0, // 117
0, 0, 102, 102, 102, 60, 24, 0, // 118
0, 0, 99, 107, 127, 62, 54, 0, // 119
0, 0, 102, 60, 24, 60, 102, 0, // 120
0, 0, 102, 102, 102, 62, 12, 120, // 121
0, 0, 126, 12, 24, 48, 126, 0, // 122
24, 48, 48, 96, 48, 48, 24, 0, // 123
96, 96, 96, 0, 96, 96, 96, 0, // 124
96, 48, 48, 24, 48, 48, 96, 0, // 125
0, 0, 97, 153, 134, 0, 0, 0, // 126
8, 12, 14, 255, 255, 14, 12, 8, // 127
60, 102, 96, 96, 102, 60, 24, 56, // 128
102, 0, 102, 102, 102, 102, 62, 0, // 129
12, 24, 60, 102, 126, 96, 60, 0, // 130
24, 36, 60, 6, 62, 102, 62, 0, // 131
102, 0, 60, 6, 62, 102, 62, 0, // 132
48, 24, 60, 6, 62, 102, 62, 0, // 133
0, 0, 0, 0, 0, 0, 0, 0, // 134
0, 60, 96, 96, 96, 60, 24, 56, // 135
24, 36, 60, 102, 126, 96, 60, 0, // 136
102, 0, 60, 102, 126, 96, 60, 0, // 137
48, 24, 60, 102, 126, 96, 60, 0, // 138
0, 216, 0, 112, 48, 48, 120, 0, // 139
48, 72, 0, 112, 48, 48, 120, 0, // 140
96, 48, 0, 112, 48, 48, 120, 0, // 141
102, 24, 60, 102, 126, 102, 102, 0, // 142
0, 0, 0, 0, 0, 0, 0, 0, // 143
24, 48, 124, 96, 120, 96, 124, 0, // 144
0, 0, 108, 26, 126, 216, 110, 0, // 145
30, 40, 40, 126, 72, 136, 142, 0, // 146
24, 36, 60, 102, 102, 102, 60, 0, // 147
102, 0, 60, 102, 102, 102, 60, 0, // 148
48, 24, 60, 102, 102, 102, 60, 0, // 149
24, 36, 0, 102, 102, 102, 62, 0, // 150
48, 24, 102, 102, 102, 102, 62, 0, // 151
0, 0, 0, 0, 0, 0, 0, 0, // 152
102, 60, 102, 102, 102, 102, 60, 0, // 153
102, 0, 102, 102, 102, 102, 60, 0, // 154
0, 0, 0, 0, 0, 0, 0, 0, // 155
0, 0, 0, 0, 0, 0, 0, 0, // 156
0, 0, 0, 0, 0, 0, 0, 0, // 157
0, 0, 0, 0, 0, 0, 0, 0, // 158
0, 0, 0, 0, 0, 0, 0, 0, // 159
12, 24, 60, 6, 62, 102, 62, 0, // 160
0, 0, 0, 0, 0, 0, 0, 0, // 161
0, 0, 0, 0, 0, 0, 0, 0, // 162
0, 0, 0, 0, 0, 0, 0, 0, // 163
0, 0, 0, 0, 0, 0, 0, 0, // 164
0, 0, 0, 0, 0, 0, 0, 0, // 165
0, 0, 0, 0, 0, 0, 0, 0, // 166
0, 0, 0, 0, 0, 0, 0, 0, // 167
0, 0, 0, 0, 0, 0, 0, 0, // 168
0, 0, 0, 0, 0, 0, 0, 0, // 169
0, 0, 0, 0, 0, 0, 0, 0, // 170
0, 0, 0, 0, 0, 0, 0, 0, // 171
0, 0, 0, 0, 0, 0, 0, 0, // 172
0, 0, 0, 0, 0, 0, 0, 0, // 173
0, 0, 0, 0, 0, 0, 0, 0, // 174
0, 0, 0, 0, 0, 0, 0, 0, // 175
0, 0, 0, 0, 0, 0, 0, 0, // 176
0, 0, 0, 0, 0, 0, 0, 0, // 177
0, 0, 0, 0, 0, 0, 0, 0, // 178
0, 0, 0, 0, 0, 0, 0, 0, // 179
0, 0, 0, 0, 0, 0, 0, 0, // 180
0, 0, 0, 0, 0, 0, 0, 0, // 181
0, 0, 0, 0, 0, 0, 0, 0, // 182
0, 0, 0, 0, 0, 0, 0, 0, // 183
0, 0, 0, 0, 0, 0, 0, 0, // 184
0, 0, 0, 0, 0, 0, 0, 0, // 185
0, 0, 0, 0, 0, 0, 0, 0, // 186
0, 0, 0, 0, 0, 0, 0, 0, // 187
0, 0, 0, 0, 0, 0, 0, 0, // 188
0, 0, 0, 0, 0, 0, 0, 0, // 189
0, 0, 0, 0, 0, 0, 0, 0, // 190
0, 0, 0, 0, 0, 0, 0, 0, // 191
0, 0, 0, 0, 0, 0, 0, 0, // 192
0, 0, 0, 0, 0, 0, 0, 0, // 193
0, 0, 0, 0, 0, 0, 0, 0, // 194
0, 0, 0, 0, 0, 0, 0, 0, // 195
0, 0, 0, 0, 0, 0, 0, 0, // 196
0, 0, 0, 0, 0, 0, 0, 0, // 197
0, 0, 0, 0, 0, 0, 0, 0, // 198
0, 0, 0, 0, 0, 0, 0, 0, // 199
0, 0, 0, 0, 0, 0, 0, 0, // 200
0, 0, 0, 0, 0, 0, 0, 0, // 201
0, 0, 0, 0, 0, 0, 0, 0, // 202
0, 0, 0, 0, 0, 0, 0, 0, // 203
0, 0, 0, 0, 0, 0, 0, 0, // 204
0, 0, 0, 0, 0, 0, 0, 0, // 205
0, 0, 0, 0, 0, 0, 0, 0, // 206
0, 0, 0, 0, 0, 0, 0, 0, // 207
0, 0, 0, 0, 0, 0, 0, 0, // 208
0, 0, 0, 0, 0, 0, 0, 0, // 209
0, 0, 0, 0, 0, 0, 0, 0, // 210
0, 0, 0, 0, 0, 0, 0, 0, // 211
0, 0, 0, 0, 0, 0, 0, 0, // 212
0, 0, 0, 0, 0, 0, 0, 0, // 213
0, 0, 0, 0, 0, 0, 0, 0, // 214
0, 0, 0, 0, 0, 0, 0, 0, // 215
0, 0, 0, 0, 0, 0, 0, 0, // 216
0, 0, 0, 0, 0, 0, 0, 0, // 217
0, 0, 0, 0, 0, 0, 0, 0, // 218
0, 0, 0, 0, 0, 0, 0, 0, // 219
0, 0, 0, 0, 0, 0, 0, 0, // 220
0, 0, 0, 0, 0, 0, 0, 0, // 221
0, 0, 0, 0, 0, 0, 0, 0, // 222
0, 0, 0, 0, 0, 0, 0, 0, // 223
0, 0, 0, 0, 0, 0, 0, 0, // 224
28, 54, 54, 124, 102, 102, 124, 64, // 225
0, 0, 0 // ???
};
int ScummFont::getCharWidth(byte chr) const {
return guifont[chr+6];
}
void ScummFont::drawChar(Surface *dst, byte chr, int tx, int ty, uint32 color) const {
assert(dst != 0);
byte *ptr = (byte *)dst->getBasePtr(tx, ty);
const byte *tmp = guifont + 6 + guifont[4] + chr * 8;
uint buffer = 0;
uint mask = 0;
for (int y = 0; y < 8; y++) {
if (ty + y < 0 || ty + y >= dst->h)
continue;
for (int x = 0; x < 8; x++) {
if (tx + x < 0 || tx + x >= dst->w)
continue;
unsigned char c;
mask >>= 1;
if (mask == 0) {
buffer = *tmp++;
mask = 0x80;
}
c = ((buffer & mask) != 0);
if (c) {
if (dst->bytesPerPixel == 1)
ptr[x] = color;
else if (dst->bytesPerPixel == 2)
((uint16 *)ptr)[x] = color;
}
}
ptr += dst->pitch;
}
}
} // End of namespace Graphics

Some files were not shown because too many files have changed in this diff Show More