mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-02 06:41:51 +00:00
* initial works on GUI, launcher works, not external themes yet
* cleanup header files
This commit is contained in:
parent
aaa9ce687a
commit
26f97ed5a3
2
Makefile
2
Makefile
@ -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
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
233
backends/platform/sdl/hardwarekeys.cpp
Normal file
233
backends/platform/sdl/hardwarekeys.cpp
Normal 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
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
MODULE := backends/platform/sdl
|
||||
|
||||
MODULE_OBJS := \
|
||||
hardwarekeys.o \
|
||||
sdl_driver.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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__
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -1 +1,5 @@
|
||||
#define RESIDUAL_VERSION "@VERSION@"
|
||||
#ifndef RESIDUAL_SVN_REVISION
|
||||
#define RESIDUAL_SVN_REVISION
|
||||
#endif
|
||||
|
||||
#define RESIDUAL_VERSION "@VERSION@" RESIDUAL_SVN_REVISION
|
||||
|
180
base/main.cpp
180
base/main.cpp
@ -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;
|
||||
}
|
||||
|
@ -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$
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ALGORITHM_H
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_ARRAY_H
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_DEBUG_H
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/util.h"
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_FS_H
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_FUNC_H
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_HASH_STR_H
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_LIST_H
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_LIST_INTERN_H
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_MD5_H
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_PTR_H
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_QUEUE_H
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
126
common/stack.h
Normal 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
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/str.h"
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_STRING_H
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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; }
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
*
|
||||
* $URL$
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef COMMON_TIMER_H
|
||||
|
1456
common/unzip.cpp
Normal file
1456
common/unzip.cpp
Normal file
File diff suppressed because it is too large
Load Diff
72
common/unzip.h
Normal file
72
common/unzip.h
Normal 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 */
|
@ -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
412
common/xmlparser.cpp
Normal 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
453
common/xmlparser.h
Normal 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
32
configure
vendored
@ -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
|
||||
|
@ -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
327
engines/dialogs.cpp
Normal 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
75
engines/dialogs.h
Normal 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
|
@ -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());
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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");
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -2,6 +2,7 @@ MODULE := engines
|
||||
|
||||
MODULE_OBJS := \
|
||||
advancedDetector.o \
|
||||
dialogs.o \
|
||||
engine.o \
|
||||
game.o
|
||||
|
||||
|
149
graphics/VectorRenderer.cpp
Normal file
149
graphics/VectorRenderer.cpp
Normal 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
491
graphics/VectorRenderer.h
Normal 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
|
1619
graphics/VectorRendererSpec.cpp
Normal file
1619
graphics/VectorRendererSpec.cpp
Normal file
File diff suppressed because it is too large
Load Diff
279
graphics/VectorRendererSpec.h
Normal file
279
graphics/VectorRendererSpec.h
Normal 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
|
@ -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
145
graphics/cursorman.cpp
Normal 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
214
graphics/cursorman.h
Normal 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
940
graphics/font.cpp
Normal 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
157
graphics/font.h
Normal 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
96
graphics/fontman.cpp
Normal 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
96
graphics/fontman.h
Normal 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
|
5660
graphics/fonts/consolefont.cpp
Normal file
5660
graphics/fonts/consolefont.cpp
Normal file
File diff suppressed because it is too large
Load Diff
7444
graphics/fonts/newfont.cpp
Normal file
7444
graphics/fonts/newfont.cpp
Normal file
File diff suppressed because it is too large
Load Diff
5548
graphics/fonts/newfont_big.cpp
Normal file
5548
graphics/fonts/newfont_big.cpp
Normal file
File diff suppressed because it is too large
Load Diff
315
graphics/fonts/scummfont.cpp
Normal file
315
graphics/fonts/scummfont.cpp
Normal 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
Loading…
x
Reference in New Issue
Block a user