Merge remote-tracking branch 'origin/master' into soltys_wip2
This commit is contained in:
commit
66e81d633f
142 changed files with 3558 additions and 2509 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -28,6 +28,7 @@ lib*.a
|
||||||
/Icon.*
|
/Icon.*
|
||||||
|
|
||||||
/build
|
/build
|
||||||
|
/staging
|
||||||
|
|
||||||
/backends/platform/dc/gui
|
/backends/platform/dc/gui
|
||||||
/backends/platform/dc/graphics
|
/backends/platform/dc/graphics
|
||||||
|
|
12
AUTHORS
12
AUTHORS
|
@ -19,7 +19,7 @@ ScummVM Team
|
||||||
Jonathan Gray - (retired)
|
Jonathan Gray - (retired)
|
||||||
Vincent Hamm - (retired)
|
Vincent Hamm - (retired)
|
||||||
Max Horn - (retired)
|
Max Horn - (retired)
|
||||||
Travis Howell - (retired)
|
Travis Howell
|
||||||
Pawel Kolodziejski - Codecs, iMUSE, Smush, etc.
|
Pawel Kolodziejski - Codecs, iMUSE, Smush, etc.
|
||||||
Gregory Montoir
|
Gregory Montoir
|
||||||
Eugene Sandulenko - FT INSANE, MM NES, MM C64, game detection,
|
Eugene Sandulenko - FT INSANE, MM NES, MM C64, game detection,
|
||||||
|
@ -28,7 +28,7 @@ ScummVM Team
|
||||||
|
|
||||||
HE:
|
HE:
|
||||||
Jonathan Gray - (retired)
|
Jonathan Gray - (retired)
|
||||||
Travis Howell - (retired)
|
Travis Howell
|
||||||
Gregory Montoir
|
Gregory Montoir
|
||||||
Eugene Sandulenko
|
Eugene Sandulenko
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ ScummVM Team
|
||||||
Matthew Hoops
|
Matthew Hoops
|
||||||
Filippos Karapetis
|
Filippos Karapetis
|
||||||
Pawel Kolodziejski
|
Pawel Kolodziejski
|
||||||
Walter van Niftrik
|
Walter van Niftrik - (retired)
|
||||||
Kari Salminen
|
Kari Salminen
|
||||||
Eugene Sandulenko
|
Eugene Sandulenko
|
||||||
David Symonds - (retired)
|
David Symonds - (retired)
|
||||||
|
@ -45,7 +45,7 @@ ScummVM Team
|
||||||
AGOS:
|
AGOS:
|
||||||
Torbjorn Andersson
|
Torbjorn Andersson
|
||||||
Paul Gilbert
|
Paul Gilbert
|
||||||
Travis Howell - (retired)
|
Travis Howell
|
||||||
Oliver Kiehl - (retired)
|
Oliver Kiehl - (retired)
|
||||||
Ludvig Strigeus - (retired)
|
Ludvig Strigeus - (retired)
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ ScummVM Team
|
||||||
Max Horn - (retired)
|
Max Horn - (retired)
|
||||||
Filippos Karapetis
|
Filippos Karapetis
|
||||||
Martin Kiewitz
|
Martin Kiewitz
|
||||||
Walter van Niftrik
|
Walter van Niftrik - (retired)
|
||||||
Willem Jan Palenstijn
|
Willem Jan Palenstijn
|
||||||
Jordi Vilalta Prat
|
Jordi Vilalta Prat
|
||||||
Lars Skovlund
|
Lars Skovlund
|
||||||
|
@ -361,7 +361,7 @@ Other contributions
|
||||||
Markus Strangl
|
Markus Strangl
|
||||||
|
|
||||||
Win32:
|
Win32:
|
||||||
Travis Howell - (retired)
|
Travis Howell
|
||||||
|
|
||||||
Win64:
|
Win64:
|
||||||
Chris Gray - (retired)
|
Chris Gray - (retired)
|
||||||
|
|
2
NEWS
2
NEWS
|
@ -5,7 +5,7 @@ For a more comprehensive changelog of the latest experimental code, see:
|
||||||
SDL ports:
|
SDL ports:
|
||||||
- Added support for OpenGL (GSoC Task).
|
- Added support for OpenGL (GSoC Task).
|
||||||
|
|
||||||
1.3.1 (????-??-??)
|
1.3.1 (2011-07-12)
|
||||||
General:
|
General:
|
||||||
- Improved audio device detection and fallback.
|
- Improved audio device detection and fallback.
|
||||||
There should be no more silent errors due to invalid audio devices.
|
There should be no more silent errors due to invalid audio devices.
|
||||||
|
|
3
README
3
README
|
@ -219,6 +219,7 @@ AGI Games by Sierra:
|
||||||
AGOS Games by Adventuresoft/Horrorsoft:
|
AGOS Games by Adventuresoft/Horrorsoft:
|
||||||
Elvira - Mistress of the Dark [elvira1]
|
Elvira - Mistress of the Dark [elvira1]
|
||||||
Elvira II - The Jaws of Cerberus [elvira2]
|
Elvira II - The Jaws of Cerberus [elvira2]
|
||||||
|
Personal Nightmare [pn]
|
||||||
Waxworks [waxworks]
|
Waxworks [waxworks]
|
||||||
Simon the Sorcerer 1 [simon1]
|
Simon the Sorcerer 1 [simon1]
|
||||||
Simon the Sorcerer 2 [simon2]
|
Simon the Sorcerer 2 [simon2]
|
||||||
|
@ -942,6 +943,7 @@ arguments -- see the next section.
|
||||||
-z, --list-games Display list of supported games and exit
|
-z, --list-games Display list of supported games and exit
|
||||||
-t, --list-targets Display list of configured targets and exit
|
-t, --list-targets Display list of configured targets and exit
|
||||||
--list-saves=TARGET Display a list of savegames for the game (TARGET) specified
|
--list-saves=TARGET Display a list of savegames for the game (TARGET) specified
|
||||||
|
--console Enable the console window (default: enabled) (Windows only)
|
||||||
|
|
||||||
-c, --config=CONFIG Use alternate configuration file
|
-c, --config=CONFIG Use alternate configuration file
|
||||||
-p, --path=PATH Path to where the game is installed
|
-p, --path=PATH Path to where the game is installed
|
||||||
|
@ -1974,6 +1976,7 @@ The following keywords are recognized:
|
||||||
|
|
||||||
confirm_exit bool Ask for confirmation by the user before quitting
|
confirm_exit bool Ask for confirmation by the user before quitting
|
||||||
(SDL backend only).
|
(SDL backend only).
|
||||||
|
console bool Enable the console window (default: enabled) (Windows only).
|
||||||
cdrom number Number of CD-ROM unit to use for audio. If
|
cdrom number Number of CD-ROM unit to use for audio. If
|
||||||
negative, don't even try to access the CD-ROM.
|
negative, don't even try to access the CD-ROM.
|
||||||
joystick_num number Number of joystick device to use for input
|
joystick_num number Number of joystick device to use for input
|
||||||
|
|
|
@ -128,7 +128,8 @@ Common::String MidiDriver::getDeviceString(DeviceHandle handle, DeviceStringType
|
||||||
|
|
||||||
MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
||||||
// Query the selected music device (defaults to MT_AUTO device).
|
// Query the selected music device (defaults to MT_AUTO device).
|
||||||
DeviceHandle hdl = getDeviceHandle(ConfMan.get("music_driver"));
|
Common::String selDevStr = ConfMan.hasKey("music_driver") ? ConfMan.get("music_driver") : Common::String("auto");
|
||||||
|
DeviceHandle hdl = getDeviceHandle(selDevStr.empty() ? Common::String("auto") : selDevStr);
|
||||||
DeviceHandle reslt = 0;
|
DeviceHandle reslt = 0;
|
||||||
|
|
||||||
_forceTypeMT32 = false;
|
_forceTypeMT32 = false;
|
||||||
|
@ -200,7 +201,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
||||||
if (getMusicType(hdl) == MT_INVALID) {
|
if (getMusicType(hdl) == MT_INVALID) {
|
||||||
// If the expressly selected driver or device cannot be found (no longer compiled in, turned off, etc.)
|
// If the expressly selected driver or device cannot be found (no longer compiled in, turned off, etc.)
|
||||||
// we display a warning and continue.
|
// we display a warning and continue.
|
||||||
failedDevStr = ConfMan.get("music_driver");
|
failedDevStr = selDevStr;
|
||||||
Common::String warningMsg = Common::String::format(_("The selected audio device '%s' was not found (e.g. might be turned off or disconnected). Attempting to fall back to the next available device..."), failedDevStr.c_str());
|
Common::String warningMsg = Common::String::format(_("The selected audio device '%s' was not found (e.g. might be turned off or disconnected). Attempting to fall back to the next available device..."), failedDevStr.c_str());
|
||||||
GUI::MessageDialog dialog(warningMsg);
|
GUI::MessageDialog dialog(warningMsg);
|
||||||
dialog.runModal();
|
dialog.runModal();
|
||||||
|
@ -230,13 +231,15 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) {
|
||||||
// If a preferred MT32 or GM device has been selected that device gets returned if available.
|
// If a preferred MT32 or GM device has been selected that device gets returned if available.
|
||||||
Common::String devStr;
|
Common::String devStr;
|
||||||
if (flags & MDT_PREFER_MT32)
|
if (flags & MDT_PREFER_MT32)
|
||||||
devStr = ConfMan.get("mt32_device");
|
devStr = ConfMan.hasKey("mt32_device") ? ConfMan.get("mt32_device") : Common::String("null");
|
||||||
else if (flags & MDT_PREFER_GM)
|
else if (flags & MDT_PREFER_GM)
|
||||||
devStr = ConfMan.get("gm_device");
|
devStr = ConfMan.hasKey("gm_device") ? ConfMan.get("gm_device") : Common::String("null");
|
||||||
else
|
else
|
||||||
devStr = "auto";
|
devStr = "auto";
|
||||||
|
|
||||||
hdl = getDeviceHandle(devStr);
|
// Default to Null device here, since we also register a default null setting for
|
||||||
|
// the MT32 or GM device in the config manager.
|
||||||
|
hdl = getDeviceHandle(devStr.empty() ? Common::String("null") : devStr);
|
||||||
const MusicType type = getMusicType(hdl);
|
const MusicType type = getMusicType(hdl);
|
||||||
|
|
||||||
// If we have a "Don't use GM/MT-32" setting we skip this part and jump
|
// If we have a "Don't use GM/MT-32" setting we skip this part and jump
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
#include "backends/fs/ds/ds-fs.h"
|
#include "backends/fs/ds/ds-fs.h"
|
||||||
#include "dsmain.h" //for the isGBAMPAvailable() function
|
#include "dsmain.h" //for the isGBAMPAvailable() function
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(DSFilesystemFactory);
|
DECLARE_SINGLETON(DSFilesystemFactory);
|
||||||
|
}
|
||||||
|
|
||||||
AbstractFSNode *DSFilesystemFactory::makeRootFileNode() const {
|
AbstractFSNode *DSFilesystemFactory::makeRootFileNode() const {
|
||||||
if (DS::isGBAMPAvailable()) {
|
if (DS::isGBAMPAvailable()) {
|
||||||
|
|
|
@ -27,7 +27,9 @@
|
||||||
#include "backends/fs/ps2/ps2-fs-factory.h"
|
#include "backends/fs/ps2/ps2-fs-factory.h"
|
||||||
#include "backends/fs/ps2/ps2-fs.h"
|
#include "backends/fs/ps2/ps2-fs.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(Ps2FilesystemFactory);
|
DECLARE_SINGLETON(Ps2FilesystemFactory);
|
||||||
|
}
|
||||||
|
|
||||||
AbstractFSNode *Ps2FilesystemFactory::makeRootFileNode() const {
|
AbstractFSNode *Ps2FilesystemFactory::makeRootFileNode() const {
|
||||||
return new Ps2FilesystemNode();
|
return new Ps2FilesystemNode();
|
||||||
|
|
|
@ -43,7 +43,9 @@
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(PSPFilesystemFactory);
|
DECLARE_SINGLETON(PSPFilesystemFactory);
|
||||||
|
}
|
||||||
|
|
||||||
AbstractFSNode *PSPFilesystemFactory::makeRootFileNode() const {
|
AbstractFSNode *PSPFilesystemFactory::makeRootFileNode() const {
|
||||||
return new PSPFilesystemNode();
|
return new PSPFilesystemNode();
|
||||||
|
|
|
@ -40,7 +40,9 @@
|
||||||
#include <smb.h>
|
#include <smb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(WiiFilesystemFactory);
|
DECLARE_SINGLETON(WiiFilesystemFactory);
|
||||||
|
}
|
||||||
|
|
||||||
WiiFilesystemFactory::WiiFilesystemFactory() :
|
WiiFilesystemFactory::WiiFilesystemFactory() :
|
||||||
_dvdMounted(false),
|
_dvdMounted(false),
|
||||||
|
|
|
@ -752,6 +752,12 @@ bool SurfaceSdlGraphicsManager::loadGFXMode() {
|
||||||
error("allocating _screen failed");
|
error("allocating _screen failed");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// SDL 1.2 palettes default to all black,
|
||||||
|
// SDL 1.3 palettes default to all white,
|
||||||
|
// Thus set our own default palette to all black.
|
||||||
|
// SDL_SetColors does nothing for non indexed surfaces.
|
||||||
|
SDL_SetColors(_screen, _currentPalette, 0, 256);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Create the surface that contains the scaled graphics in 16 bit mode
|
// Create the surface that contains the scaled graphics in 16 bit mode
|
||||||
//
|
//
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
|
|
||||||
#include "engines/engine.h"
|
#include "engines/engine.h"
|
||||||
|
|
||||||
#include "graphics/font.h"
|
#include "graphics/fonts/bdf.h"
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
#include "icon.h"
|
#include "icon.h"
|
||||||
|
@ -96,7 +96,7 @@ OSystem_PS2 *g_systemPs2;
|
||||||
#define FOREVER 2147483647
|
#define FOREVER 2147483647
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
extern const NewFont g_sysfont;
|
extern const BdfFont g_sysfont;
|
||||||
};
|
};
|
||||||
|
|
||||||
PS2Device detectBootPath(const char *elfPath, char *bootPath);
|
PS2Device detectBootPath(const char *elfPath, char *bootPath);
|
||||||
|
|
|
@ -62,7 +62,9 @@ const OSystem::GraphicsMode DisplayManager::_supportedModes[] = {
|
||||||
|
|
||||||
// Class VramAllocator -----------------------------------
|
// Class VramAllocator -----------------------------------
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(VramAllocator);
|
DECLARE_SINGLETON(VramAllocator);
|
||||||
|
}
|
||||||
|
|
||||||
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
//#define __PSP_DEBUG_FUNCS__ /* For debugging the stack */
|
||||||
//#define __PSP_DEBUG_PRINT__
|
//#define __PSP_DEBUG_PRINT__
|
||||||
|
|
|
@ -30,7 +30,9 @@
|
||||||
//#define __PSP_DEBUG_PRINT__
|
//#define __PSP_DEBUG_PRINT__
|
||||||
#include "backends/platform/psp/trace.h"
|
#include "backends/platform/psp/trace.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(PowerManager);
|
DECLARE_SINGLETON(PowerManager);
|
||||||
|
}
|
||||||
|
|
||||||
// Function to debug the Power Manager (we have no output to screen)
|
// Function to debug the Power Manager (we have no output to screen)
|
||||||
inline void PowerManager::debugPM() {
|
inline void PowerManager::debugPM() {
|
||||||
|
|
|
@ -34,7 +34,9 @@
|
||||||
|
|
||||||
|
|
||||||
// Class PspRtc ---------------------------------------------------------------
|
// Class PspRtc ---------------------------------------------------------------
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(PspRtc);
|
DECLARE_SINGLETON(PspRtc);
|
||||||
|
}
|
||||||
|
|
||||||
void PspRtc::init() { // init our starting ticks
|
void PspRtc::init() { // init our starting ticks
|
||||||
uint32 ticks[2];
|
uint32 ticks[2];
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
#define FORBIDDEN_SYMBOL_ALLOW_ALL
|
||||||
|
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
@ -44,46 +45,7 @@
|
||||||
|
|
||||||
#define DEFAULT_CONFIG_FILE "scummvm.ini"
|
#define DEFAULT_CONFIG_FILE "scummvm.ini"
|
||||||
|
|
||||||
//#define HIDE_CONSOLE
|
|
||||||
|
|
||||||
#ifdef HIDE_CONSOLE
|
|
||||||
struct SdlConsoleHidingWin32 {
|
|
||||||
DWORD myPid;
|
|
||||||
DWORD myTid;
|
|
||||||
HWND consoleHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
// console hiding for win32
|
|
||||||
static BOOL CALLBACK initBackendFindConsoleWin32Proc(HWND hWnd, LPARAM lParam) {
|
|
||||||
DWORD pid, tid;
|
|
||||||
SdlConsoleHidingWin32 *variables = (SdlConsoleHidingWin32 *)lParam;
|
|
||||||
tid = GetWindowThreadProcessId(hWnd, &pid);
|
|
||||||
if ((tid == variables->myTid) && (pid == variables->myPid)) {
|
|
||||||
variables->consoleHandle = hWnd;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OSystem_Win32::init() {
|
void OSystem_Win32::init() {
|
||||||
#ifdef HIDE_CONSOLE
|
|
||||||
// console hiding for win32
|
|
||||||
SdlConsoleHidingWin32 consoleHidingWin32;
|
|
||||||
consoleHidingWin32.consoleHandle = 0;
|
|
||||||
consoleHidingWin32.myPid = GetCurrentProcessId();
|
|
||||||
consoleHidingWin32.myTid = GetCurrentThreadId();
|
|
||||||
EnumWindows (initBackendFindConsoleWin32Proc, (LPARAM)&consoleHidingWin32);
|
|
||||||
|
|
||||||
if (!ConfMan.getBool("show_console")) {
|
|
||||||
if (consoleHidingWin32.consoleHandle) {
|
|
||||||
// We won't find a window with our TID/PID in case we were started from command-line
|
|
||||||
ShowWindow(consoleHidingWin32.consoleHandle, SW_HIDE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initialize File System Factory
|
// Initialize File System Factory
|
||||||
_fsFactory = new WindowsFilesystemFactory();
|
_fsFactory = new WindowsFilesystemFactory();
|
||||||
|
|
||||||
|
@ -96,6 +58,26 @@ void OSystem_Win32::init() {
|
||||||
OSystem_SDL::init();
|
OSystem_SDL::init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OSystem_Win32::initBackend() {
|
||||||
|
// Console window is enabled by default on Windows
|
||||||
|
ConfMan.registerDefault("console", true);
|
||||||
|
|
||||||
|
// Enable or disable the window console window
|
||||||
|
if (ConfMan.getBool("console")) {
|
||||||
|
if (AllocConsole()) {
|
||||||
|
freopen("CONIN$","r",stdin);
|
||||||
|
freopen("CONOUT$","w",stdout);
|
||||||
|
freopen("CONOUT$","w",stderr);
|
||||||
|
}
|
||||||
|
SetConsoleTitle("ScummVM Status Window");
|
||||||
|
} else {
|
||||||
|
FreeConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoke parent implementation of this method
|
||||||
|
OSystem_SDL::initBackend();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool OSystem_Win32::hasFeature(Feature f) {
|
bool OSystem_Win32::hasFeature(Feature f) {
|
||||||
if (f == kFeatureDisplayLogFile)
|
if (f == kFeatureDisplayLogFile)
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
class OSystem_Win32 : public OSystem_SDL {
|
class OSystem_Win32 : public OSystem_SDL {
|
||||||
public:
|
public:
|
||||||
virtual void init();
|
virtual void init();
|
||||||
|
virtual void initBackend();
|
||||||
|
|
||||||
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
|
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
ScummVM Windows CE FAQ
|
ScummVM Windows CE FAQ
|
||||||
Last updated: 2011-05-27
|
Last updated: 2011-07-01
|
||||||
Release version: 1.3.0
|
Release version: 1.3.1
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
|
|
||||||
New in this version
|
New in this version
|
||||||
-------------------
|
-------------------
|
||||||
|
1.3.1:
|
||||||
|
- Fix for Normal2xAspect scaler which was causing screen update issues in some
|
||||||
|
games.
|
||||||
|
- Fix for Normal1xAspect scaler which caused problems in the bottom part of the
|
||||||
|
screen when toolbar was hidden.
|
||||||
|
- Fix for freelook mode.
|
||||||
|
- Fix for timer manager, caused timing issues in some games.
|
||||||
|
- Activated runtime language detection for ScummVM gui.
|
||||||
|
- Toolbar is now hidden when returning to the game list.
|
||||||
|
- Double-tap right-click emulation is now turned off for SCI games by default.
|
||||||
|
- Added a new option "no_doubletap_paneltoggle" for scummvm.ini to disable
|
||||||
|
toolbar toggling when double-tapping on the top part of the screen.
|
||||||
|
- SDL library related fixes:
|
||||||
|
* Fix for screen/mouse-cursor rotation issues (fixes erratic touchscreen
|
||||||
|
behaviour)
|
||||||
|
* Fix for hardware keyboard on some devices (HTC Touch Pro, etc.)
|
||||||
|
|
||||||
1.3.0:
|
1.3.0:
|
||||||
This is the first official Windows CE release since 1.1.1.
|
This is the first official Windows CE release since 1.1.1.
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(ELFMemoryManager);
|
DECLARE_SINGLETON(ELFMemoryManager);
|
||||||
|
}
|
||||||
|
|
||||||
ELFMemoryManager::ELFMemoryManager() :
|
ELFMemoryManager::ELFMemoryManager() :
|
||||||
_heap(0), _heapSize(0), _heapAlign(0),
|
_heap(0), _heapSize(0), _heapAlign(0),
|
||||||
|
|
|
@ -33,7 +33,9 @@ extern char __plugin_hole_start; // Indicates start of hole in program file for
|
||||||
extern char __plugin_hole_end; // Indicates end of hole in program file
|
extern char __plugin_hole_end; // Indicates end of hole in program file
|
||||||
extern char _gp[]; // Value of gp register
|
extern char _gp[]; // Value of gp register
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(ShortSegmentManager); // For singleton
|
DECLARE_SINGLETON(ShortSegmentManager); // For singleton
|
||||||
|
}
|
||||||
|
|
||||||
ShortSegmentManager::ShortSegmentManager() {
|
ShortSegmentManager::ShortSegmentManager() {
|
||||||
_shortsStart = &__plugin_hole_start ; //shorts segment begins at the plugin hole we made when linking
|
_shortsStart = &__plugin_hole_start ; //shorts segment begins at the plugin hole we made when linking
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
// System.Title property key, values taken from http://msdn.microsoft.com/en-us/library/bb787584.aspx
|
// System.Title property key, values taken from http://msdn.microsoft.com/en-us/library/bb787584.aspx
|
||||||
const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } }, /* propID = */ 2 };
|
const PROPERTYKEY PKEY_Title = { /* fmtid = */ { 0xF29F85E0, 0x4FF9, 0x1068, { 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9 } }, /* propID = */ 2 };
|
||||||
|
|
||||||
Win32TaskbarManager::Win32TaskbarManager() : _taskbar(NULL) {
|
Win32TaskbarManager::Win32TaskbarManager() : _taskbar(NULL), _count(0), _icon(NULL) {
|
||||||
// Do nothing if not running on Windows 7 or later
|
// Do nothing if not running on Windows 7 or later
|
||||||
if (!isWin7OrLater())
|
if (!isWin7OrLater())
|
||||||
return;
|
return;
|
||||||
|
@ -96,6 +96,9 @@ Win32TaskbarManager::~Win32TaskbarManager() {
|
||||||
_taskbar->Release();
|
_taskbar->Release();
|
||||||
_taskbar = NULL;
|
_taskbar = NULL;
|
||||||
|
|
||||||
|
if (_icon)
|
||||||
|
DestroyIcon(_icon);
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,6 +147,123 @@ void Win32TaskbarManager::setProgressState(TaskbarProgressState state) {
|
||||||
_taskbar->SetProgressState(getHwnd(), (TBPFLAG)state);
|
_taskbar->SetProgressState(getHwnd(), (TBPFLAG)state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Win32TaskbarManager::setCount(int count) {
|
||||||
|
if (_taskbar == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
_taskbar->SetOverlayIcon(getHwnd(), NULL, L"");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: This isn't really nice and could use a cleanup.
|
||||||
|
// The only good thing is that it doesn't use GDI+
|
||||||
|
// and thus does not have a dependancy on it,
|
||||||
|
// with the downside of being a lot more ugly.
|
||||||
|
// Maybe replace it by a Graphic::Surface, use
|
||||||
|
// ScummVM font drawing and extract the contents at
|
||||||
|
// the end?
|
||||||
|
|
||||||
|
if (_count != count || _icon == NULL) {
|
||||||
|
// Cleanup previous icon
|
||||||
|
_count = count;
|
||||||
|
if (_icon)
|
||||||
|
DestroyIcon(_icon);
|
||||||
|
|
||||||
|
Common::String countString = (count < 100 ? Common::String::format("%d", count) : "9+");
|
||||||
|
|
||||||
|
// Create transparent background
|
||||||
|
BITMAPV5HEADER bi;
|
||||||
|
ZeroMemory(&bi, sizeof(BITMAPV5HEADER));
|
||||||
|
bi.bV5Size = sizeof(BITMAPV5HEADER);
|
||||||
|
bi.bV5Width = 16;
|
||||||
|
bi.bV5Height = 16;
|
||||||
|
bi.bV5Planes = 1;
|
||||||
|
bi.bV5BitCount = 32;
|
||||||
|
bi.bV5Compression = BI_RGB;
|
||||||
|
// Set 32 BPP alpha format
|
||||||
|
bi.bV5RedMask = 0x00FF0000;
|
||||||
|
bi.bV5GreenMask = 0x0000FF00;
|
||||||
|
bi.bV5BlueMask = 0x000000FF;
|
||||||
|
bi.bV5AlphaMask = 0xFF000000;
|
||||||
|
|
||||||
|
// Get DC
|
||||||
|
HDC hdc;
|
||||||
|
hdc = GetDC(NULL);
|
||||||
|
HDC hMemDC = CreateCompatibleDC(hdc);
|
||||||
|
ReleaseDC(NULL, hdc);
|
||||||
|
|
||||||
|
// Create a bitmap mask
|
||||||
|
HBITMAP hBitmapMask = CreateBitmap(16, 16, 1, 1, NULL);
|
||||||
|
|
||||||
|
// Create the DIB section with an alpha channel
|
||||||
|
void *lpBits;
|
||||||
|
HBITMAP hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, 0);
|
||||||
|
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
|
||||||
|
|
||||||
|
// Load the icon background
|
||||||
|
HICON hIconBackground = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(1002 /* IDI_COUNT */));
|
||||||
|
DrawIconEx(hMemDC, 0, 0, hIconBackground, 16, 16, 0, 0, DI_NORMAL);
|
||||||
|
DeleteObject(hIconBackground);
|
||||||
|
|
||||||
|
// Draw the count
|
||||||
|
LOGFONT lFont;
|
||||||
|
memset(&lFont, 0, sizeof(LOGFONT));
|
||||||
|
lFont.lfHeight = 10;
|
||||||
|
lFont.lfWeight = FW_BOLD;
|
||||||
|
lFont.lfItalic = 1;
|
||||||
|
strcpy(lFont.lfFaceName, "Arial");
|
||||||
|
|
||||||
|
HFONT hFont = CreateFontIndirect(&lFont);
|
||||||
|
SelectObject(hMemDC, hFont);
|
||||||
|
|
||||||
|
RECT rect;
|
||||||
|
SetRect(&rect, 4, 4, 12, 12);
|
||||||
|
SetTextColor(hMemDC, RGB(48, 48, 48));
|
||||||
|
SetBkMode(hMemDC, TRANSPARENT);
|
||||||
|
DrawText(hMemDC, countString.c_str(), -1, &rect, DT_NOCLIP|DT_CENTER);
|
||||||
|
|
||||||
|
// Set the text alpha to fully opaque (we consider the data inside the text rect)
|
||||||
|
DWORD *lpdwPixel = (DWORD *)lpBits;
|
||||||
|
for (int x = 3; x < 12; x++) {
|
||||||
|
for(int y = 3; y < 12; y++) {
|
||||||
|
unsigned char *p = (unsigned char *)(lpdwPixel + x * 16 + y);
|
||||||
|
|
||||||
|
if (p[0] != 0 && p[1] != 0 && p[2] != 0)
|
||||||
|
p[3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup DC
|
||||||
|
DeleteObject(hFont);
|
||||||
|
SelectObject(hMemDC, hOldBitmap);
|
||||||
|
DeleteDC(hMemDC);
|
||||||
|
|
||||||
|
// Prepare our new icon
|
||||||
|
ICONINFO ii;
|
||||||
|
ii.fIcon = FALSE;
|
||||||
|
ii.xHotspot = 0;
|
||||||
|
ii.yHotspot = 0;
|
||||||
|
ii.hbmMask = hBitmapMask;
|
||||||
|
ii.hbmColor = hBitmap;
|
||||||
|
|
||||||
|
_icon = CreateIconIndirect(&ii);
|
||||||
|
|
||||||
|
DeleteObject(hBitmap);
|
||||||
|
DeleteObject(hBitmapMask);
|
||||||
|
|
||||||
|
if (!_icon) {
|
||||||
|
warning("[Win32TaskbarManager::setCount] Cannot create icon for count");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets the overlay icon
|
||||||
|
LPWSTR desc = ansiToUnicode(Common::String::format("Found games: %d", count).c_str());
|
||||||
|
_taskbar->SetOverlayIcon(getHwnd(), _icon, desc);
|
||||||
|
delete[] desc;
|
||||||
|
}
|
||||||
|
|
||||||
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
|
void Win32TaskbarManager::addRecent(const Common::String &name, const Common::String &description) {
|
||||||
//warning("[Win32TaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str());
|
//warning("[Win32TaskbarManager::addRecent] Adding recent list entry: %s (%s)", name.c_str(), description.c_str());
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,16 @@ public:
|
||||||
virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
|
virtual void setOverlayIcon(const Common::String &name, const Common::String &description);
|
||||||
virtual void setProgressValue(int completed, int total);
|
virtual void setProgressValue(int completed, int total);
|
||||||
virtual void setProgressState(TaskbarProgressState state);
|
virtual void setProgressState(TaskbarProgressState state);
|
||||||
|
virtual void setCount(int count);
|
||||||
virtual void addRecent(const Common::String &name, const Common::String &description);
|
virtual void addRecent(const Common::String &name, const Common::String &description);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ITaskbarList3 *_taskbar;
|
ITaskbarList3 *_taskbar;
|
||||||
|
|
||||||
|
// Count handling
|
||||||
|
HICON _icon;
|
||||||
|
int _count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the path to an icon for the game
|
* Get the path to an icon for the game
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,6 +65,9 @@ static const char HELP_STRING[] =
|
||||||
" -z, --list-games Display list of supported games and exit\n"
|
" -z, --list-games Display list of supported games and exit\n"
|
||||||
" -t, --list-targets Display list of configured targets and exit\n"
|
" -t, --list-targets Display list of configured targets and exit\n"
|
||||||
" --list-saves=TARGET Display a list of savegames for the game (TARGET) specified\n"
|
" --list-saves=TARGET Display a list of savegames for the game (TARGET) specified\n"
|
||||||
|
#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
|
||||||
|
" --console Enable the console window (default:enabled)\n"
|
||||||
|
#endif
|
||||||
"\n"
|
"\n"
|
||||||
" -c, --config=CONFIG Use alternate configuration file\n"
|
" -c, --config=CONFIG Use alternate configuration file\n"
|
||||||
" -p, --path=PATH Path to where the game is installed\n"
|
" -p, --path=PATH Path to where the game is installed\n"
|
||||||
|
@ -181,8 +184,8 @@ void registerDefaults() {
|
||||||
ConfMan.registerDefault("native_mt32", false);
|
ConfMan.registerDefault("native_mt32", false);
|
||||||
ConfMan.registerDefault("enable_gs", false);
|
ConfMan.registerDefault("enable_gs", false);
|
||||||
ConfMan.registerDefault("midi_gain", 100);
|
ConfMan.registerDefault("midi_gain", 100);
|
||||||
// ConfMan.registerDefault("music_driver", ???);
|
|
||||||
|
|
||||||
|
ConfMan.registerDefault("music_driver", "auto");
|
||||||
ConfMan.registerDefault("mt32_device", "null");
|
ConfMan.registerDefault("mt32_device", "null");
|
||||||
ConfMan.registerDefault("gm_device", "null");
|
ConfMan.registerDefault("gm_device", "null");
|
||||||
|
|
||||||
|
@ -231,13 +234,6 @@ void registerDefaults() {
|
||||||
ConfMan.registerDefault("record_temp_file_name", "record.tmp");
|
ConfMan.registerDefault("record_temp_file_name", "record.tmp");
|
||||||
ConfMan.registerDefault("record_time_file_name", "record.time");
|
ConfMan.registerDefault("record_time_file_name", "record.time");
|
||||||
|
|
||||||
#if 0
|
|
||||||
// NEW CODE TO HIDE CONSOLE FOR WIN32
|
|
||||||
#ifdef WIN32
|
|
||||||
// console hiding for win32
|
|
||||||
ConfMan.registerDefault("show_console", false);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -554,14 +550,11 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha
|
||||||
END_OPTION
|
END_OPTION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__)
|
||||||
// NEW CODE TO HIDE CONSOLE FOR WIN32
|
// Optional console window on Windows (default: enabled)
|
||||||
#ifdef WIN32
|
DO_LONG_OPTION_BOOL("console")
|
||||||
// console hiding for win32
|
|
||||||
DO_LONG_OPTION_BOOL("show-console")
|
|
||||||
END_OPTION
|
END_OPTION
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
unknownOption:
|
unknownOption:
|
||||||
// If we get till here, the option is unhandled and hence unknown.
|
// If we get till here, the option is unhandled and hence unknown.
|
||||||
|
@ -669,7 +662,7 @@ static Common::Error listSaves(const char *target) {
|
||||||
" ---- ------------------------------------------------------\n");
|
" ---- ------------------------------------------------------\n");
|
||||||
|
|
||||||
for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) {
|
for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) {
|
||||||
printf(" %-4s %s\n", x->save_slot().c_str(), x->description().c_str());
|
printf(" %-4d %s\n", x->getSaveSlot(), x->getDescription().c_str());
|
||||||
// TODO: Could also iterate over the full hashmap, printing all key-value pairs
|
// TODO: Could also iterate over the full hashmap, printing all key-value pairs
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -543,7 +543,9 @@ void PluginManager::addToPluginsInMemList(Plugin *plugin) {
|
||||||
|
|
||||||
#include "engines/metaengine.h"
|
#include "engines/metaengine.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(EngineManager);
|
DECLARE_SINGLETON(EngineManager);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function works for both cached and uncached PluginManagers.
|
* This function works for both cached and uncached PluginManagers.
|
||||||
|
@ -634,7 +636,9 @@ const EnginePlugin::List &EngineManager::getPlugins() const {
|
||||||
|
|
||||||
#include "audio/musicplugin.h"
|
#include "audio/musicplugin.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(MusicManager);
|
DECLARE_SINGLETON(MusicManager);
|
||||||
|
}
|
||||||
|
|
||||||
const MusicPlugin::List &MusicManager::getPlugins() const {
|
const MusicPlugin::List &MusicManager::getPlugins() const {
|
||||||
return (const MusicPlugin::List &)PluginManager::instance().getPlugins(PLUGIN_TYPE_MUSIC);
|
return (const MusicPlugin::List &)PluginManager::instance().getPlugins(PLUGIN_TYPE_MUSIC);
|
||||||
|
|
|
@ -27,10 +27,10 @@
|
||||||
#include "common/savefile.h"
|
#include "common/savefile.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
DECLARE_SINGLETON(Common::EventRecorder);
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(EventRecorder);
|
||||||
|
|
||||||
#define RECORD_SIGNATURE 0x54455354
|
#define RECORD_SIGNATURE 0x54455354
|
||||||
#define RECORD_VERSION 1
|
#define RECORD_VERSION 1
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,7 @@ void SearchManager::clear() {
|
||||||
addDirectory(".", ".", -2);
|
addDirectory(".", ".", -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(SearchManager);
|
||||||
|
|
||||||
} // namespace Common
|
} // namespace Common
|
||||||
|
|
||||||
DECLARE_SINGLETON(Common::SearchManager);
|
|
||||||
|
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
DECLARE_SINGLETON(Common::ConfigManager);
|
|
||||||
|
|
||||||
static bool isValidDomainName(const Common::String &domName) {
|
static bool isValidDomainName(const Common::String &domName) {
|
||||||
const char *p = domName.c_str();
|
const char *p = domName.c_str();
|
||||||
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
|
while (*p && (isalnum(static_cast<unsigned char>(*p)) || *p == '-' || *p == '_'))
|
||||||
|
@ -38,6 +36,8 @@ static bool isValidDomainName(const Common::String &domName) {
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(ConfigManager);
|
||||||
|
|
||||||
const char *ConfigManager::kApplicationDomain = "scummvm";
|
const char *ConfigManager::kApplicationDomain = "scummvm";
|
||||||
const char *ConfigManager::kTransientDomain = "__TRANSIENT";
|
const char *ConfigManager::kTransientDomain = "__TRANSIENT";
|
||||||
|
|
||||||
|
|
|
@ -23,16 +23,17 @@
|
||||||
#include "common/debug-channels.h"
|
#include "common/debug-channels.h"
|
||||||
#include "common/system.h"
|
#include "common/system.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
#include "common/algorithm.h"
|
||||||
|
|
||||||
#include <stdarg.h> // For va_list etc.
|
#include <stdarg.h> // For va_list etc.
|
||||||
|
|
||||||
// TODO: Move gDebugLevel into namespace Common.
|
// TODO: Move gDebugLevel into namespace Common.
|
||||||
int gDebugLevel = -1;
|
int gDebugLevel = -1;
|
||||||
|
|
||||||
DECLARE_SINGLETON(Common::DebugManager);
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(DebugManager);
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct DebugLevelComperator {
|
struct DebugLevelComperator {
|
||||||
|
|
|
@ -106,8 +106,9 @@ private:
|
||||||
HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR
|
HASHMAP_MEMORYPOOL_SIZE = HASHMAP_MIN_CAPACITY * HASHMAP_LOADFACTOR_NUMERATOR / HASHMAP_LOADFACTOR_DENOMINATOR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_HASHMAP_MEMORY_POOL
|
||||||
ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool;
|
ObjectPool<Node, HASHMAP_MEMORYPOOL_SIZE> _nodePool;
|
||||||
|
#endif
|
||||||
|
|
||||||
Node **_storage; ///< hashtable of size arrsize.
|
Node **_storage; ///< hashtable of size arrsize.
|
||||||
uint _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
|
uint _mask; ///< Capacity of the HashMap minus one; must be a power of two of minus one
|
||||||
|
@ -128,12 +129,20 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Node *allocNode(const Key &key) {
|
Node *allocNode(const Key &key) {
|
||||||
|
#ifdef USE_HASHMAP_MEMORY_POOL
|
||||||
return new (_nodePool) Node(key);
|
return new (_nodePool) Node(key);
|
||||||
|
#else
|
||||||
|
return new Node(key);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeNode(Node *node) {
|
void freeNode(Node *node) {
|
||||||
if (node && node != HASHMAP_DUMMY_NODE)
|
if (node && node != HASHMAP_DUMMY_NODE)
|
||||||
|
#ifdef USE_HASHMAP_MEMORY_POOL
|
||||||
_nodePool.deleteChunk(node);
|
_nodePool.deleteChunk(node);
|
||||||
|
#else
|
||||||
|
delete node;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign(const HM_t &map);
|
void assign(const HM_t &map);
|
||||||
|
|
|
@ -89,15 +89,13 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Note that you need to use this macro from the global namespace.
|
* Note that you need to use this macro from the Common namespace.
|
||||||
*
|
*
|
||||||
* This is because C++ requires initial explicit specialization
|
* This is because C++ requires initial explicit specialization
|
||||||
* to be placed in the same namespace as the template.
|
* to be placed in the same namespace as the template.
|
||||||
* It has to be put in the global namespace to assure the correct
|
|
||||||
* namespace Common is referenced.
|
|
||||||
*/
|
*/
|
||||||
#define DECLARE_SINGLETON(T) \
|
#define DECLARE_SINGLETON(T) \
|
||||||
template<> T *Common::Singleton<T>::_singleton = 0
|
template<> T *Singleton<T>::_singleton = 0
|
||||||
|
|
||||||
} // End of namespace Common
|
} // End of namespace Common
|
||||||
|
|
||||||
|
|
|
@ -154,9 +154,9 @@ protected:
|
||||||
|
|
||||||
#if defined(USE_TASKBAR)
|
#if defined(USE_TASKBAR)
|
||||||
/**
|
/**
|
||||||
* No default value is provided for _savefileManager by OSystem.
|
* No default value is provided for _taskbarManager by OSystem.
|
||||||
*
|
*
|
||||||
* @note _savefileManager is deleted by the OSystem destructor.
|
* @note _taskbarManager is deleted by the OSystem destructor.
|
||||||
*/
|
*/
|
||||||
Common::TaskbarManager *_taskbarManager;
|
Common::TaskbarManager *_taskbarManager;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,10 +37,10 @@
|
||||||
|
|
||||||
#ifdef USE_TRANSLATION
|
#ifdef USE_TRANSLATION
|
||||||
|
|
||||||
DECLARE_SINGLETON(Common::TranslationManager);
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
DECLARE_SINGLETON(TranslationManager);
|
||||||
|
|
||||||
bool operator<(const TLanguage &l, const TLanguage &r) {
|
bool operator<(const TLanguage &l, const TLanguage &r) {
|
||||||
return strcmp(l.name, r.name) < 0;
|
return strcmp(l.name, r.name) < 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "common/hashmap.h"
|
#include "common/hashmap.h"
|
||||||
#include "common/hash-str.h"
|
#include "common/hash-str.h"
|
||||||
#include "common/stack.h"
|
#include "common/stack.h"
|
||||||
|
#include "common/memorypool.h"
|
||||||
|
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
7
configure
vendored
7
configure
vendored
|
@ -175,7 +175,8 @@ _strip=strip
|
||||||
_ar="ar cru"
|
_ar="ar cru"
|
||||||
_as="as"
|
_as="as"
|
||||||
_windres=windres
|
_windres=windres
|
||||||
_win32path="build/x86"
|
_stagingpath="staging"
|
||||||
|
_win32path="c:/scummvm"
|
||||||
_aos4path="Games:ScummVM"
|
_aos4path="Games:ScummVM"
|
||||||
_staticlibpath=/sw
|
_staticlibpath=/sw
|
||||||
_sdlconfig=sdl-config
|
_sdlconfig=sdl-config
|
||||||
|
@ -1854,7 +1855,8 @@ case $_host_os in
|
||||||
mingw*)
|
mingw*)
|
||||||
DEFINES="$DEFINES -DWIN32"
|
DEFINES="$DEFINES -DWIN32"
|
||||||
DEFINES="$DEFINES -D__USE_MINGW_ANSI_STDIO=0"
|
DEFINES="$DEFINES -D__USE_MINGW_ANSI_STDIO=0"
|
||||||
LIBS="$LIBS -lmingw32 -lwinmm"
|
LDFLAGS="$LDFLAGS -static-libgcc -static-libstdc++"
|
||||||
|
LIBS="$LIBS -lmingw32 -lwinmm -lgdi32"
|
||||||
OBJS="$OBJS scummvmwinres.o"
|
OBJS="$OBJS scummvmwinres.o"
|
||||||
add_line_to_config_mk 'WIN32 = 1'
|
add_line_to_config_mk 'WIN32 = 1'
|
||||||
;;
|
;;
|
||||||
|
@ -3518,6 +3520,7 @@ AS := $_as
|
||||||
ASFLAGS := $ASFLAGS
|
ASFLAGS := $ASFLAGS
|
||||||
WINDRES := $_windres
|
WINDRES := $_windres
|
||||||
WINDRESFLAGS := $WINDRESFLAGS
|
WINDRESFLAGS := $WINDRESFLAGS
|
||||||
|
STAGINGPATH=$_stagingpath
|
||||||
WIN32PATH=$_win32path
|
WIN32PATH=$_win32path
|
||||||
AOS4PATH=$_aos4path
|
AOS4PATH=$_aos4path
|
||||||
STATICLIBPATH=$_staticlibpath
|
STATICLIBPATH=$_staticlibpath
|
||||||
|
|
|
@ -721,7 +721,7 @@ int gen_c_source(struct font* pf, char *path) {
|
||||||
char bbuf[256];
|
char bbuf[256];
|
||||||
char hdr1[] = {
|
char hdr1[] = {
|
||||||
"/* Generated by convbdf on %s. */\n"
|
"/* Generated by convbdf on %s. */\n"
|
||||||
"#include \"graphics/font.h\"\n"
|
"#include \"graphics/fonts/bdf.h\"\n"
|
||||||
"\n"
|
"\n"
|
||||||
"/* Font information:\n"
|
"/* Font information:\n"
|
||||||
" name: %s\n"
|
" name: %s\n"
|
||||||
|
@ -890,7 +890,7 @@ int gen_c_source(struct font* pf, char *path) {
|
||||||
|
|
||||||
fprintf(ofp,
|
fprintf(ofp,
|
||||||
"/* Exported structure definition. */\n"
|
"/* Exported structure definition. */\n"
|
||||||
"static const FontDesc desc = {\n"
|
"static const BdfFontDesc desc = {\n"
|
||||||
"\t" "\"%s\",\n"
|
"\t" "\"%s\",\n"
|
||||||
"\t" "%d,\n"
|
"\t" "%d,\n"
|
||||||
"\t" "%d,\n"
|
"\t" "%d,\n"
|
||||||
|
@ -917,7 +917,7 @@ int gen_c_source(struct font* pf, char *path) {
|
||||||
pf->defaultchar);
|
pf->defaultchar);
|
||||||
|
|
||||||
fprintf(ofp, "\n" "#if !(defined(__GP32__))\n");
|
fprintf(ofp, "\n" "#if !(defined(__GP32__))\n");
|
||||||
fprintf(ofp, "extern const NewFont g_sysfont(desc);\n");
|
fprintf(ofp, "extern const BdfFont g_sysfont(desc);\n");
|
||||||
fprintf(ofp, "#else\n");
|
fprintf(ofp, "#else\n");
|
||||||
fprintf(ofp, "DEFINE_FONT(g_sysfont)\n");
|
fprintf(ofp, "DEFINE_FONT(g_sysfont)\n");
|
||||||
fprintf(ofp, "#endif\n");
|
fprintf(ofp, "#endif\n");
|
||||||
|
|
|
@ -72,10 +72,9 @@ Sub CreateInstaller()
|
||||||
' Build command line
|
' Build command line
|
||||||
Dim commandLine : commandLine = """" & nsisPath & "\makensis.exe"" /V2" & _
|
Dim commandLine : commandLine = """" & nsisPath & "\makensis.exe"" /V2" & _
|
||||||
" /Dtop_srcdir=""" & rootFolder & """" & _
|
" /Dtop_srcdir=""" & rootFolder & """" & _
|
||||||
" /Dbuild_dir=""" & targetFolder & """" & _
|
" /Dstaging_dir=""" & targetFolder & """" & _
|
||||||
" /Dtext_dir=""" & rootFolder & """" & _
|
|
||||||
" /DARCH=""" & arch & """" & _
|
" /DARCH=""" & arch & """" & _
|
||||||
" """ & rootFolder & "\dists\nsis\scummvm.nsi"""
|
" """ & rootFolder & "\dists\win32\scummvm.nsi"""
|
||||||
|
|
||||||
Dim oExec: Set oExec = WshShell.Exec(commandline)
|
Dim oExec: Set oExec = WshShell.Exec(commandline)
|
||||||
If Err.Number <> 0 Then
|
If Err.Number <> 0 Then
|
||||||
|
|
|
@ -23,23 +23,7 @@ if "%~5"=="" goto error_installer
|
||||||
echo Copying data files
|
echo Copying data files
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM xcopy /F /Y "%~1/AUTHORS" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/COPYING.GPL" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/COPYING" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/COPYING.LGPL" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/COPYRIGHT" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/NEWS" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/README" %~2 1>NUL 2>&1
|
|
||||||
|
|
||||||
REM xcopy /F /Y "%~1/dists/engine-data/*.dat" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/dists/engine-data/*.tbl" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/dists/engine-data/*.cpt" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/gui/themes/*.zip" %~2 1>NUL 2>&1
|
|
||||||
REM xcopy /F /Y "%~1/gui/themes/translations.dat" %~2 1>NUL 2>&1
|
|
||||||
|
|
||||||
xcopy /F /Y "%~4/lib/%~3/SDL.dll" "%~2" 1>NUL 2>&1
|
xcopy /F /Y "%~4/lib/%~3/SDL.dll" "%~2" 1>NUL 2>&1
|
||||||
xcopy /F /Y "%~4/README-SDL" "%~2" 1>NUL 2>&1
|
|
||||||
|
|
||||||
xcopy /F /Y "%~1/backends/vkeybd/packs/vkeybd_default.zip" "%~2" 1>NUL 2>&1
|
xcopy /F /Y "%~1/backends/vkeybd/packs/vkeybd_default.zip" "%~2" 1>NUL 2>&1
|
||||||
|
|
||||||
if "%~5"=="0" goto done
|
if "%~5"=="0" goto done
|
||||||
|
|
|
@ -467,7 +467,7 @@ begin_credits("Credits");
|
||||||
add_person("Jonathan Gray", "khalek", "(retired)");
|
add_person("Jonathan Gray", "khalek", "(retired)");
|
||||||
add_person("Vincent Hamm", "yaz0r", "(retired)");
|
add_person("Vincent Hamm", "yaz0r", "(retired)");
|
||||||
add_person("Max Horn", "Fingolfin", "(retired)");
|
add_person("Max Horn", "Fingolfin", "(retired)");
|
||||||
add_person("Travis Howell", "Kirben", "(retired)");
|
add_person("Travis Howell", "Kirben", "");
|
||||||
add_person("Paweł Kołodziejski", "aquadran", "Codecs, iMUSE, Smush, etc.");
|
add_person("Paweł Kołodziejski", "aquadran", "Codecs, iMUSE, Smush, etc.");
|
||||||
add_person("Gregory Montoir", "cyx", "");
|
add_person("Gregory Montoir", "cyx", "");
|
||||||
add_person("Eugene Sandulenko", "sev", "FT INSANE, MM NES, MM C64, game detection, Herc/CGA");
|
add_person("Eugene Sandulenko", "sev", "FT INSANE, MM NES, MM C64, game detection, Herc/CGA");
|
||||||
|
@ -476,7 +476,7 @@ begin_credits("Credits");
|
||||||
|
|
||||||
begin_section("HE");
|
begin_section("HE");
|
||||||
add_person("Jonathan Gray", "khalek", "(retired)");
|
add_person("Jonathan Gray", "khalek", "(retired)");
|
||||||
add_person("Travis Howell", "Kirben", "(retired)");
|
add_person("Travis Howell", "Kirben", "");
|
||||||
add_person("Gregory Montoir", "cyx", "");
|
add_person("Gregory Montoir", "cyx", "");
|
||||||
add_person("Eugene Sandulenko", "sev", "");
|
add_person("Eugene Sandulenko", "sev", "");
|
||||||
end_section();
|
end_section();
|
||||||
|
@ -486,7 +486,7 @@ begin_credits("Credits");
|
||||||
add_person("Matthew Hoops", "clone2727", "");
|
add_person("Matthew Hoops", "clone2727", "");
|
||||||
add_person("Filippos Karapetis", "[md5]", "");
|
add_person("Filippos Karapetis", "[md5]", "");
|
||||||
add_person("Paweł Kołodziejski", "aquadran", "");
|
add_person("Paweł Kołodziejski", "aquadran", "");
|
||||||
add_person("Walter van Niftrik", "waltervn", "");
|
add_person("Walter van Niftrik", "waltervn", "(retired)");
|
||||||
add_person("Kari Salminen", "Buddha^", "");
|
add_person("Kari Salminen", "Buddha^", "");
|
||||||
add_person("Eugene Sandulenko", "sev", "");
|
add_person("Eugene Sandulenko", "sev", "");
|
||||||
add_person("David Symonds", "dsymonds", "(retired)");
|
add_person("David Symonds", "dsymonds", "(retired)");
|
||||||
|
@ -495,7 +495,7 @@ begin_credits("Credits");
|
||||||
begin_section("AGOS");
|
begin_section("AGOS");
|
||||||
add_person("Torbjörn Andersson", "eriktorbjorn", "");
|
add_person("Torbjörn Andersson", "eriktorbjorn", "");
|
||||||
add_person("Paul Gilbert", "dreammaster", "");
|
add_person("Paul Gilbert", "dreammaster", "");
|
||||||
add_person("Travis Howell", "Kirben", "(retired)");
|
add_person("Travis Howell", "Kirben", "");
|
||||||
add_person("Oliver Kiehl", "olki", "(retired)");
|
add_person("Oliver Kiehl", "olki", "(retired)");
|
||||||
add_person("Ludvig Strigeus", "ludde", "(retired)");
|
add_person("Ludvig Strigeus", "ludde", "(retired)");
|
||||||
end_section();
|
end_section();
|
||||||
|
@ -609,7 +609,7 @@ begin_credits("Credits");
|
||||||
add_person("Max Horn", "Fingolfin", "(retired)");
|
add_person("Max Horn", "Fingolfin", "(retired)");
|
||||||
add_person("Filippos Karapetis", "[md5]", "");
|
add_person("Filippos Karapetis", "[md5]", "");
|
||||||
add_person("Martin Kiewitz", "m_kiewitz", "");
|
add_person("Martin Kiewitz", "m_kiewitz", "");
|
||||||
add_person("Walter van Niftrik", "waltervn", "");
|
add_person("Walter van Niftrik", "waltervn", "(retired)");
|
||||||
add_person("Willem Jan Palenstijn", "wjp", "");
|
add_person("Willem Jan Palenstijn", "wjp", "");
|
||||||
add_person("Jordi Vilalta Prat", "jvprat", "");
|
add_person("Jordi Vilalta Prat", "jvprat", "");
|
||||||
add_person("Lars Skovlund", "lskovlun", "");
|
add_person("Lars Skovlund", "lskovlun", "");
|
||||||
|
@ -878,7 +878,7 @@ begin_credits("Credits");
|
||||||
end_section();
|
end_section();
|
||||||
|
|
||||||
begin_section("Win32");
|
begin_section("Win32");
|
||||||
add_person("Travis Howell", "Kirben", "(retired)");
|
add_person("Travis Howell", "Kirben", "");
|
||||||
end_section();
|
end_section();
|
||||||
|
|
||||||
begin_section("Win64");
|
begin_section("Win64");
|
||||||
|
|
|
@ -39,7 +39,7 @@ my @subs_files = qw(
|
||||||
dists/macosx/Info.plist
|
dists/macosx/Info.plist
|
||||||
dists/iphone/Info.plist
|
dists/iphone/Info.plist
|
||||||
dists/irix/scummvm.spec
|
dists/irix/scummvm.spec
|
||||||
dists/nsis/scummvm.nsi
|
dists/win32/scummvm.nsi
|
||||||
dists/wii/meta.xml
|
dists/wii/meta.xml
|
||||||
dists/android/AndroidManifest.xml
|
dists/android/AndroidManifest.xml
|
||||||
dists/android/plugin-manifest.xml
|
dists/android/plugin-manifest.xml
|
||||||
|
|
|
@ -6,8 +6,13 @@
|
||||||
|
|
||||||
#define FILE 256
|
#define FILE 256
|
||||||
#define IDI_ICON 1001
|
#define IDI_ICON 1001
|
||||||
|
#define IDI_COUNT 1002
|
||||||
|
#define ID_GDF_XML __GDF_XML
|
||||||
|
|
||||||
IDI_ICON ICON DISCARDABLE "icons/scummvm.ico"
|
IDI_ICON ICON DISCARDABLE "icons/scummvm.ico"
|
||||||
|
IDI_COUNT ICON DISCARDABLE "icons/count.ico"
|
||||||
|
|
||||||
|
ID_GDF_XML DATA "dists/win32/scummvm.gdf.xml"
|
||||||
|
|
||||||
scummmodern.zip FILE "gui/themes/scummmodern.zip"
|
scummmodern.zip FILE "gui/themes/scummmodern.zip"
|
||||||
#ifdef USE_TRANSLATION
|
#ifdef USE_TRANSLATION
|
||||||
|
|
|
@ -6,8 +6,13 @@
|
||||||
|
|
||||||
#define FILE 256
|
#define FILE 256
|
||||||
#define IDI_ICON 1001
|
#define IDI_ICON 1001
|
||||||
|
#define IDI_COUNT 1002
|
||||||
|
#define ID_GDF_XML __GDF_XML
|
||||||
|
|
||||||
IDI_ICON ICON DISCARDABLE "icons/scummvm.ico"
|
IDI_ICON ICON DISCARDABLE "icons/scummvm.ico"
|
||||||
|
IDI_COUNT ICON DISCARDABLE "icons/count.ico"
|
||||||
|
|
||||||
|
ID_GDF_XML DATA "dists/win32/scummvm.gdf.xml"
|
||||||
|
|
||||||
scummmodern.zip FILE "gui/themes/scummmodern.zip"
|
scummmodern.zip FILE "gui/themes/scummmodern.zip"
|
||||||
#ifdef USE_TRANSLATION
|
#ifdef USE_TRANSLATION
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
[Setup]
|
[Setup]
|
||||||
DefaultDirName={pf}\ScummVM
|
|
||||||
AppCopyright=2011
|
AppCopyright=2011
|
||||||
AppName=ScummVM
|
AppName=ScummVM
|
||||||
AppVerName=ScummVM Git
|
AppVerName=ScummVM Git
|
||||||
|
AppPublisher=The ScummVM Team
|
||||||
|
AppPublisherURL=http://www.scummvm.org/
|
||||||
|
AppSupportURL=http://www.scummvm.org/
|
||||||
|
AppUpdatesURL=http://www.scummvm.org/
|
||||||
|
DefaultDirName={pf}\ScummVM
|
||||||
DefaultGroupName=ScummVM
|
DefaultGroupName=ScummVM
|
||||||
AllowNoIcons=true
|
AllowNoIcons=true
|
||||||
AlwaysUsePersonalGroup=false
|
AlwaysUsePersonalGroup=false
|
||||||
|
@ -14,7 +18,8 @@ DisableStartupPrompt=true
|
||||||
AppendDefaultDirName=false
|
AppendDefaultDirName=false
|
||||||
SolidCompression=true
|
SolidCompression=true
|
||||||
DirExistsWarning=no
|
DirExistsWarning=no
|
||||||
SetupIconFile=scummvm.ico
|
SetupIconFile=graphics\scummvm-install.ico
|
||||||
|
WizardImageFile=graphics\left.bmp
|
||||||
ShowLanguageDialog=yes
|
ShowLanguageDialog=yes
|
||||||
LanguageDetectionMethod=uilanguage
|
LanguageDetectionMethod=uilanguage
|
||||||
|
|
||||||
|
@ -44,6 +49,7 @@ Name: es; MessagesFile: compiler:Languages\Spanish.isl
|
||||||
[Icons]
|
[Icons]
|
||||||
Name: {group}\{cm:UninstallProgram, ScummVM}; Filename: {uninstallexe}
|
Name: {group}\{cm:UninstallProgram, ScummVM}; Filename: {uninstallexe}
|
||||||
Name: {group}\ScummVM; Filename: {app}\scummvm.exe; WorkingDir: {app}; Comment: scummvm; Flags: createonlyiffileexists; IconIndex: 0
|
Name: {group}\ScummVM; Filename: {app}\scummvm.exe; WorkingDir: {app}; Comment: scummvm; Flags: createonlyiffileexists; IconIndex: 0
|
||||||
|
Name: {group}\ScummVM (noconsole); Filename: {app}\scummvm.exe; Parameters: "--no-console"; WorkingDir: {app}; Comment: scummvm; Flags: createonlyiffileexists; IconIndex: 0
|
||||||
Name: {group}\Authors; Filename: {app}\AUTHORS.txt; WorkingDir: {app}; Comment: AUTHORS; Flags: createonlyiffileexists
|
Name: {group}\Authors; Filename: {app}\AUTHORS.txt; WorkingDir: {app}; Comment: AUTHORS; Flags: createonlyiffileexists
|
||||||
Name: {group}\Copying; Filename: {app}\COPYING.txt; WorkingDir: {app}; Comment: COPYING; Flags: createonlyiffileexists
|
Name: {group}\Copying; Filename: {app}\COPYING.txt; WorkingDir: {app}; Comment: COPYING; Flags: createonlyiffileexists
|
||||||
Name: {group}\Copying.LGPL; Filename: {app}\COPYING.LGPL.txt; WorkingDir: {app}; Comment: COPYING.LGPL; Flags: createonlyiffileexists
|
Name: {group}\Copying.LGPL; Filename: {app}\COPYING.LGPL.txt; WorkingDir: {app}; Comment: COPYING.LGPL; Flags: createonlyiffileexists
|
||||||
|
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
BIN
dists/win32/plugins/Games.dll
Normal file
BIN
dists/win32/plugins/Games.dll
Normal file
Binary file not shown.
44
dists/win32/scummvm.gdf.xml
Normal file
44
dists/win32/scummvm.gdf.xml
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<GameDefinitionFile xmlns:baseTypes="urn:schemas-microsoft-com:GamesExplorerBaseTypes.v1" xmlns="urn:schemas-microsoft-com:GameDescription.v1">
|
||||||
|
<GameDefinition gameID="{F2475C5C-EA7C-41F0-A56D-1ABF7CFEA389}">
|
||||||
|
<Name>ScummVM</Name>
|
||||||
|
<Description>ScummVM is a program which allows you to run certain classic graphical point-and-click adventure games, provided you already have their data files. The clever part about this: ScummVM just replaces the executables shipped with the games, allowing you to play them on systems for which they were never designed!</Description>
|
||||||
|
<ReleaseDate>2011-09-30</ReleaseDate>
|
||||||
|
<Genres>
|
||||||
|
<Genre>Adventure</Genre>
|
||||||
|
</Genres>
|
||||||
|
<Version>
|
||||||
|
<VersionFile path="scummvm.exe" />
|
||||||
|
</Version>
|
||||||
|
<WindowsSystemPerformanceRating minimum="1.0" recommended="2.0" />
|
||||||
|
<Developers>
|
||||||
|
<Developer URI="http://www.scummvm.org">The ScummVM Team</Developer>
|
||||||
|
</Developers>
|
||||||
|
<Publishers>
|
||||||
|
<Publisher URI="http://www.scummvm.org">The ScummVM Team</Publisher>
|
||||||
|
</Publishers>
|
||||||
|
<GameExecutables>
|
||||||
|
<GameExecutable path="scummvm.exe" />
|
||||||
|
</GameExecutables>
|
||||||
|
<ExtendedProperties>
|
||||||
|
<GameTasks>
|
||||||
|
<Play>
|
||||||
|
<Primary>
|
||||||
|
<FileTask path="scummvm.exe" arguments="--no-console" />
|
||||||
|
</Primary>
|
||||||
|
<Task index="1" name="Play (console)">
|
||||||
|
<FileTask path="scummvm.exe" arguments="" />
|
||||||
|
</Task>
|
||||||
|
</Play>
|
||||||
|
<Support>
|
||||||
|
<Task index="0" name="View README">
|
||||||
|
<FileTask path="README.txt" arguments="" />
|
||||||
|
</Task>
|
||||||
|
<Task index="1" name="ScummVM Website">
|
||||||
|
<URLTask Link="http://www.scummvm.org" />
|
||||||
|
</Task>
|
||||||
|
</Support>
|
||||||
|
</GameTasks>
|
||||||
|
</ExtendedProperties>
|
||||||
|
</GameDefinition>
|
||||||
|
</GameDefinitionFile>
|
|
@ -20,19 +20,26 @@
|
||||||
|
|
||||||
#!define _DEBUG
|
#!define _DEBUG
|
||||||
#!define _INCLUDE_DATA_FILES
|
#!define _INCLUDE_DATA_FILES
|
||||||
|
!define _ENABLE_GAME_EXPLORER
|
||||||
|
#!define _LOG_BUILD
|
||||||
|
!define _CONVERT_TEXT
|
||||||
|
|
||||||
Name ScummVM
|
Name ScummVM
|
||||||
|
|
||||||
# Included files
|
# Included files
|
||||||
!include MUI2.nsh
|
!include MUI2.nsh
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
!ifdef _ENABLE_GAME_EXPLORER
|
||||||
|
!AddPluginDir "./plugins"
|
||||||
|
!endif
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Command line options
|
# Command line options
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
#!define top_srcdir ""
|
#!define top_srcdir ""
|
||||||
#!define build_dir ""
|
#!define staging_dir ""
|
||||||
#!define text_dir ""
|
|
||||||
#!define ARCH "" ;(optional, defaults to win32)
|
#!define ARCH "" ;(optional, defaults to win32)
|
||||||
|
|
||||||
# Check parameters
|
# Check parameters
|
||||||
|
@ -40,17 +47,19 @@ Name ScummVM
|
||||||
!error "Top source folder has not been passed to command line!"
|
!error "Top source folder has not been passed to command line!"
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
!ifndef build_dir
|
!ifndef staging_dir
|
||||||
!error "Build folder has not been passed to command line (this folder should contain the executable and linked DLLs)!"
|
!error "Staging folder has not been passed to command line (this folder should contain the executable and linked DLLs)!"
|
||||||
!endif
|
|
||||||
|
|
||||||
!ifndef text_dir
|
|
||||||
!error "Text folder has not been passed to command line (this folder should contain all the text files used by the installer)!"
|
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
!ifndef ARCH
|
!ifndef ARCH
|
||||||
!warning "ARCH has not been defined, defaulting to 'win32'"
|
!warning "ARCH has not been defined, defaulting to 'win32'"
|
||||||
!define ARCH "win32"
|
!define ARCH "win32"
|
||||||
|
!else
|
||||||
|
!if "${ARCH}" == ""
|
||||||
|
!warning "ARCH was empty, defaulting to 'win32'"
|
||||||
|
!undef ARCH
|
||||||
|
!define ARCH "win32"
|
||||||
|
!endif
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
@ -72,7 +81,7 @@ Name ScummVM
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Installer configuration
|
# Installer configuration
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
OutFile ${build_dir}\scummvm-${VERSION}-${ARCH}.exe
|
OutFile ${staging_dir}\scummvm-${VERSION}-${ARCH}.exe
|
||||||
InstallDir $PROGRAMFILES\ScummVM ; Default installation folder
|
InstallDir $PROGRAMFILES\ScummVM ; Default installation folder
|
||||||
InstallDirRegKey HKCU "Software\ScummVM\ScummVM" "InstallPath" ; Get installation folder from registry if available
|
InstallDirRegKey HKCU "Software\ScummVM\ScummVM" "InstallPath" ; Get installation folder from registry if available
|
||||||
; The application name needs to be refered directly instead of through ${REGKEY}
|
; The application name needs to be refered directly instead of through ${REGKEY}
|
||||||
|
@ -220,17 +229,35 @@ Var StartMenuGroup
|
||||||
# Installer sections
|
# Installer sections
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
Section "ScummVM" SecMain
|
Section "ScummVM" SecMain
|
||||||
|
!ifdef _LOG_BUILD
|
||||||
|
LogSet on
|
||||||
|
!endif
|
||||||
SetOutPath $INSTDIR
|
SetOutPath $INSTDIR
|
||||||
SetOverwrite on
|
SetOverwrite on
|
||||||
|
|
||||||
# Text files
|
# Text files
|
||||||
File /oname=AUTHORS.txt "${text_dir}\AUTHORS"
|
File /oname=AUTHORS.txt "${top_srcdir}\AUTHORS"
|
||||||
File /oname=COPYING.LGPL.txt "${text_dir}\COPYING.LGPL"
|
File /oname=COPYING.LGPL.txt "${top_srcdir}\COPYING.LGPL"
|
||||||
File /oname=COPYING.txt "${text_dir}\COPYING"
|
File /oname=COPYING.txt "${top_srcdir}\COPYING"
|
||||||
File /oname=COPYRIGHT.txt "${text_dir}\COPYRIGHT"
|
File /oname=COPYRIGHT.txt "${top_srcdir}\COPYRIGHT"
|
||||||
File /oname=NEWS.txt "${text_dir}\NEWS"
|
File /oname=NEWS.txt "${top_srcdir}\NEWS"
|
||||||
File /oname=README.txt "${text_dir}\README"
|
File /oname=README.txt "${top_srcdir}\README"
|
||||||
File /oname=README-SDL.txt "${build_dir}\README-SDL"
|
|
||||||
|
!ifdef _CONVERT_TEXT
|
||||||
|
# Convert line endings
|
||||||
|
Push "$INSTDIR\AUTHORS.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\COPYING.LGPL.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\COPYING.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\COPYRIGHT.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\NEWS.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\README.txt"
|
||||||
|
Call unix2dos
|
||||||
|
!endif
|
||||||
|
|
||||||
!ifdef _INCLUDE_DATA_FILES
|
!ifdef _INCLUDE_DATA_FILES
|
||||||
# Engine data
|
# Engine data
|
||||||
|
@ -253,10 +280,27 @@ Section "ScummVM" SecMain
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
# Main exe and dlls
|
# Main exe and dlls
|
||||||
File "${build_dir}\scummvm.exe"
|
File "${staging_dir}\scummvm.exe"
|
||||||
File "${build_dir}\SDL.dll"
|
File "${staging_dir}\SDL.dll"
|
||||||
|
|
||||||
WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder
|
WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder
|
||||||
|
|
||||||
|
#Register with game explorer
|
||||||
|
!ifdef _ENABLE_GAME_EXPLORER
|
||||||
|
Games::registerGame "$INSTDIR\scummvm.exe"
|
||||||
|
pop $0
|
||||||
|
# This is for Vista only, for 7 the tasks are defined in the gdf xml
|
||||||
|
${If} $0 != "0"
|
||||||
|
${AndIf} $0 != ""
|
||||||
|
${AndIf} $0 != "$INSTDIR\scummvm.exe"
|
||||||
|
CreateDirectory "$0\PlayTasks\0"
|
||||||
|
CreateShortcut "$0\PlayTasks\0\Play.lnk" "$INSTDIR\scummvm.exe" "--no-console"
|
||||||
|
CreateDirectory "$0\PlayTasks\1"
|
||||||
|
CreateShortcut "$0\PlayTasks\1\Play (console).lnk" "$INSTDIR\scummvm.exe"
|
||||||
|
CreateDirectory "$0\SupportTasks\0"
|
||||||
|
CreateShortcut "$0\SupportTasks\0\Home Page.lnk" "${URL}"
|
||||||
|
${EndIf}
|
||||||
|
!endif
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
# Write Start menu entries and uninstaller
|
# Write Start menu entries and uninstaller
|
||||||
|
@ -267,6 +311,7 @@ Section -post SecMainPost
|
||||||
SetShellVarContext all ; Create shortcuts in the all-users folder
|
SetShellVarContext all ; Create shortcuts in the all-users folder
|
||||||
CreateDirectory "$SMPROGRAMS\$StartMenuGroup"
|
CreateDirectory "$SMPROGRAMS\$StartMenuGroup"
|
||||||
CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon
|
CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon
|
||||||
|
CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name) (No console).lnk" $INSTDIR\$(^Name).exe "--no-console" "$INSTDIR\$(^Name).exe" 0
|
||||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt
|
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt
|
||||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe
|
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe
|
||||||
!insertmacro MUI_STARTMENU_WRITE_END
|
!insertmacro MUI_STARTMENU_WRITE_END
|
||||||
|
@ -320,6 +365,10 @@ Section -un.Main SecUninstall
|
||||||
Delete /REBOOTOK $INSTDIR\translations.dat
|
Delete /REBOOTOK $INSTDIR\translations.dat
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
!ifdef _ENABLE_GAME_EXPLORER
|
||||||
|
Games::unregisterGame "$INSTDIR\scummvm.exe"
|
||||||
|
!endif
|
||||||
|
|
||||||
Delete /REBOOTOK $INSTDIR\scummvm.exe
|
Delete /REBOOTOK $INSTDIR\scummvm.exe
|
||||||
Delete /REBOOTOK $INSTDIR\SDL.dll
|
Delete /REBOOTOK $INSTDIR\SDL.dll
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
@ -354,3 +403,63 @@ Function un.onInit
|
||||||
ReadRegStr $INSTDIR HKCU "${REGKEY}" InstallPath
|
ReadRegStr $INSTDIR HKCU "${REGKEY}" InstallPath
|
||||||
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
|
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Helper functions
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
!ifdef _CONVERT_TEXT
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; strips all CRs and then converts all LFs into CRLFs
|
||||||
|
; (this is roughly equivalent to "cat file | dos2unix | unix2dos")
|
||||||
|
;
|
||||||
|
; Usage:
|
||||||
|
; Push "infile"
|
||||||
|
; Call unix2dos
|
||||||
|
;
|
||||||
|
; Note: this function destroys $0 $1 $2
|
||||||
|
Function unix2dos
|
||||||
|
ClearErrors
|
||||||
|
|
||||||
|
Pop $2
|
||||||
|
Rename $2 $2.U2D
|
||||||
|
FileOpen $1 $2 w
|
||||||
|
|
||||||
|
FileOpen $0 $2.U2D r
|
||||||
|
|
||||||
|
Push $2 ; save name for deleting
|
||||||
|
|
||||||
|
IfErrors unix2dos_done
|
||||||
|
|
||||||
|
; $0 = file input (opened for reading)
|
||||||
|
; $1 = file output (opened for writing)
|
||||||
|
|
||||||
|
unix2dos_loop:
|
||||||
|
; read a byte (stored in $2)
|
||||||
|
FileReadByte $0 $2
|
||||||
|
IfErrors unix2dos_done ; EOL
|
||||||
|
; skip CR
|
||||||
|
StrCmp $2 13 unix2dos_loop
|
||||||
|
; if LF write an extra CR
|
||||||
|
StrCmp $2 10 unix2dos_cr unix2dos_write
|
||||||
|
|
||||||
|
unix2dos_cr:
|
||||||
|
FileWriteByte $1 13
|
||||||
|
|
||||||
|
unix2dos_write:
|
||||||
|
; write byte
|
||||||
|
FileWriteByte $1 $2
|
||||||
|
; read next byte
|
||||||
|
Goto unix2dos_loop
|
||||||
|
|
||||||
|
unix2dos_done:
|
||||||
|
; close files
|
||||||
|
FileClose $0
|
||||||
|
FileClose $1
|
||||||
|
|
||||||
|
; delete original
|
||||||
|
Pop $0
|
||||||
|
Delete $0.U2D
|
||||||
|
FunctionEnd
|
||||||
|
!endif
|
|
@ -20,19 +20,26 @@
|
||||||
|
|
||||||
#!define _DEBUG
|
#!define _DEBUG
|
||||||
#!define _INCLUDE_DATA_FILES
|
#!define _INCLUDE_DATA_FILES
|
||||||
|
!define _ENABLE_GAME_EXPLORER
|
||||||
|
#!define _LOG_BUILD
|
||||||
|
!define _CONVERT_TEXT
|
||||||
|
|
||||||
Name ScummVM
|
Name ScummVM
|
||||||
|
|
||||||
# Included files
|
# Included files
|
||||||
!include MUI2.nsh
|
!include MUI2.nsh
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
!ifdef _ENABLE_GAME_EXPLORER
|
||||||
|
!AddPluginDir "./plugins"
|
||||||
|
!endif
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Command line options
|
# Command line options
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|
||||||
#!define top_srcdir ""
|
#!define top_srcdir ""
|
||||||
#!define build_dir ""
|
#!define staging_dir ""
|
||||||
#!define text_dir ""
|
|
||||||
#!define ARCH "" ;(optional, defaults to win32)
|
#!define ARCH "" ;(optional, defaults to win32)
|
||||||
|
|
||||||
# Check parameters
|
# Check parameters
|
||||||
|
@ -40,17 +47,19 @@ Name ScummVM
|
||||||
!error "Top source folder has not been passed to command line!"
|
!error "Top source folder has not been passed to command line!"
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
!ifndef build_dir
|
!ifndef staging_dir
|
||||||
!error "Build folder has not been passed to command line (this folder should contain the executable and linked DLLs)!"
|
!error "Staging folder has not been passed to command line (this folder should contain the executable and linked DLLs)!"
|
||||||
!endif
|
|
||||||
|
|
||||||
!ifndef text_dir
|
|
||||||
!error "Text folder has not been passed to command line (this folder should contain all the text files used by the installer)!"
|
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
!ifndef ARCH
|
!ifndef ARCH
|
||||||
!warning "ARCH has not been defined, defaulting to 'win32'"
|
!warning "ARCH has not been defined, defaulting to 'win32'"
|
||||||
!define ARCH "win32"
|
!define ARCH "win32"
|
||||||
|
!else
|
||||||
|
!if "${ARCH}" == ""
|
||||||
|
!warning "ARCH was empty, defaulting to 'win32'"
|
||||||
|
!undef ARCH
|
||||||
|
!define ARCH "win32"
|
||||||
|
!endif
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
@ -72,7 +81,7 @@ Name ScummVM
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# Installer configuration
|
# Installer configuration
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
OutFile ${build_dir}\scummvm-${VERSION}-${ARCH}.exe
|
OutFile ${staging_dir}\scummvm-${VERSION}-${ARCH}.exe
|
||||||
InstallDir $PROGRAMFILES\ScummVM ; Default installation folder
|
InstallDir $PROGRAMFILES\ScummVM ; Default installation folder
|
||||||
InstallDirRegKey HKCU "Software\ScummVM\ScummVM" "InstallPath" ; Get installation folder from registry if available
|
InstallDirRegKey HKCU "Software\ScummVM\ScummVM" "InstallPath" ; Get installation folder from registry if available
|
||||||
; The application name needs to be refered directly instead of through ${REGKEY}
|
; The application name needs to be refered directly instead of through ${REGKEY}
|
||||||
|
@ -220,17 +229,35 @@ Var StartMenuGroup
|
||||||
# Installer sections
|
# Installer sections
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
Section "ScummVM" SecMain
|
Section "ScummVM" SecMain
|
||||||
|
!ifdef _LOG_BUILD
|
||||||
|
LogSet on
|
||||||
|
!endif
|
||||||
SetOutPath $INSTDIR
|
SetOutPath $INSTDIR
|
||||||
SetOverwrite on
|
SetOverwrite on
|
||||||
|
|
||||||
# Text files
|
# Text files
|
||||||
File /oname=AUTHORS.txt "${text_dir}\AUTHORS"
|
File /oname=AUTHORS.txt "${top_srcdir}\AUTHORS"
|
||||||
File /oname=COPYING.LGPL.txt "${text_dir}\COPYING.LGPL"
|
File /oname=COPYING.LGPL.txt "${top_srcdir}\COPYING.LGPL"
|
||||||
File /oname=COPYING.txt "${text_dir}\COPYING"
|
File /oname=COPYING.txt "${top_srcdir}\COPYING"
|
||||||
File /oname=COPYRIGHT.txt "${text_dir}\COPYRIGHT"
|
File /oname=COPYRIGHT.txt "${top_srcdir}\COPYRIGHT"
|
||||||
File /oname=NEWS.txt "${text_dir}\NEWS"
|
File /oname=NEWS.txt "${top_srcdir}\NEWS"
|
||||||
File /oname=README.txt "${text_dir}\README"
|
File /oname=README.txt "${top_srcdir}\README"
|
||||||
File /oname=README-SDL.txt "${build_dir}\README-SDL"
|
|
||||||
|
!ifdef _CONVERT_TEXT
|
||||||
|
# Convert line endings
|
||||||
|
Push "$INSTDIR\AUTHORS.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\COPYING.LGPL.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\COPYING.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\COPYRIGHT.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\NEWS.txt"
|
||||||
|
Call unix2dos
|
||||||
|
Push "$INSTDIR\README.txt"
|
||||||
|
Call unix2dos
|
||||||
|
!endif
|
||||||
|
|
||||||
!ifdef _INCLUDE_DATA_FILES
|
!ifdef _INCLUDE_DATA_FILES
|
||||||
# Engine data
|
# Engine data
|
||||||
|
@ -253,10 +280,27 @@ Section "ScummVM" SecMain
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
# Main exe and dlls
|
# Main exe and dlls
|
||||||
File "${build_dir}\scummvm.exe"
|
File "${staging_dir}\scummvm.exe"
|
||||||
File "${build_dir}\SDL.dll"
|
File "${staging_dir}\SDL.dll"
|
||||||
|
|
||||||
WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder
|
WriteRegStr HKCU "${REGKEY}" InstallPath "$INSTDIR" ; Store installation folder
|
||||||
|
|
||||||
|
#Register with game explorer
|
||||||
|
!ifdef _ENABLE_GAME_EXPLORER
|
||||||
|
Games::registerGame "$INSTDIR\scummvm.exe"
|
||||||
|
pop $0
|
||||||
|
# This is for Vista only, for 7 the tasks are defined in the gdf xml
|
||||||
|
${If} $0 != "0"
|
||||||
|
${AndIf} $0 != ""
|
||||||
|
${AndIf} $0 != "$INSTDIR\scummvm.exe"
|
||||||
|
CreateDirectory "$0\PlayTasks\0"
|
||||||
|
CreateShortcut "$0\PlayTasks\0\Play.lnk" "$INSTDIR\scummvm.exe" "--no-console"
|
||||||
|
CreateDirectory "$0\PlayTasks\1"
|
||||||
|
CreateShortcut "$0\PlayTasks\1\Play (console).lnk" "$INSTDIR\scummvm.exe"
|
||||||
|
CreateDirectory "$0\SupportTasks\0"
|
||||||
|
CreateShortcut "$0\SupportTasks\0\Home Page.lnk" "${URL}"
|
||||||
|
${EndIf}
|
||||||
|
!endif
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
# Write Start menu entries and uninstaller
|
# Write Start menu entries and uninstaller
|
||||||
|
@ -267,6 +311,7 @@ Section -post SecMainPost
|
||||||
SetShellVarContext all ; Create shortcuts in the all-users folder
|
SetShellVarContext all ; Create shortcuts in the all-users folder
|
||||||
CreateDirectory "$SMPROGRAMS\$StartMenuGroup"
|
CreateDirectory "$SMPROGRAMS\$StartMenuGroup"
|
||||||
CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon
|
CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name).lnk" $INSTDIR\$(^Name).exe "" "$INSTDIR\$(^Name).exe" 0 ; Create shortcut with icon
|
||||||
|
CreateShortCut "$SMPROGRAMS\$StartMenuGroup\$(^Name) (No console).lnk" $INSTDIR\$(^Name).exe "--no-console" "$INSTDIR\$(^Name).exe" 0
|
||||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt
|
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Readme.lnk" $INSTDIR\README.txt
|
||||||
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe
|
CreateShortcut "$SMPROGRAMS\$StartMenuGroup\Uninstall $(^Name).lnk" $INSTDIR\uninstall.exe
|
||||||
!insertmacro MUI_STARTMENU_WRITE_END
|
!insertmacro MUI_STARTMENU_WRITE_END
|
||||||
|
@ -320,6 +365,10 @@ Section -un.Main SecUninstall
|
||||||
Delete /REBOOTOK $INSTDIR\translations.dat
|
Delete /REBOOTOK $INSTDIR\translations.dat
|
||||||
!endif
|
!endif
|
||||||
|
|
||||||
|
!ifdef _ENABLE_GAME_EXPLORER
|
||||||
|
Games::unregisterGame "$INSTDIR\scummvm.exe"
|
||||||
|
!endif
|
||||||
|
|
||||||
Delete /REBOOTOK $INSTDIR\scummvm.exe
|
Delete /REBOOTOK $INSTDIR\scummvm.exe
|
||||||
Delete /REBOOTOK $INSTDIR\SDL.dll
|
Delete /REBOOTOK $INSTDIR\SDL.dll
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
@ -354,3 +403,63 @@ Function un.onInit
|
||||||
ReadRegStr $INSTDIR HKCU "${REGKEY}" InstallPath
|
ReadRegStr $INSTDIR HKCU "${REGKEY}" InstallPath
|
||||||
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
|
!insertmacro MUI_STARTMENU_GETFOLDER Application $StartMenuGroup
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# Helper functions
|
||||||
|
#########################################################################################
|
||||||
|
|
||||||
|
!ifdef _CONVERT_TEXT
|
||||||
|
;-------------------------------------------------------------------------------
|
||||||
|
; strips all CRs and then converts all LFs into CRLFs
|
||||||
|
; (this is roughly equivalent to "cat file | dos2unix | unix2dos")
|
||||||
|
;
|
||||||
|
; Usage:
|
||||||
|
; Push "infile"
|
||||||
|
; Call unix2dos
|
||||||
|
;
|
||||||
|
; Note: this function destroys $0 $1 $2
|
||||||
|
Function unix2dos
|
||||||
|
ClearErrors
|
||||||
|
|
||||||
|
Pop $2
|
||||||
|
Rename $2 $2.U2D
|
||||||
|
FileOpen $1 $2 w
|
||||||
|
|
||||||
|
FileOpen $0 $2.U2D r
|
||||||
|
|
||||||
|
Push $2 ; save name for deleting
|
||||||
|
|
||||||
|
IfErrors unix2dos_done
|
||||||
|
|
||||||
|
; $0 = file input (opened for reading)
|
||||||
|
; $1 = file output (opened for writing)
|
||||||
|
|
||||||
|
unix2dos_loop:
|
||||||
|
; read a byte (stored in $2)
|
||||||
|
FileReadByte $0 $2
|
||||||
|
IfErrors unix2dos_done ; EOL
|
||||||
|
; skip CR
|
||||||
|
StrCmp $2 13 unix2dos_loop
|
||||||
|
; if LF write an extra CR
|
||||||
|
StrCmp $2 10 unix2dos_cr unix2dos_write
|
||||||
|
|
||||||
|
unix2dos_cr:
|
||||||
|
FileWriteByte $1 13
|
||||||
|
|
||||||
|
unix2dos_write:
|
||||||
|
; write byte
|
||||||
|
FileWriteByte $1 $2
|
||||||
|
; read next byte
|
||||||
|
Goto unix2dos_loop
|
||||||
|
|
||||||
|
unix2dos_done:
|
||||||
|
; close files
|
||||||
|
FileClose $0
|
||||||
|
FileClose $1
|
||||||
|
|
||||||
|
; delete original
|
||||||
|
Pop $0
|
||||||
|
Delete $0.U2D
|
||||||
|
FunctionEnd
|
||||||
|
!endif
|
|
@ -86,27 +86,30 @@ void Winnie::parseObjHeader(WTP_OBJ_HDR *objHdr, byte *buffer, int len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
|
uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
|
||||||
char szFile[256] = {0};
|
Common::String fileName;
|
||||||
|
|
||||||
if (_vm->getPlatform() == Common::kPlatformPC)
|
if (_vm->getPlatform() == Common::kPlatformPC)
|
||||||
sprintf(szFile, IDS_WTP_ROOM_DOS, iRoom);
|
fileName = Common::String::format(IDS_WTP_ROOM_DOS, iRoom);
|
||||||
else if (_vm->getPlatform() == Common::kPlatformAmiga)
|
else if (_vm->getPlatform() == Common::kPlatformAmiga)
|
||||||
sprintf(szFile, IDS_WTP_ROOM_AMIGA, iRoom);
|
fileName = Common::String::format(IDS_WTP_ROOM_AMIGA, iRoom);
|
||||||
else if (_vm->getPlatform() == Common::kPlatformC64)
|
else if (_vm->getPlatform() == Common::kPlatformC64)
|
||||||
sprintf(szFile, IDS_WTP_ROOM_C64, iRoom);
|
fileName = Common::String::format(IDS_WTP_ROOM_C64, iRoom);
|
||||||
else if (_vm->getPlatform() == Common::kPlatformApple2GS)
|
else if (_vm->getPlatform() == Common::kPlatformApple2GS)
|
||||||
sprintf(szFile, IDS_WTP_ROOM_APPLE, iRoom);
|
fileName = Common::String::format(IDS_WTP_ROOM_APPLE, iRoom);
|
||||||
|
|
||||||
Common::File file;
|
Common::File file;
|
||||||
if (!file.open(szFile)) {
|
if (!file.open(fileName)) {
|
||||||
warning ("Could not open file \'%s\'", szFile);
|
warning("Could not open file \'%s\'", fileName.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 filelen = file.size();
|
uint32 filelen = file.size();
|
||||||
if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
|
if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
|
||||||
filelen -= 2;
|
filelen -= 2;
|
||||||
file.seek(2, SEEK_CUR);
|
file.seek(2, SEEK_CUR);
|
||||||
}
|
}
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
|
memset(buffer, 0, 4096);
|
||||||
file.read(buffer, filelen);
|
file.read(buffer, filelen);
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
@ -116,26 +119,30 @@ uint32 Winnie::readRoom(int iRoom, uint8 *buffer, WTP_ROOM_HDR &roomHdr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Winnie::readObj(int iObj, uint8 *buffer) {
|
uint32 Winnie::readObj(int iObj, uint8 *buffer) {
|
||||||
char szFile[256] = {0};
|
Common::String fileName;
|
||||||
|
|
||||||
if (_vm->getPlatform() == Common::kPlatformPC)
|
if (_vm->getPlatform() == Common::kPlatformPC)
|
||||||
sprintf(szFile, IDS_WTP_OBJ_DOS, iObj);
|
fileName = Common::String::format(IDS_WTP_OBJ_DOS, iObj);
|
||||||
else if (_vm->getPlatform() == Common::kPlatformAmiga)
|
else if (_vm->getPlatform() == Common::kPlatformAmiga)
|
||||||
sprintf(szFile, IDS_WTP_OBJ_AMIGA, iObj);
|
fileName = Common::String::format(IDS_WTP_OBJ_AMIGA, iObj);
|
||||||
else if (_vm->getPlatform() == Common::kPlatformC64)
|
else if (_vm->getPlatform() == Common::kPlatformC64)
|
||||||
sprintf(szFile, IDS_WTP_OBJ_C64, iObj);
|
fileName = Common::String::format(IDS_WTP_OBJ_C64, iObj);
|
||||||
else if (_vm->getPlatform() == Common::kPlatformApple2GS)
|
else if (_vm->getPlatform() == Common::kPlatformApple2GS)
|
||||||
sprintf(szFile, IDS_WTP_OBJ_APPLE, iObj);
|
fileName = Common::String::format(IDS_WTP_OBJ_APPLE, iObj);
|
||||||
|
|
||||||
Common::File file;
|
Common::File file;
|
||||||
if (!file.open(szFile)) {
|
if (!file.open(fileName)) {
|
||||||
warning ("Could not open file \'%s\'", szFile);
|
warning ("Could not open file \'%s\'", fileName.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 filelen = file.size();
|
uint32 filelen = file.size();
|
||||||
if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
|
if (_vm->getPlatform() == Common::kPlatformC64) { // Skip the loading address
|
||||||
filelen -= 2;
|
filelen -= 2;
|
||||||
file.seek(2, SEEK_CUR);
|
file.seek(2, SEEK_CUR);
|
||||||
}
|
}
|
||||||
memset(buffer, 0, sizeof(buffer));
|
|
||||||
|
memset(buffer, 0, 2048);
|
||||||
file.read(buffer, filelen);
|
file.read(buffer, filelen);
|
||||||
file.close();
|
file.close();
|
||||||
return filelen;
|
return filelen;
|
||||||
|
@ -461,8 +468,6 @@ void Winnie::keyHelp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Winnie::inventory() {
|
void Winnie::inventory() {
|
||||||
char szMissing[41] = {0};
|
|
||||||
|
|
||||||
if (_game.iObjHave)
|
if (_game.iObjHave)
|
||||||
printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE);
|
printObjStr(_game.iObjHave, IDI_WTP_OBJ_TAKE);
|
||||||
else {
|
else {
|
||||||
|
@ -470,8 +475,9 @@ void Winnie::inventory() {
|
||||||
_vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0);
|
_vm->drawStr(IDI_WTP_ROW_MENU, IDI_WTP_COL_MENU, IDA_DEFAULT, IDS_WTP_INVENTORY_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(szMissing, IDS_WTP_INVENTORY_1, _game.nObjMiss);
|
Common::String missing = Common::String::format(IDS_WTP_INVENTORY_1, _game.nObjMiss);
|
||||||
_vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, szMissing);
|
|
||||||
|
_vm->drawStr(IDI_WTP_ROW_OPTION_4, IDI_WTP_COL_MENU, IDA_DEFAULT, missing.c_str());
|
||||||
_vm->_gfx->doUpdate();
|
_vm->_gfx->doUpdate();
|
||||||
_vm->_system->updateScreen(); //TODO: Move to game's main loop
|
_vm->_system->updateScreen(); //TODO: Move to game's main loop
|
||||||
_vm->getSelection(kSelAnyKey);
|
_vm->getSelection(kSelAnyKey);
|
||||||
|
@ -1042,16 +1048,15 @@ phase2:
|
||||||
}
|
}
|
||||||
|
|
||||||
void Winnie::drawPic(const char *szName) {
|
void Winnie::drawPic(const char *szName) {
|
||||||
char szFile[256] = {0};
|
Common::String fileName = szName;
|
||||||
|
|
||||||
|
if (_vm->getPlatform() != Common::kPlatformAmiga)
|
||||||
|
fileName += ".pic";
|
||||||
|
|
||||||
Common::File file;
|
Common::File file;
|
||||||
|
|
||||||
// construct filename
|
if (!file.open(fileName)) {
|
||||||
if (_vm->getPlatform() != Common::kPlatformAmiga)
|
warning ("Could not open file \'%s\'", fileName.c_str());
|
||||||
sprintf(szFile, "%s.pic", szName);
|
|
||||||
else
|
|
||||||
strcpy(szFile, szName);
|
|
||||||
if (!file.open(szFile)) {
|
|
||||||
warning ("Could not open file \'%s\'", szFile);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,12 +1147,11 @@ void Winnie::gameOver() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Winnie::saveGame() {
|
void Winnie::saveGame() {
|
||||||
Common::OutSaveFile* outfile;
|
|
||||||
char szFile[256] = {0};
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
sprintf(szFile, IDS_WTP_FILE_SAVEGAME);
|
Common::OutSaveFile *outfile = _vm->getSaveFileMan()->openForSaving(IDS_WTP_FILE_SAVEGAME);
|
||||||
if (!(outfile = _vm->getSaveFileMan()->openForSaving(szFile)))
|
|
||||||
|
if (!outfile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
outfile->writeUint32BE(MKTAG('W','I','N','N')); // header
|
outfile->writeUint32BE(MKTAG('W','I','N','N')); // header
|
||||||
|
@ -1171,19 +1175,18 @@ void Winnie::saveGame() {
|
||||||
outfile->finalize();
|
outfile->finalize();
|
||||||
|
|
||||||
if (outfile->err())
|
if (outfile->err())
|
||||||
warning("Can't write file '%s'. (Disk full?)", szFile);
|
warning("Can't write file '%s'. (Disk full?)", IDS_WTP_FILE_SAVEGAME);
|
||||||
|
|
||||||
delete outfile;
|
delete outfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Winnie::loadGame() {
|
void Winnie::loadGame() {
|
||||||
Common::InSaveFile* infile;
|
|
||||||
char szFile[256] = {0};
|
|
||||||
int saveVersion = 0;
|
int saveVersion = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
sprintf(szFile, IDS_WTP_FILE_SAVEGAME);
|
Common::InSaveFile *infile = _vm->getSaveFileMan()->openForLoading(IDS_WTP_FILE_SAVEGAME);
|
||||||
if (!(infile = _vm->getSaveFileMan()->openForLoading(szFile)))
|
|
||||||
|
if (!infile)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (infile->readUint32BE() == MKTAG('W','I','N','N')) {
|
if (infile->readUint32BE() == MKTAG('W','I','N','N')) {
|
||||||
|
|
|
@ -688,8 +688,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
|
||||||
int16 di;
|
int16 di;
|
||||||
uint16 j;
|
uint16 j;
|
||||||
int16 mouseX, mouseY;
|
int16 mouseX, mouseY;
|
||||||
int16 var_16;
|
|
||||||
int16 var_14;
|
|
||||||
int16 currentSelection, oldSelection;
|
int16 currentSelection, oldSelection;
|
||||||
int16 var_4;
|
int16 var_4;
|
||||||
SelectionMenu *menu;
|
SelectionMenu *menu;
|
||||||
|
@ -731,9 +729,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X,
|
||||||
manageEvents();
|
manageEvents();
|
||||||
getMouseData(mouseUpdateStatus, &button, (uint16 *)&mouseX, (uint16 *)&mouseY);
|
getMouseData(mouseUpdateStatus, &button, (uint16 *)&mouseX, (uint16 *)&mouseY);
|
||||||
|
|
||||||
var_16 = mouseX;
|
|
||||||
var_14 = mouseY;
|
|
||||||
|
|
||||||
menuVar = 0;
|
menuVar = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
|
@ -902,18 +902,8 @@ bool createDialog(int objOvl, int objIdx, int x, int y) {
|
||||||
if (!obj2Ovl) obj2Ovl = j;
|
if (!obj2Ovl) obj2Ovl = j;
|
||||||
|
|
||||||
char verbe_name[80];
|
char verbe_name[80];
|
||||||
char obj1_name[80];
|
|
||||||
char obj2_name[80];
|
|
||||||
char r_verbe_name[80];
|
|
||||||
char r_obj1_name[80];
|
|
||||||
char r_obj2_name[80];
|
|
||||||
|
|
||||||
verbe_name[0] = 0;
|
verbe_name[0] = 0;
|
||||||
obj1_name[0] = 0;
|
|
||||||
obj2_name[0] = 0;
|
|
||||||
r_verbe_name[0] = 0;
|
|
||||||
r_obj1_name[0] = 0;
|
|
||||||
r_obj2_name[0] = 0;
|
|
||||||
|
|
||||||
ovlDataStruct *ovl2 = NULL;
|
ovlDataStruct *ovl2 = NULL;
|
||||||
ovlDataStruct *ovl3 = NULL;
|
ovlDataStruct *ovl3 = NULL;
|
||||||
|
|
|
@ -440,7 +440,6 @@ void buildSegment() {
|
||||||
|
|
||||||
// is segment on screen ?
|
// is segment on screen ?
|
||||||
if (!((tempAX > 199) || (tempDX < 0))) {
|
if (!((tempAX > 199) || (tempDX < 0))) {
|
||||||
int dx = Y1;
|
|
||||||
int cx = X2 - X1;
|
int cx = X2 - X1;
|
||||||
if (cx == 0) {
|
if (cx == 0) {
|
||||||
// vertical line
|
// vertical line
|
||||||
|
@ -473,7 +472,6 @@ void buildSegment() {
|
||||||
} else {
|
} else {
|
||||||
if (cx < 0) {
|
if (cx < 0) {
|
||||||
cx = -cx;
|
cx = -cx;
|
||||||
dx = Y2;
|
|
||||||
|
|
||||||
SWAP(X1, X2);
|
SWAP(X1, X2);
|
||||||
SWAP(Y1, Y2);
|
SWAP(Y1, Y2);
|
||||||
|
@ -1490,9 +1488,6 @@ void mainDraw(int16 param) {
|
||||||
if (currentObjPtr->animLoop > 0)
|
if (currentObjPtr->animLoop > 0)
|
||||||
currentObjPtr->animLoop--;
|
currentObjPtr->animLoop--;
|
||||||
} else {
|
} else {
|
||||||
int16 data2;
|
|
||||||
data2 = currentObjPtr->animStart;
|
|
||||||
|
|
||||||
change = false;
|
change = false;
|
||||||
currentObjPtr->animStep = 0;
|
currentObjPtr->animStep = 0;
|
||||||
|
|
||||||
|
@ -1512,9 +1507,6 @@ void mainDraw(int16 param) {
|
||||||
if (currentObjPtr->animLoop > 0)
|
if (currentObjPtr->animLoop > 0)
|
||||||
currentObjPtr->animLoop--;
|
currentObjPtr->animLoop--;
|
||||||
} else {
|
} else {
|
||||||
int16 data2;
|
|
||||||
data2 = currentObjPtr->animStart;
|
|
||||||
|
|
||||||
change = false;
|
change = false;
|
||||||
currentObjPtr->animStep = 0;
|
currentObjPtr->animStep = 0;
|
||||||
|
|
||||||
|
|
|
@ -231,9 +231,7 @@ int32 opcodeType2() {
|
||||||
int type = getByteFromScript();
|
int type = getByteFromScript();
|
||||||
int overlay = getByteFromScript();
|
int overlay = getByteFromScript();
|
||||||
|
|
||||||
int firstOffset;
|
int offset = getShortFromScript();
|
||||||
int offset;
|
|
||||||
firstOffset = offset = getShortFromScript();
|
|
||||||
offset += index;
|
offset += index;
|
||||||
|
|
||||||
int typ7 = type & 7;
|
int typ7 = type & 7;
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
AdvancedMetaEngine(DreamWeb::gameDescriptions,
|
AdvancedMetaEngine(DreamWeb::gameDescriptions,
|
||||||
sizeof(DreamWeb::DreamWebGameDescription), dreamWebGames) {
|
sizeof(DreamWeb::DreamWebGameDescription), dreamWebGames) {
|
||||||
_singleid = "dreamweb";
|
_singleid = "dreamweb";
|
||||||
_guioptions = Common::GUIO_NOMIDI;
|
_guioptions = Common::GUIO_NOMIDI | Common::GUIO_NOLAUNCHLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const char *getName() const {
|
virtual const char *getName() const {
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace DreamWeb {
|
||||||
using Common::GUIO_NONE;
|
using Common::GUIO_NONE;
|
||||||
|
|
||||||
static const DreamWebGameDescription gameDescriptions[] = {
|
static const DreamWebGameDescription gameDescriptions[] = {
|
||||||
|
// International floppy release
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
"dreamweb",
|
"dreamweb",
|
||||||
|
@ -81,6 +82,23 @@ static const DreamWebGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// French CD release
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"dreamweb",
|
||||||
|
"CD",
|
||||||
|
{
|
||||||
|
{"dreamwfr.r00", 0, "e354582a8564faf5c515df92f207e8d1", 154657},
|
||||||
|
{"dreamwfr.r02", 0, "57f3f08d5aefd04184eac76927eced80", 200575},
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::FR_FRA,
|
||||||
|
Common::kPlatformPC,
|
||||||
|
ADGF_CD | ADGF_UNSTABLE,
|
||||||
|
GUIO_NONE
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// German floppy release
|
// German floppy release
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -132,6 +150,23 @@ static const DreamWebGameDescription gameDescriptions[] = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Spanish CD release
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"dreamweb",
|
||||||
|
"CD",
|
||||||
|
{
|
||||||
|
{"dreamwsp.r00", 0, "2df07174321de39c4f17c9ff654b268a", 153608},
|
||||||
|
{"dreamwsp.r02", 0, "577d435ad5da08fb1bcf6ea3dd6e0b9e", 199499},
|
||||||
|
AD_LISTEND
|
||||||
|
},
|
||||||
|
Common::ES_ESP,
|
||||||
|
Common::kPlatformPC,
|
||||||
|
ADGF_CD | ADGF_UNSTABLE,
|
||||||
|
GUIO_NONE
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
// Italian floppy release
|
// Italian floppy release
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -410,7 +410,7 @@ void Engine::openMainMenuDialog() {
|
||||||
// value, which is quite bad since it could
|
// value, which is quite bad since it could
|
||||||
// be a fatal loading error, which renders
|
// be a fatal loading error, which renders
|
||||||
// the engine unusable.
|
// the engine unusable.
|
||||||
if (_saveSlotToLoad > 0)
|
if (_saveSlotToLoad >= 0)
|
||||||
loadGameState(_saveSlotToLoad);
|
loadGameState(_saveSlotToLoad);
|
||||||
|
|
||||||
syncSoundSettings();
|
syncSoundSettings();
|
||||||
|
|
|
@ -102,7 +102,7 @@ Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int s
|
||||||
// Fill the SaveStateDescriptor if it was provided
|
// Fill the SaveStateDescriptor if it was provided
|
||||||
if (descriptor) {
|
if (descriptor) {
|
||||||
// Initialize the SaveStateDescriptor
|
// Initialize the SaveStateDescriptor
|
||||||
descriptor->setVal("save_slot", Common::String('0' + slot));
|
descriptor->setSaveSlot(slot);
|
||||||
descriptor->setDeletableFlag(true);
|
descriptor->setDeletableFlag(true);
|
||||||
descriptor->setWriteProtectedFlag(false);
|
descriptor->setWriteProtectedFlag(false);
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ Common::InSaveFile *SaveLoad::openForLoading(const Common::String &target, int s
|
||||||
description += c;
|
description += c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
descriptor->setVal("description", description);
|
descriptor->setDescription(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a substream, skipping the metadata
|
// Return a substream, skipping the metadata
|
||||||
|
|
|
@ -1350,15 +1350,15 @@ void Script::o_checkvalidsaves() {
|
||||||
uint count = 0;
|
uint count = 0;
|
||||||
SaveStateList::iterator it = list.begin();
|
SaveStateList::iterator it = list.begin();
|
||||||
while (it != list.end()) {
|
while (it != list.end()) {
|
||||||
int8 slot = it->getVal("save_slot").lastChar() - '0';
|
int8 slot = it->getSaveSlot();
|
||||||
if (SaveLoad::isSlotValid(slot)) {
|
if (SaveLoad::isSlotValid(slot)) {
|
||||||
debugScript(2, true, " Found valid savegame: %s", it->getVal("description").c_str());
|
debugScript(2, true, " Found valid savegame: %s", it->getDescription().c_str());
|
||||||
|
|
||||||
// Mark this slot as used
|
// Mark this slot as used
|
||||||
setVariable(slot, 1);
|
setVariable(slot, 1);
|
||||||
|
|
||||||
// Cache this slot's description
|
// Cache this slot's description
|
||||||
_saveNames[slot] = it->getVal("description");
|
_saveNames[slot] = it->getDescription();
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
it++;
|
it++;
|
||||||
|
|
|
@ -71,7 +71,7 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm->game() != GI_KYRA1 && _vm->resource()->getFileSize(argv[1]) != 768) {
|
if (_vm->game() != GI_KYRA1 && _vm->resource()->getFileSize(argv[1]) != 768) {
|
||||||
uint8 *buffer = (uint8 *)malloc(320 * 200 * sizeof(uint8));
|
uint8 *buffer = new uint8[320 * 200 * sizeof(uint8)];
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
DebugPrintf("ERROR: Cannot allocate buffer for screen region!\n");
|
DebugPrintf("ERROR: Cannot allocate buffer for screen region!\n");
|
||||||
return true;
|
return true;
|
||||||
|
@ -82,7 +82,7 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) {
|
||||||
palette.copy(_vm->screen()->getCPagePtr(5), 0, 256);
|
palette.copy(_vm->screen()->getCPagePtr(5), 0, 256);
|
||||||
_vm->screen()->copyBlockToPage(5, 0, 0, 320, 200, buffer);
|
_vm->screen()->copyBlockToPage(5, 0, 0, 320, 200, buffer);
|
||||||
|
|
||||||
free(buffer);
|
delete[] buffer;
|
||||||
} else if (!_vm->screen()->loadPalette(argv[1], palette)) {
|
} else if (!_vm->screen()->loadPalette(argv[1], palette)) {
|
||||||
DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]);
|
DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -576,6 +576,15 @@ void GUI_LoK::setupSavegames(Menu &menu, int num) {
|
||||||
if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) {
|
if ((in = _vm->openSaveForReading(_vm->getSavegameFilename(_saveSlots[i + _savegameOffset]), header))) {
|
||||||
Common::strlcpy(_savegameNames[i], header.description.c_str(), ARRAYSIZE(_savegameNames[0]));
|
Common::strlcpy(_savegameNames[i], header.description.c_str(), ARRAYSIZE(_savegameNames[0]));
|
||||||
|
|
||||||
|
// Trim long GMM save descriptions to fit our save slots
|
||||||
|
_screen->_charWidth = -2;
|
||||||
|
int fC = _screen->getTextWidth(_savegameNames[i]);
|
||||||
|
while (_savegameNames[i][0] && (fC > 240 )) {
|
||||||
|
_savegameNames[i][strlen(_savegameNames[i]) - 1] = 0;
|
||||||
|
fC = _screen->getTextWidth(_savegameNames[i]);
|
||||||
|
}
|
||||||
|
_screen->_charWidth = 0;
|
||||||
|
|
||||||
Util::convertISOToDOS(_savegameNames[i]);
|
Util::convertISOToDOS(_savegameNames[i]);
|
||||||
|
|
||||||
menu.item[i].itemString = _savegameNames[i];
|
menu.item[i].itemString = _savegameNames[i];
|
||||||
|
@ -693,12 +702,15 @@ void GUI_LoK::updateSavegameString() {
|
||||||
|
|
||||||
if (_keyPressed.keycode) {
|
if (_keyPressed.keycode) {
|
||||||
length = strlen(_savegameName);
|
length = strlen(_savegameName);
|
||||||
|
_screen->_charWidth = -2;
|
||||||
|
int width = _screen->getTextWidth(_savegameName) + 7;
|
||||||
|
_screen->_charWidth = 0;
|
||||||
|
|
||||||
char inputKey = _keyPressed.ascii;
|
char inputKey = _keyPressed.ascii;
|
||||||
Util::convertISOToDOS(inputKey);
|
Util::convertISOToDOS(inputKey);
|
||||||
|
|
||||||
if ((uint8)inputKey > 31 && (uint8)inputKey < (_vm->gameFlags().lang == Common::JA_JPN ? 128 : 226)) {
|
if ((uint8)inputKey > 31 && (uint8)inputKey < (_vm->gameFlags().lang == Common::JA_JPN ? 128 : 226)) {
|
||||||
if (length < ARRAYSIZE(_savegameName)-1) {
|
if ((length < ARRAYSIZE(_savegameName)-1) && (width <= 240)) {
|
||||||
_savegameName[length] = inputKey;
|
_savegameName[length] = inputKey;
|
||||||
_savegameName[length+1] = 0;
|
_savegameName[length+1] = 0;
|
||||||
redrawTextfield();
|
redrawTextfield();
|
||||||
|
|
|
@ -2572,9 +2572,19 @@ void GUI_LoL::setupSaveMenuSlots(Menu &menu, int num) {
|
||||||
slotOffs = 1;
|
slotOffs = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int saveSlotMaxLen = ((_screen->getScreenDim(8))->w << 3) - _screen->getCharWidth('W');
|
||||||
|
|
||||||
for (int i = startSlot; i < num && _savegameOffset + i - slotOffs < _savegameListSize; ++i) {
|
for (int i = startSlot; i < num && _savegameOffset + i - slotOffs < _savegameListSize; ++i) {
|
||||||
if (_savegameList[_saveSlots[i + _savegameOffset - slotOffs]]) {
|
if (_savegameList[_saveSlots[i + _savegameOffset - slotOffs]]) {
|
||||||
Common::strlcpy(s, _savegameList[_saveSlots[i + _savegameOffset - slotOffs]], 80);
|
Common::strlcpy(s, _savegameList[_saveSlots[i + _savegameOffset - slotOffs]], 80);
|
||||||
|
|
||||||
|
// Trim long GMM save descriptions to fit our save slots
|
||||||
|
int fC = _screen->getTextWidth(s);
|
||||||
|
while (s[0] && fC >= saveSlotMaxLen) {
|
||||||
|
s[strlen(s) - 1] = 0;
|
||||||
|
fC = _screen->getTextWidth(s);
|
||||||
|
}
|
||||||
|
|
||||||
menu.item[i].itemString = s;
|
menu.item[i].itemString = s;
|
||||||
s += (strlen(s) + 1);
|
s += (strlen(s) + 1);
|
||||||
menu.item[i].saveSlot = _saveSlots[i + _savegameOffset - slotOffs];
|
menu.item[i].saveSlot = _saveSlots[i + _savegameOffset - slotOffs];
|
||||||
|
|
|
@ -457,6 +457,15 @@ void GUI_v2::setupSavegameNames(Menu &menu, int num) {
|
||||||
Common::strlcpy(s, header.description.c_str(), 80);
|
Common::strlcpy(s, header.description.c_str(), 80);
|
||||||
Util::convertISOToDOS(s);
|
Util::convertISOToDOS(s);
|
||||||
|
|
||||||
|
// Trim long GMM save descriptions to fit our save slots
|
||||||
|
_screen->_charWidth = -2;
|
||||||
|
int fC = _screen->getTextWidth(s);
|
||||||
|
while (s[0] && fC > 240) {
|
||||||
|
s[strlen(s) - 1] = 0;
|
||||||
|
fC = _screen->getTextWidth(s);
|
||||||
|
}
|
||||||
|
_screen->_charWidth = 0;
|
||||||
|
|
||||||
menu.item[i].saveSlot = _saveSlots[i + _savegameOffset];
|
menu.item[i].saveSlot = _saveSlots[i + _savegameOffset];
|
||||||
menu.item[i].enabled = true;
|
menu.item[i].enabled = true;
|
||||||
delete in;
|
delete in;
|
||||||
|
|
|
@ -83,6 +83,8 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
void KyraEngine_v1::pauseEngineIntern(bool pause) {
|
void KyraEngine_v1::pauseEngineIntern(bool pause) {
|
||||||
|
Engine::pauseEngineIntern(pause);
|
||||||
|
if (_sound)
|
||||||
_sound->pause(pause);
|
_sound->pause(pause);
|
||||||
_timer->pause(pause);
|
_timer->pause(pause);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3359,7 +3359,7 @@ void SJISFont::drawChar(uint16 c, byte *dst, int pitch) const {
|
||||||
color2 = _colorMap[0];
|
color2 = _colorMap[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
_font->drawChar(dst, c, 640, 1, color1, color2);
|
_font->drawChar(dst, c, 640, 1, color1, color2, 640, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark -
|
#pragma mark -
|
||||||
|
|
|
@ -43,10 +43,6 @@ Sound::Sound(KyraEngine_v1 *vm, Audio::Mixer *mixer)
|
||||||
Sound::~Sound() {
|
Sound::~Sound() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sound::pause(bool paused) {
|
|
||||||
_mixer->pauseAll(paused);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sound::voiceFileIsPresent(const char *file) {
|
bool Sound::voiceFileIsPresent(const char *file) {
|
||||||
for (int i = 0; _supportedCodecs[i].fileext; ++i) {
|
for (int i = 0; _supportedCodecs[i].fileext; ++i) {
|
||||||
Common::String f = file;
|
Common::String f = file;
|
||||||
|
|
|
@ -156,7 +156,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Stops all audio playback when paused. Continues after end of pause.
|
* Stops all audio playback when paused. Continues after end of pause.
|
||||||
*/
|
*/
|
||||||
virtual void pause(bool paused);
|
virtual void pause(bool paused) {}
|
||||||
|
|
||||||
void enableMusic(int enable) { _musicEnabled = enable; }
|
void enableMusic(int enable) { _musicEnabled = enable; }
|
||||||
int musicEnabled() const { return _musicEnabled; }
|
int musicEnabled() const { return _musicEnabled; }
|
||||||
|
|
|
@ -716,9 +716,6 @@ void SoundMidiPC::beginFadeOut() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundMidiPC::pause(bool paused) {
|
void SoundMidiPC::pause(bool paused) {
|
||||||
// Stop all mixer related sounds
|
|
||||||
Sound::pause(paused);
|
|
||||||
|
|
||||||
Common::StackLock lock(_mutex);
|
Common::StackLock lock(_mutex);
|
||||||
|
|
||||||
if (paused) {
|
if (paused) {
|
||||||
|
|
|
@ -36,13 +36,329 @@
|
||||||
|
|
||||||
namespace LastExpress {
|
namespace LastExpress {
|
||||||
|
|
||||||
|
#pragma region Sound filters tables
|
||||||
|
|
||||||
|
static const int filterData[1424] = {
|
||||||
|
0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256,
|
||||||
|
384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0,
|
||||||
|
192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640,
|
||||||
|
64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128,
|
||||||
|
320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576,
|
||||||
|
704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192,
|
||||||
|
192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448,
|
||||||
|
576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832,
|
||||||
|
320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320,
|
||||||
|
320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704,
|
||||||
|
832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448,
|
||||||
|
448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448,
|
||||||
|
640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960,
|
||||||
|
1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576,
|
||||||
|
576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576,
|
||||||
|
576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832,
|
||||||
|
960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088,
|
||||||
|
1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704,
|
||||||
|
704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768,
|
||||||
|
768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960,
|
||||||
|
1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280,
|
||||||
|
1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896,
|
||||||
|
896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896,
|
||||||
|
896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152,
|
||||||
|
1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408,
|
||||||
|
1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600,
|
||||||
|
1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088,
|
||||||
|
1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088,
|
||||||
|
1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152,
|
||||||
|
1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152,
|
||||||
|
1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408,
|
||||||
|
1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536,
|
||||||
|
1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728,
|
||||||
|
1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856,
|
||||||
|
1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344,
|
||||||
|
1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408,
|
||||||
|
1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408,
|
||||||
|
1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472,
|
||||||
|
1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664,
|
||||||
|
1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856,
|
||||||
|
1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984,
|
||||||
|
2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176,
|
||||||
|
1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664,
|
||||||
|
1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664,
|
||||||
|
1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728,
|
||||||
|
1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728,
|
||||||
|
1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984,
|
||||||
|
2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112,
|
||||||
|
2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304,
|
||||||
|
2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432,
|
||||||
|
1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920,
|
||||||
|
1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984,
|
||||||
|
1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984,
|
||||||
|
1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048,
|
||||||
|
2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240,
|
||||||
|
2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432,
|
||||||
|
2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560,
|
||||||
|
2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752,
|
||||||
|
2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240,
|
||||||
|
2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240,
|
||||||
|
2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304,
|
||||||
|
2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304,
|
||||||
|
2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560,
|
||||||
|
2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688,
|
||||||
|
2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880,
|
||||||
|
3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008,
|
||||||
|
2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496,
|
||||||
|
2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560,
|
||||||
|
2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560,
|
||||||
|
2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624,
|
||||||
|
2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816,
|
||||||
|
2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008,
|
||||||
|
3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136,
|
||||||
|
3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328,
|
||||||
|
2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816,
|
||||||
|
2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816,
|
||||||
|
2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880,
|
||||||
|
2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880,
|
||||||
|
3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136,
|
||||||
|
3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264,
|
||||||
|
3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456,
|
||||||
|
3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584,
|
||||||
|
3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072,
|
||||||
|
3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136,
|
||||||
|
3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136,
|
||||||
|
3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200,
|
||||||
|
3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392,
|
||||||
|
3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584,
|
||||||
|
3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712,
|
||||||
|
3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904,
|
||||||
|
3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392,
|
||||||
|
3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392,
|
||||||
|
3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456,
|
||||||
|
3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456,
|
||||||
|
3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712,
|
||||||
|
3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840,
|
||||||
|
3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032,
|
||||||
|
4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160,
|
||||||
|
3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648,
|
||||||
|
3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712,
|
||||||
|
3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712,
|
||||||
|
3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776,
|
||||||
|
3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968,
|
||||||
|
4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160,
|
||||||
|
4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288,
|
||||||
|
4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480,
|
||||||
|
3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968,
|
||||||
|
3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968,
|
||||||
|
3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032,
|
||||||
|
4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032,
|
||||||
|
4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288,
|
||||||
|
4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416,
|
||||||
|
4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608,
|
||||||
|
4.6, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736,
|
||||||
|
4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224,
|
||||||
|
4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288,
|
||||||
|
4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288,
|
||||||
|
4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352,
|
||||||
|
4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544,
|
||||||
|
4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736,
|
||||||
|
4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864,
|
||||||
|
4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056,
|
||||||
|
4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544,
|
||||||
|
4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544,
|
||||||
|
4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608,
|
||||||
|
4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608,
|
||||||
|
4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864,
|
||||||
|
4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992,
|
||||||
|
5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184,
|
||||||
|
5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312,
|
||||||
|
4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800,
|
||||||
|
4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864,
|
||||||
|
4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864,
|
||||||
|
4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928,
|
||||||
|
5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120,
|
||||||
|
5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312,
|
||||||
|
5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440,
|
||||||
|
5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632,
|
||||||
|
5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120,
|
||||||
|
5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120,
|
||||||
|
5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184,
|
||||||
|
5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184,
|
||||||
|
5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440,
|
||||||
|
5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568,
|
||||||
|
5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632,
|
||||||
|
5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632,
|
||||||
|
5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376,
|
||||||
|
5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440,
|
||||||
|
5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440,
|
||||||
|
5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504,
|
||||||
|
5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632,
|
||||||
|
5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632,
|
||||||
|
5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632,
|
||||||
|
5632
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int filterData2[1424] = {
|
||||||
|
0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11,
|
||||||
|
-13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9,
|
||||||
|
-11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5,
|
||||||
|
-7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18,
|
||||||
|
-1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12,
|
||||||
|
15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4,
|
||||||
|
7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19,
|
||||||
|
-22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14,
|
||||||
|
-17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5,
|
||||||
|
-8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26,
|
||||||
|
30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10,
|
||||||
|
14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27,
|
||||||
|
-31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16,
|
||||||
|
-21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2,
|
||||||
|
-7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25,
|
||||||
|
31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3,
|
||||||
|
9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34,
|
||||||
|
-40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17,
|
||||||
|
-24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50,
|
||||||
|
58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21,
|
||||||
|
29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55,
|
||||||
|
-63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32,
|
||||||
|
-41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5,
|
||||||
|
-15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50,
|
||||||
|
61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6,
|
||||||
|
18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56,
|
||||||
|
-68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20,
|
||||||
|
-34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82,
|
||||||
|
97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8,
|
||||||
|
24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74,
|
||||||
|
-90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9,
|
||||||
|
-27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70,
|
||||||
|
90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130,
|
||||||
|
-150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55,
|
||||||
|
-77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133,
|
||||||
|
157, 181, -12, -36, -60, -84, -109, -133, -157, -181,
|
||||||
|
13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93,
|
||||||
|
-120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191,
|
||||||
|
221, -14, -44, -73, -103, -132, -162, -191, -221, 16,
|
||||||
|
48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113,
|
||||||
|
-146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232,
|
||||||
|
268, -17, -53, -89, -125, -160, -196, -232, -268, 19,
|
||||||
|
58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137,
|
||||||
|
-176, -215, -255, -294, 21, 64, 108, 151, 194, 237,
|
||||||
|
281, 324, -21, -64, -108, -151, -194, -237, -281, -324,
|
||||||
|
23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118,
|
||||||
|
-166, -213, -261, -308, -356, 26, 78, 130, 182, 235,
|
||||||
|
287, 339, 391, -26, -78, -130, -182, -235, -287, -339,
|
||||||
|
-391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86,
|
||||||
|
-143, -201, -258, -316, -373, -431, 31, 94, 158, 221,
|
||||||
|
284, 347, 411, 474, -31, -94, -158, -221, -284, -347,
|
||||||
|
-411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34,
|
||||||
|
-104, -174, -244, -313, -383, -453, -523, 38, 115, 191,
|
||||||
|
268, 345, 422, 498, 575, -38, -115, -191, -268, -345,
|
||||||
|
-422, -498, -575, 42, 126, 210, 294, 379, 463, 547,
|
||||||
|
631, -42, -126, -210, -294, -379, -463, -547, -631,
|
||||||
|
46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231,
|
||||||
|
-324, -417, -510, -602, -695, 51, 153, 255, 357, 459,
|
||||||
|
561, 663, 765, -51, -153, -255, -357, -459, -561, -663,
|
||||||
|
-765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168,
|
||||||
|
-280, -392, -505, -617, -729, -841, 61, 185, 308, 432,
|
||||||
|
555, 679, 802, 926, -61, -185, -308, -432, -555, -679,
|
||||||
|
-802, -926, 68, 204, 340, 476, 612, 748, 884, 1020,
|
||||||
|
-68, -204, -340, -476, -612, -748, -884, -1020, 74,
|
||||||
|
224, 373, 523, 672, 822, 971, 1121, -74, -224, -373,
|
||||||
|
-523, -672, -822, -971, -1121, 82, 246, 411, 575, 740,
|
||||||
|
904, 1069, 1233, -82, -246, -411, -575, -740, -904,
|
||||||
|
-1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357,
|
||||||
|
-90, -271, -452, -633, -814, -995, -1176, -1357, 99,
|
||||||
|
298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497,
|
||||||
|
-696, -895, -1094, -1293, -1492, 109, 328, 547, 766,
|
||||||
|
985, 1204, 1423, 1642, -109, -328, -547, -766, -985,
|
||||||
|
-1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324,
|
||||||
|
1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564,
|
||||||
|
-1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132,
|
||||||
|
-397, -662, -927, -1192, -1457, -1722, -1987, 145, 437,
|
||||||
|
728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728,
|
||||||
|
-1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121,
|
||||||
|
1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442,
|
||||||
|
-1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940,
|
||||||
|
2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292,
|
||||||
|
-2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910,
|
||||||
|
-194, -582, -970, -1358, -1746, -2134, -2522, -2910,
|
||||||
|
213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213,
|
||||||
|
-640, -1066, -1493, -1920, -2347, -2773, -3200, 234,
|
||||||
|
704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704,
|
||||||
|
-1173, -1643, -2112, -2582, -3051, -3521, 258, 774,
|
||||||
|
1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291,
|
||||||
|
-1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988,
|
||||||
|
2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556,
|
||||||
|
-3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436,
|
||||||
|
4060, 4685, -312, -937, -1561, -2186, -2811, -3436,
|
||||||
|
-4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467,
|
||||||
|
5154, -343, -1030, -1718, -2405, -3092, -3779, -4467,
|
||||||
|
-5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670,
|
||||||
|
-378, -1134, -1890, -2646, -3402, -4158, -4914, -5670,
|
||||||
|
415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415,
|
||||||
|
-1247, -2079, -2911, -3742, -4574, -5406, -6238, 457,
|
||||||
|
1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372,
|
||||||
|
-2287, -3202, -4117, -5032, -5947, -6862, 503, 1509,
|
||||||
|
2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516,
|
||||||
|
-3522, -4529, -5535, -6542, -7548, 553, 1660, 2767,
|
||||||
|
3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874,
|
||||||
|
-4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479,
|
||||||
|
6697, 7915, 9133, -608, -1826, -3044, -4262, -5479,
|
||||||
|
-6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367,
|
||||||
|
8706, 10046, -669, -2009, -3348, -4688, -6027, -7367,
|
||||||
|
-8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577,
|
||||||
|
11051, -736, -2210, -3683, -5157, -6630, -8104, -9577,
|
||||||
|
-11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157,
|
||||||
|
-810, -2431, -4052, -5673, -7294, -8915, -10536, -12157,
|
||||||
|
891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891,
|
||||||
|
-2674, -4457, -6240, -8023, -9806, -11589, -13372, 980,
|
||||||
|
2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941,
|
||||||
|
-4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236,
|
||||||
|
5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236,
|
||||||
|
-5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559,
|
||||||
|
5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559,
|
||||||
|
-5933, -8306, -10679, -13052, -15426, -17799, 1305,
|
||||||
|
3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305,
|
||||||
|
-3915, -6526, -9136, -11747, -14357, -16968, -19578,
|
||||||
|
1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538,
|
||||||
|
-1435, -4307, -7179, -10051, -12922, -15794, -18666,
|
||||||
|
-21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531,
|
||||||
|
23690, -1579, -4738, -7896, -11055, -14214, -17373,
|
||||||
|
-20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111,
|
||||||
|
22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111,
|
||||||
|
-22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022,
|
||||||
|
24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022,
|
||||||
|
-24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124,
|
||||||
|
27329, 31533, -2102, -6306, -10511, -14715, -18920,
|
||||||
|
-23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812,
|
||||||
|
25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812,
|
||||||
|
-25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893,
|
||||||
|
27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893,
|
||||||
|
-27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183,
|
||||||
|
30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183,
|
||||||
|
-30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700,
|
||||||
|
32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700,
|
||||||
|
-32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471,
|
||||||
|
32767, 32767, 32767, -3385, -10157, -16928, -23700,
|
||||||
|
-30471, -32767, -32767, -32767, 3724, 11172, 18621,
|
||||||
|
26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621,
|
||||||
|
-26069, -32767, -32767, -32767, -32767, 4095, 12287,
|
||||||
|
20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287,
|
||||||
|
-20479, -28671, -32767, -32767, -32767, -32767
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 };
|
||||||
|
static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 };
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
// Last Express ADPCM is similar to MS IMA mono, but inverts its nibbles
|
// Last Express ADPCM is similar to MS IMA mono, but inverts its nibbles
|
||||||
// and does not have the 4 byte per channel requirement
|
// and does not have the 4 byte per channel requirement
|
||||||
|
|
||||||
class LastExpress_ADPCMStream : public Audio::Ima_ADPCMStream {
|
class LastExpress_ADPCMStream : public Audio::Ima_ADPCMStream {
|
||||||
public:
|
public:
|
||||||
LastExpress_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, uint32 blockSize) :
|
LastExpress_ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, uint32 blockSize, int32 filterId) :
|
||||||
Audio::Ima_ADPCMStream(stream, disposeAfterUse, size, 44100, 1, blockSize) {}
|
Audio::Ima_ADPCMStream(stream, disposeAfterUse, size, 44100, 1, blockSize) {
|
||||||
|
_currentFilterId = -1;
|
||||||
|
_nextFilterId = filterId;
|
||||||
|
}
|
||||||
|
|
||||||
int readBuffer(int16 *buffer, const int numSamples) {
|
int readBuffer(int16 *buffer, const int numSamples) {
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
|
@ -67,6 +383,45 @@ public:
|
||||||
|
|
||||||
return samples;
|
return samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setFilterId(int32 filterId) { _nextFilterId = filterId; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 _currentFilterId;
|
||||||
|
int32 _nextFilterId; // the sound filter id, -1 for none
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sound filter
|
||||||
|
*
|
||||||
|
* @param [in] data If non-null, the input data
|
||||||
|
* @param [in,out] buffer If non-null, the output buffer.
|
||||||
|
* @param p1 The first filter input.
|
||||||
|
* @param p2 The second filter input.
|
||||||
|
*/
|
||||||
|
static void soundFilter(byte *data, int16 *buffer, int p1, int p2) {
|
||||||
|
int data1, data2, data1p, data2p;
|
||||||
|
byte idx;
|
||||||
|
|
||||||
|
data2 = data[0];
|
||||||
|
data1 = data[1] << 6;
|
||||||
|
|
||||||
|
data += 2;
|
||||||
|
|
||||||
|
for (int count = 0; count < 735; count++) {
|
||||||
|
idx = data[count] >> 4;
|
||||||
|
|
||||||
|
data1p = filterData[idx + data1];
|
||||||
|
data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767);
|
||||||
|
|
||||||
|
buffer[2 * count] = (p2 * data2p) >> p1;
|
||||||
|
|
||||||
|
idx = data[count] & 0xF;
|
||||||
|
|
||||||
|
data1 = filterData[idx + data1p];
|
||||||
|
data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767);
|
||||||
|
buffer[2 * count + 1] = (p2 * data2) >> p1;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -92,8 +447,8 @@ void SimpleSound::loadHeader(Common::SeekableReadStream *in) {
|
||||||
_blockSize = _size / _blocks;
|
_blockSize = _size / _blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
Audio::AudioStream *SimpleSound::makeDecoder(Common::SeekableReadStream *in, uint32 size) const {
|
Audio::AudioStream *SimpleSound::makeDecoder(Common::SeekableReadStream *in, uint32 size, int32 filterId) const {
|
||||||
return new LastExpress_ADPCMStream(in, DisposeAfterUse::YES, size, _blockSize);
|
return new LastExpress_ADPCMStream(in, DisposeAfterUse::YES, size, _blockSize, filterId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SimpleSound::play(Audio::AudioStream *as) {
|
void SimpleSound::play(Audio::AudioStream *as) {
|
||||||
|
@ -103,10 +458,11 @@ void SimpleSound::play(Audio::AudioStream *as) {
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// StreamedSound
|
// StreamedSound
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
StreamedSound::StreamedSound() {}
|
StreamedSound::StreamedSound() : _as(NULL), _loaded(false) {}
|
||||||
|
|
||||||
StreamedSound::~StreamedSound() {}
|
StreamedSound::~StreamedSound() {}
|
||||||
|
|
||||||
bool StreamedSound::load(Common::SeekableReadStream *stream) {
|
bool StreamedSound::load(Common::SeekableReadStream *stream, int32 filterId) {
|
||||||
if (!stream)
|
if (!stream)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -115,14 +471,27 @@ bool StreamedSound::load(Common::SeekableReadStream *stream) {
|
||||||
loadHeader(stream);
|
loadHeader(stream);
|
||||||
|
|
||||||
// Start decoding the input stream
|
// Start decoding the input stream
|
||||||
Audio::AudioStream *as = makeDecoder(stream, _size);
|
_as = makeDecoder(stream, _size, filterId);
|
||||||
|
|
||||||
// Start playing the decoded audio stream
|
// Start playing the decoded audio stream
|
||||||
play(as);
|
play(_as);
|
||||||
|
|
||||||
|
_loaded = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StreamedSound::isFinished() {
|
||||||
|
if (!_loaded)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !g_system->getMixer()->isSoundHandleActive(_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamedSound::setFilterId(int32 filterId) {
|
||||||
|
((LastExpress_ADPCMStream *)_as)->setFilterId(filterId);
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// StreamedSound
|
// StreamedSound
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -172,4 +541,8 @@ void AppendableSound::finish() {
|
||||||
_finished = true;
|
_finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppendableSound::isFinished() {
|
||||||
|
return _as->endOfStream();
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace LastExpress
|
} // End of namespace LastExpress
|
||||||
|
|
|
@ -55,10 +55,11 @@ public:
|
||||||
virtual ~SimpleSound();
|
virtual ~SimpleSound();
|
||||||
|
|
||||||
void stop() const;
|
void stop() const;
|
||||||
|
virtual bool isFinished() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void loadHeader(Common::SeekableReadStream *in);
|
void loadHeader(Common::SeekableReadStream *in);
|
||||||
Audio::AudioStream *makeDecoder(Common::SeekableReadStream *in, uint32 size) const;
|
Audio::AudioStream *makeDecoder(Common::SeekableReadStream *in, uint32 size, int32 filterId = -1) const;
|
||||||
void play(Audio::AudioStream *as);
|
void play(Audio::AudioStream *as);
|
||||||
|
|
||||||
uint32 _size; ///< data size
|
uint32 _size; ///< data size
|
||||||
|
@ -75,7 +76,14 @@ public:
|
||||||
StreamedSound();
|
StreamedSound();
|
||||||
~StreamedSound();
|
~StreamedSound();
|
||||||
|
|
||||||
bool load(Common::SeekableReadStream *stream);
|
bool load(Common::SeekableReadStream *stream, int32 filterId = -1);
|
||||||
|
virtual bool isFinished();
|
||||||
|
|
||||||
|
void setFilterId(int32 filterId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Audio::AudioStream *_as;
|
||||||
|
bool _loaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AppendableSound : public SimpleSound {
|
class AppendableSound : public SimpleSound {
|
||||||
|
@ -87,6 +95,8 @@ public:
|
||||||
void queueBuffer(Common::SeekableReadStream *bufferIn);
|
void queueBuffer(Common::SeekableReadStream *bufferIn);
|
||||||
void finish();
|
void finish();
|
||||||
|
|
||||||
|
virtual bool isFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Audio::QueuingAudioStream *_as;
|
Audio::QueuingAudioStream *_as;
|
||||||
bool _finished;
|
bool _finished;
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#include "lastexpress/data/archive.h"
|
#include "lastexpress/data/archive.h"
|
||||||
#include "lastexpress/shared.h"
|
#include "lastexpress/shared.h"
|
||||||
|
|
||||||
|
#include "common/array.h"
|
||||||
|
|
||||||
namespace LastExpress {
|
namespace LastExpress {
|
||||||
|
|
||||||
class Background;
|
class Background;
|
||||||
|
|
|
@ -89,6 +89,27 @@ enum SoundState {
|
||||||
kSoundState2 = 2
|
kSoundState2 = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SoundStatus {
|
||||||
|
kSoundStatus_20 = 0x20,
|
||||||
|
kSoundStatus_40 = 0x40,
|
||||||
|
kSoundStatus_180 = 0x180,
|
||||||
|
kSoundStatusClosed = 0x200,
|
||||||
|
kSoundStatus_400 = 0x400,
|
||||||
|
|
||||||
|
kSoundStatus_8000 = 0x8000,
|
||||||
|
kSoundStatus_20000 = 0x20000,
|
||||||
|
kSoundStatus_100000 = 0x100000,
|
||||||
|
kSoundStatus_20000000 = 0x20000000,
|
||||||
|
kSoundStatus_40000000 = 0x40000000,
|
||||||
|
|
||||||
|
kSoundStatusClear0 = 0x10,
|
||||||
|
kSoundStatusFilter = 0x1F,
|
||||||
|
kSoundStatusCached = 0x80,
|
||||||
|
kSoundStatusClear3 = 0x200,
|
||||||
|
kSoundStatusClear4 = 0x800,
|
||||||
|
kSoundStatusClearAll = 0xFFFFFFE0
|
||||||
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Time values
|
// Time values
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -38,15 +38,15 @@
|
||||||
|
|
||||||
namespace LastExpress {
|
namespace LastExpress {
|
||||||
|
|
||||||
|
#define SOUNDCACHE_ENTRY_SIZE 92160
|
||||||
|
#define FILTER_BUFFER_SIZE 2940
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// SoundEntry
|
// SoundEntry
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
||||||
_type = kSoundTypeNone;
|
_type = kSoundTypeNone;
|
||||||
|
|
||||||
_currentDataPtr = 0;
|
|
||||||
_soundData = NULL;
|
|
||||||
|
|
||||||
_blockCount = 0;
|
_blockCount = 0;
|
||||||
_time = 0;
|
_time = 0;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
||||||
_field_34 = 0;
|
_field_34 = 0;
|
||||||
_field_38 = 0;
|
_field_38 = 0;
|
||||||
_field_3C = 0;
|
_field_3C = 0;
|
||||||
_field_40 = 0;
|
_variant = 0;
|
||||||
_entity = kEntityPlayer;
|
_entity = kEntityPlayer;
|
||||||
_field_48 = 0;
|
_field_48 = 0;
|
||||||
_priority = 0;
|
_priority = 0;
|
||||||
|
@ -63,13 +63,14 @@ SoundEntry::SoundEntry(LastExpressEngine *engine) : _engine(engine) {
|
||||||
_subtitle = NULL;
|
_subtitle = NULL;
|
||||||
|
|
||||||
_soundStream = NULL;
|
_soundStream = NULL;
|
||||||
|
|
||||||
|
_queued = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundEntry::~SoundEntry() {
|
SoundEntry::~SoundEntry() {
|
||||||
// Entries that have been queued would have their streamed disposed automatically
|
// Entries that have been queued will have their streamed disposed automatically
|
||||||
if (!_soundStream)
|
if (!_soundStream)
|
||||||
SAFE_DELETE(_stream);
|
SAFE_DELETE(_stream);
|
||||||
|
|
||||||
delete _soundStream;
|
delete _soundStream;
|
||||||
|
|
||||||
// Zero passed pointers
|
// Zero passed pointers
|
||||||
|
@ -79,18 +80,12 @@ SoundEntry::~SoundEntry() {
|
||||||
void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
|
void SoundEntry::open(Common::String name, SoundFlag flag, int priority) {
|
||||||
_priority = priority;
|
_priority = priority;
|
||||||
setType(flag);
|
setType(flag);
|
||||||
setStatus(flag);
|
setupStatus(flag);
|
||||||
|
loadStream(name);
|
||||||
// Add entry to sound list
|
|
||||||
getSoundQueue()->addToQueue(this);
|
|
||||||
|
|
||||||
// Add entry to cache and load sound data
|
|
||||||
getSoundQueue()->setupCache(this);
|
|
||||||
loadSoundData(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundEntry::close() {
|
void SoundEntry::close() {
|
||||||
_status.status |= kSoundStatusRemoved;
|
_status.status |= kSoundStatusClosed;
|
||||||
|
|
||||||
// Loop until ready
|
// Loop until ready
|
||||||
while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
|
while (!(_status.status1 & 4) && !(getSoundQueue()->getFlag() & 8) && (getSoundQueue()->getFlag() & 1))
|
||||||
|
@ -114,6 +109,43 @@ void SoundEntry::close() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SoundEntry::play() {
|
||||||
|
if (!_stream) {
|
||||||
|
warning("[SoundEntry::play] stream has been disposed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare sound stream
|
||||||
|
if (!_soundStream)
|
||||||
|
_soundStream = new StreamedSound();
|
||||||
|
|
||||||
|
// Compute current filter id
|
||||||
|
int32 filterId = _status.status & kSoundStatusFilter;
|
||||||
|
// TODO adjust status (based on stepIndex)
|
||||||
|
|
||||||
|
if (_queued) {
|
||||||
|
_soundStream->setFilterId(filterId);
|
||||||
|
} else {
|
||||||
|
_stream->seek(0);
|
||||||
|
|
||||||
|
// Load the stream and start playing
|
||||||
|
_soundStream->load(_stream, filterId);
|
||||||
|
|
||||||
|
_queued = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SoundEntry::isFinished() {
|
||||||
|
if (!_stream)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!_soundStream || !_queued)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO check that all data has been queued
|
||||||
|
return _soundStream->isFinished();
|
||||||
|
}
|
||||||
|
|
||||||
void SoundEntry::setType(SoundFlag flag) {
|
void SoundEntry::setType(SoundFlag flag) {
|
||||||
switch (flag & kFlagType9) {
|
switch (flag & kFlagType9) {
|
||||||
default:
|
default:
|
||||||
|
@ -186,10 +218,10 @@ void SoundEntry::setType(SoundFlag flag) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundEntry::setStatus(SoundFlag flag) {
|
void SoundEntry::setupStatus(SoundFlag flag) {
|
||||||
SoundStatus statusFlag = (SoundStatus)flag;
|
SoundStatus statusFlag = (SoundStatus)flag;
|
||||||
if (!((statusFlag & 0xFF) & kSoundStatusClear1))
|
if (!((statusFlag & 0xFF) & kSoundStatusFilter))
|
||||||
statusFlag = (SoundStatus)(statusFlag | kSoundStatusClear2);
|
statusFlag = (SoundStatus)(statusFlag | kSoundStatusCached);
|
||||||
|
|
||||||
if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0)
|
if (((statusFlag & 0xFF00) >> 8) & kSoundStatusClear0)
|
||||||
_status.status = (uint32)statusFlag;
|
_status.status = (uint32)statusFlag;
|
||||||
|
@ -197,11 +229,7 @@ void SoundEntry::setStatus(SoundFlag flag) {
|
||||||
_status.status = (statusFlag | kSoundStatusClear4);
|
_status.status = (statusFlag | kSoundStatusClear4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundEntry::setInCache() {
|
void SoundEntry::loadStream(Common::String name) {
|
||||||
_status.status |= kSoundStatusClear2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundEntry::loadSoundData(Common::String name) {
|
|
||||||
_name2 = name;
|
_name2 = name;
|
||||||
|
|
||||||
// Load sound data
|
// Load sound data
|
||||||
|
@ -210,11 +238,8 @@ void SoundEntry::loadSoundData(Common::String name) {
|
||||||
if (!_stream)
|
if (!_stream)
|
||||||
_stream = getArchive("DEFAULT.SND");
|
_stream = getArchive("DEFAULT.SND");
|
||||||
|
|
||||||
if (_stream) {
|
if (!_stream)
|
||||||
warning("[Sound::loadSoundData] Not implemented");
|
_status.status = kSoundStatusClosed;
|
||||||
} else {
|
|
||||||
_status.status = kSoundStatusRemoved;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundEntry::update(uint val) {
|
void SoundEntry::update(uint val) {
|
||||||
|
@ -225,7 +250,7 @@ void SoundEntry::update(uint val) {
|
||||||
|
|
||||||
if (val) {
|
if (val) {
|
||||||
if (getSoundQueue()->getFlag() & 32) {
|
if (getSoundQueue()->getFlag() & 32) {
|
||||||
_field_40 = val;
|
_variant = val;
|
||||||
value2 = val * 2 + 1;
|
value2 = val * 2 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,15 +262,65 @@ void SoundEntry::update(uint val) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SoundEntry::updateSound() {
|
||||||
|
bool result;
|
||||||
|
char sub[16];
|
||||||
|
|
||||||
|
if (_status.status2 & 4) {
|
||||||
|
result = false;
|
||||||
|
} else {
|
||||||
|
if (_status.status2 & 0x80) {
|
||||||
|
if (_field_48 <= getSound()->getData2()) {
|
||||||
|
_status.status |= 0x20;
|
||||||
|
_status.status &= ~0x8000;
|
||||||
|
strcpy(sub, _name2.c_str());
|
||||||
|
|
||||||
|
int l = strlen(sub) + 1;
|
||||||
|
if (l - 1 > 4)
|
||||||
|
sub[l - 1 - 4] = 0;
|
||||||
|
showSubtitle(sub);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!(getSoundQueue()->getFlag() & 0x20)) {
|
||||||
|
if (!(_status.status3 & 8)) {
|
||||||
|
if (_entity) {
|
||||||
|
if (_entity < 0x80) {
|
||||||
|
updateEntryFlag(getSound()->getSoundFlag(_entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if (status.status2 & 0x40 && !((uint32)_status.status & 0x180) && v1->soundBuffer)
|
||||||
|
// Sound_FillSoundBuffer(v1);
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SoundEntry::updateEntryFlag(SoundFlag flag) {
|
||||||
|
if (flag) {
|
||||||
|
if (getSoundQueue()->getFlag() & 0x20 && _type != kSoundType9 && _type != kSoundType7)
|
||||||
|
update(flag);
|
||||||
|
else
|
||||||
|
_status.status = flag + (_status.status & ~0x1F);
|
||||||
|
} else {
|
||||||
|
_variant = 0;
|
||||||
|
_status.status |= 0x80u;
|
||||||
|
_status.status &= ~0x10001F;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SoundEntry::updateState() {
|
void SoundEntry::updateState() {
|
||||||
if (getSoundQueue()->getFlag() & 32) {
|
if (getSoundQueue()->getFlag() & 32) {
|
||||||
if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) {
|
if (_type != kSoundType9 && _type != kSoundType7 && _type != kSoundType5) {
|
||||||
uint32 newStatus = _status.status & kSoundStatusClear1;
|
uint32 variant = _status.status & kSoundStatusFilter;
|
||||||
|
|
||||||
_status.status &= kSoundStatusClearAll;
|
_status.status &= kSoundStatusClearAll;
|
||||||
|
|
||||||
_field_40 = newStatus;
|
_variant = variant;
|
||||||
_status.status |= newStatus * 2 + 1;
|
_status.status |= variant * 2 + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,13 +328,14 @@ void SoundEntry::updateState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundEntry::reset() {
|
void SoundEntry::reset() {
|
||||||
_status.status |= kSoundStatusRemoved;
|
_status.status |= kSoundStatusClosed;
|
||||||
_entity = kEntityPlayer;
|
_entity = kEntityPlayer;
|
||||||
|
|
||||||
if (_stream) {
|
if (_stream) {
|
||||||
if (!_soundStream) {
|
if (!_soundStream) {
|
||||||
SAFE_DELETE(_stream);
|
SAFE_DELETE(_stream);
|
||||||
} else {
|
} else {
|
||||||
|
// the original stream will be disposed
|
||||||
_soundStream->stop();
|
_soundStream->stop();
|
||||||
SAFE_DELETE(_soundStream);
|
SAFE_DELETE(_soundStream);
|
||||||
}
|
}
|
||||||
|
@ -307,13 +383,6 @@ void SoundEntry::saveLoadWithSerializer(Common::Serializer &s) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundEntry::loadStream() {
|
|
||||||
if (!_soundStream)
|
|
||||||
_soundStream = new StreamedSound();
|
|
||||||
|
|
||||||
_soundStream->load(_stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// SubtitleEntry
|
// SubtitleEntry
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -335,7 +404,7 @@ void SubtitleEntry::load(Common::String filename, SoundEntry *soundEntry) {
|
||||||
_sound = soundEntry;
|
_sound = soundEntry;
|
||||||
|
|
||||||
// Load subtitle data
|
// Load subtitle data
|
||||||
if (_engine->getResourceManager()->hasFile(filename)) {
|
if (_engine->getResourceManager()->hasFile(_filename)) {
|
||||||
if (getSoundQueue()->getSubtitleFlag() & 2)
|
if (getSoundQueue()->getSubtitleFlag() & 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -369,6 +438,8 @@ void SubtitleEntry::setupAndDraw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
getSoundQueue()->setCurrentSubtitle(this);
|
getSoundQueue()->setCurrentSubtitle(this);
|
||||||
|
|
||||||
|
// TODO Missing code
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitleEntry::draw() {
|
void SubtitleEntry::draw() {
|
||||||
|
@ -384,12 +455,10 @@ void SubtitleEntry::draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitleEntry::drawOnScreen() {
|
void SubtitleEntry::drawOnScreen() {
|
||||||
getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() & -1);
|
|
||||||
|
|
||||||
if (_data == NULL)
|
if (_data == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (getSoundQueue()->getSubtitleFlag() & 1)
|
getSoundQueue()->setSubtitleFlag(getSoundQueue()->getSubtitleFlag() & -2);
|
||||||
_engine->getGraphicsManager()->draw(_data, GraphicsManager::kBackgroundOverlay);
|
_engine->getGraphicsManager()->draw(_data, GraphicsManager::kBackgroundOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,27 +76,6 @@ namespace LastExpress {
|
||||||
class LastExpressEngine;
|
class LastExpressEngine;
|
||||||
class SubtitleEntry;
|
class SubtitleEntry;
|
||||||
|
|
||||||
enum SoundStatus {
|
|
||||||
kSoundStatus_20 = 0x20,
|
|
||||||
kSoundStatus_40 = 0x40,
|
|
||||||
kSoundStatus_180 = 0x180,
|
|
||||||
kSoundStatusRemoved = 0x200,
|
|
||||||
kSoundStatus_400 = 0x400,
|
|
||||||
|
|
||||||
kSoundStatus_8000 = 0x8000,
|
|
||||||
kSoundStatus_20000 = 0x20000,
|
|
||||||
kSoundStatus_100000 = 0x100000,
|
|
||||||
kSoundStatus_20000000 = 0x20000000,
|
|
||||||
kSoundStatus_40000000 = 0x40000000,
|
|
||||||
|
|
||||||
kSoundStatusClear0 = 0x10,
|
|
||||||
kSoundStatusClear1 = 0x1F,
|
|
||||||
kSoundStatusClear2 = 0x80,
|
|
||||||
kSoundStatusClear3 = 0x200,
|
|
||||||
kSoundStatusClear4 = 0x800,
|
|
||||||
kSoundStatusClearAll = 0xFFFFFFE0
|
|
||||||
};
|
|
||||||
|
|
||||||
union SoundStatusUnion {
|
union SoundStatusUnion {
|
||||||
uint32 status;
|
uint32 status;
|
||||||
byte status1;
|
byte status1;
|
||||||
|
@ -119,16 +98,13 @@ public:
|
||||||
|
|
||||||
void open(Common::String name, SoundFlag flag, int priority);
|
void open(Common::String name, SoundFlag flag, int priority);
|
||||||
void close();
|
void close();
|
||||||
|
void play();
|
||||||
void setStatus(SoundFlag flag);
|
|
||||||
void setType(SoundFlag flag);
|
|
||||||
void setInCache();
|
|
||||||
void loadSoundData(Common::String name);
|
|
||||||
void update(uint val);
|
|
||||||
void updateState();
|
|
||||||
void reset();
|
void reset();
|
||||||
|
bool isFinished();
|
||||||
void loadStream();
|
void update(uint val);
|
||||||
|
bool updateSound();
|
||||||
|
void updateState();
|
||||||
|
void updateEntryFlag(SoundFlag flag);
|
||||||
|
|
||||||
// Subtitles
|
// Subtitles
|
||||||
void showSubtitle(Common::String filename);
|
void showSubtitle(Common::String filename);
|
||||||
|
@ -150,12 +126,7 @@ public:
|
||||||
Common::String getName2() { return _name2; }
|
Common::String getName2() { return _name2; }
|
||||||
|
|
||||||
// Streams
|
// Streams
|
||||||
Common::SeekableReadStream *getStream() { return _stream; }
|
SimpleSound *getSoundStream() { return _soundStream; }
|
||||||
StreamedSound *getStreamedSound() { return _soundStream; }
|
|
||||||
|
|
||||||
public:
|
|
||||||
// TODO replace by on-the-fly allocated buffer
|
|
||||||
void *_soundData;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LastExpressEngine *_engine;
|
LastExpressEngine *_engine;
|
||||||
|
@ -164,18 +135,18 @@ private:
|
||||||
SoundType _type; // int
|
SoundType _type; // int
|
||||||
//int _data;
|
//int _data;
|
||||||
//int _endOffset;
|
//int _endOffset;
|
||||||
int _currentDataPtr;
|
byte * _currentDataPtr;
|
||||||
//int _currentBufferPtr;
|
//int _currentBufferPtr;
|
||||||
int _blockCount;
|
int _blockCount;
|
||||||
uint32 _time;
|
uint32 _time;
|
||||||
//int _size;
|
//int _size;
|
||||||
//int _field_28;
|
//int _field_28;
|
||||||
Common::SeekableReadStream *_stream; // int
|
Common::SeekableReadStream *_stream; // The file stream
|
||||||
//int _field_30;
|
//int _archive;
|
||||||
int _field_34;
|
int _field_34;
|
||||||
int _field_38;
|
int _field_38;
|
||||||
int _field_3C;
|
int _field_3C;
|
||||||
int _field_40;
|
int _variant;
|
||||||
EntityIndex _entity;
|
EntityIndex _entity;
|
||||||
int _field_48;
|
int _field_48;
|
||||||
uint32 _priority;
|
uint32 _priority;
|
||||||
|
@ -184,8 +155,13 @@ private:
|
||||||
// original has pointer to the next structure in the list (not used)
|
// original has pointer to the next structure in the list (not used)
|
||||||
SubtitleEntry *_subtitle;
|
SubtitleEntry *_subtitle;
|
||||||
|
|
||||||
// Sound stream
|
// Sound buffer & stream
|
||||||
StreamedSound *_soundStream;
|
bool _queued;
|
||||||
|
StreamedSound *_soundStream; // the filtered sound stream
|
||||||
|
|
||||||
|
void setType(SoundFlag flag);
|
||||||
|
void setupStatus(SoundFlag flag);
|
||||||
|
void loadStream(Common::String name);
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -32,18 +32,11 @@
|
||||||
|
|
||||||
namespace LastExpress {
|
namespace LastExpress {
|
||||||
|
|
||||||
#define SOUNDCACHE_ENTRY_SIZE 92160
|
|
||||||
#define SOUNDCACHE_MAX_SIZE 6
|
|
||||||
|
|
||||||
SoundQueue::SoundQueue(LastExpressEngine *engine) : _engine(engine) {
|
SoundQueue::SoundQueue(LastExpressEngine *engine) : _engine(engine) {
|
||||||
_state = 0;
|
_state = 0;
|
||||||
_currentType = kSoundType16;
|
_currentType = kSoundType16;
|
||||||
_flag = 0;
|
_flag = 0;
|
||||||
|
|
||||||
// Cache and filter buffers
|
|
||||||
memset(&_buffer, 0, sizeof(_buffer));
|
|
||||||
_soundCacheData = malloc(6 * SOUNDCACHE_ENTRY_SIZE);
|
|
||||||
|
|
||||||
_subtitlesFlag = 0;
|
_subtitlesFlag = 0;
|
||||||
_currentSubtitle = NULL;
|
_currentSubtitle = NULL;
|
||||||
}
|
}
|
||||||
|
@ -53,17 +46,12 @@ SoundQueue::~SoundQueue() {
|
||||||
SAFE_DELETE(*i);
|
SAFE_DELETE(*i);
|
||||||
_soundList.clear();
|
_soundList.clear();
|
||||||
|
|
||||||
// Entries in the cache are just pointers to sound list entries
|
|
||||||
_soundCache.clear();
|
|
||||||
|
|
||||||
for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i)
|
for (Common::List<SubtitleEntry *>::iterator i = _subtitles.begin(); i != _subtitles.end(); ++i)
|
||||||
SAFE_DELETE(*i);
|
SAFE_DELETE(*i);
|
||||||
_subtitles.clear();
|
_subtitles.clear();
|
||||||
|
|
||||||
_currentSubtitle = NULL;
|
_currentSubtitle = NULL;
|
||||||
|
|
||||||
free(_soundCacheData);
|
|
||||||
|
|
||||||
// Zero passed pointers
|
// Zero passed pointers
|
||||||
_engine = NULL;
|
_engine = NULL;
|
||||||
}
|
}
|
||||||
|
@ -76,14 +64,17 @@ void SoundQueue::handleTimer() {
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i) {
|
||||||
SoundEntry *entry = (*i);
|
SoundEntry *entry = (*i);
|
||||||
if (entry->getStream() == NULL) {
|
|
||||||
SAFE_DELETE(*i);
|
// When the entry has stopped playing, we remove his buffer
|
||||||
|
if (entry->isFinished()) {
|
||||||
|
entry->close();
|
||||||
|
SAFE_DELETE(entry);
|
||||||
i = _soundList.reverse_erase(i);
|
i = _soundList.reverse_erase(i);
|
||||||
continue;
|
continue;
|
||||||
} else if (!entry->getStreamedSound()) {
|
|
||||||
// TODO: stream any sound in the queue after filtering
|
|
||||||
entry->loadStream();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Queue the entry data, applying filtering
|
||||||
|
entry->play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,9 +102,80 @@ void SoundQueue::removeFromQueue(Common::String filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::updateQueue() {
|
void SoundQueue::updateQueue() {
|
||||||
Common::StackLock locker(_mutex);
|
//Common::StackLock locker(_mutex);
|
||||||
|
|
||||||
warning("[Sound::updateQueue] Not implemented");
|
//warning("[Sound::updateQueue] Not implemented");
|
||||||
|
|
||||||
|
int maxPriority = 0;
|
||||||
|
Common::List<SoundEntry *>::iterator lsnd;
|
||||||
|
SoundEntry *msnd;
|
||||||
|
|
||||||
|
bool loopedPlaying;
|
||||||
|
|
||||||
|
loopedPlaying = 0;
|
||||||
|
//++g_sound_flag;
|
||||||
|
|
||||||
|
for (lsnd = _soundList.begin(); lsnd != _soundList.end(); ++lsnd) {
|
||||||
|
if ((*lsnd)->getType() == kSoundType1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getSoundState() & 1) {
|
||||||
|
if (!(*lsnd) || getFlags()->flag_3 || (*lsnd && (*lsnd)->getTime() > getSound()->getLoopingSoundDuration())) {
|
||||||
|
getSound()->playLoopingSound(0x45);
|
||||||
|
} else {
|
||||||
|
if (getSound()->getData1() && getSound()->getData2() >= getSound()->getData1()) {
|
||||||
|
(*lsnd)->update(getSound()->getData0());
|
||||||
|
getSound()->setData1(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msnd = NULL;
|
||||||
|
|
||||||
|
for (lsnd = _soundList.begin(); lsnd != _soundList.end(); ++lsnd) {
|
||||||
|
if ((*lsnd)->getStatus().status2 & 0x1) { // Sound is stopped
|
||||||
|
// original code
|
||||||
|
//if ((*lsnd)->soundBuffer)
|
||||||
|
// Sound_RemoveSoundDataFromCache(*lsnd);
|
||||||
|
//if ((*lsnd)->archive) {
|
||||||
|
// Archive_SetStatusNotLoaded((*lsnd)->archive);
|
||||||
|
// (*lsnd)->archive = 0;
|
||||||
|
// (*lsnd)->field_28 = 3;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (_soundList.size() < 6) {
|
||||||
|
if ((*lsnd)->getStatus().status1 & 0x1F) {
|
||||||
|
int pri = (*lsnd)->getPriority() + ((*lsnd)->getStatus().status1 & 0x1F);
|
||||||
|
|
||||||
|
if (pri > maxPriority) {
|
||||||
|
msnd = *lsnd;
|
||||||
|
maxPriority = pri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(*lsnd)->updateSound() && !((*lsnd)->getStatus().status3 & 0x8)) {
|
||||||
|
if (msnd == *lsnd) {
|
||||||
|
maxPriority = 0;
|
||||||
|
msnd = 0;
|
||||||
|
}
|
||||||
|
if (*lsnd) {
|
||||||
|
(*lsnd)->close();
|
||||||
|
SAFE_DELETE(*lsnd);
|
||||||
|
lsnd = _soundList.reverse_erase(lsnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// We don't need this
|
||||||
|
//if (msnd)
|
||||||
|
// msnd->updateEntryInternal();
|
||||||
|
|
||||||
|
getFlags()->flag_3 = 0;
|
||||||
|
//--g_sound_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundQueue::resetQueue() {
|
void SoundQueue::resetQueue() {
|
||||||
|
@ -301,11 +363,11 @@ void SoundQueue::updateSubtitles() {
|
||||||
if (!(status & kSoundStatus_40)
|
if (!(status & kSoundStatus_40)
|
||||||
|| status & kSoundStatus_180
|
|| status & kSoundStatus_180
|
||||||
|| soundEntry->getTime() == 0
|
|| soundEntry->getTime() == 0
|
||||||
|| (status & kSoundStatusClear1) < 6
|
|| (status & kSoundStatusFilter) < 6
|
||||||
|| ((getFlags()->nis & 0x8000) && soundEntry->getPriority() < 90)) {
|
|| ((getFlags()->nis & 0x8000) && soundEntry->getPriority() < 90)) {
|
||||||
current_index = 0;
|
current_index = 0;
|
||||||
} else {
|
} else {
|
||||||
current_index = soundEntry->getPriority() + (status & kSoundStatusClear1);
|
current_index = soundEntry->getPriority() + (status & kSoundStatusFilter);
|
||||||
|
|
||||||
if (_currentSubtitle == (*i))
|
if (_currentSubtitle == (*i))
|
||||||
current_index += 4;
|
current_index += 4;
|
||||||
|
@ -333,66 +395,6 @@ void SoundQueue::updateSubtitles() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Cache
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
bool SoundQueue::setupCache(SoundEntry *entry) {
|
|
||||||
if (entry->_soundData)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (_soundCache.size() >= SOUNDCACHE_MAX_SIZE) {
|
|
||||||
|
|
||||||
SoundEntry *cacheEntry = NULL;
|
|
||||||
uint32 size = 1000;
|
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
|
|
||||||
if (!((*i)->getStatus().status & kSoundStatus_180)) {
|
|
||||||
uint32 newSize = (*i)->getPriority() + ((*i)->getStatus().status & kSoundStatusClear1);
|
|
||||||
|
|
||||||
if (newSize < size) {
|
|
||||||
cacheEntry = (*i);
|
|
||||||
size = newSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry->getPriority() <= size)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!cacheEntry)
|
|
||||||
error("[SoundManager::setupCache] Cannot find a valid entry");
|
|
||||||
|
|
||||||
cacheEntry->setInCache();
|
|
||||||
|
|
||||||
// TODO: Wait until the cache entry is ready to be removed
|
|
||||||
while (!(cacheEntry->getStatus().status1 & 1))
|
|
||||||
;
|
|
||||||
|
|
||||||
if (cacheEntry->_soundData)
|
|
||||||
removeFromCache(cacheEntry);
|
|
||||||
|
|
||||||
_soundCache.push_back(entry);
|
|
||||||
entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
|
|
||||||
} else {
|
|
||||||
_soundCache.push_back(entry);
|
|
||||||
entry->_soundData = (char *)_soundCacheData + SOUNDCACHE_ENTRY_SIZE * (_soundCache.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SoundQueue::removeFromCache(SoundEntry *entry) {
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundCache.begin(); i != _soundCache.end(); ++i) {
|
|
||||||
if ((*i) == entry) {
|
|
||||||
// Remove sound buffer
|
|
||||||
entry->_soundData = NULL;
|
|
||||||
|
|
||||||
// Remove entry from sound cache
|
|
||||||
i = _soundCache.reverse_erase(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Savegame
|
// Savegame
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -431,355 +433,6 @@ uint32 SoundQueue::count() {
|
||||||
return numEntries;
|
return numEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Sound filters
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
static const int filterData[1424] = {
|
|
||||||
0, 0, 0, 0, 128, 256, 384, 512, 0, 0, 0, 0, 128, 256,
|
|
||||||
384, 512, 0, 0, 0, 0, 192, 320, 448, 576, 0, 0, 0, 0,
|
|
||||||
192, 320, 448, 576, 64, 64, 64, 64, 256, 384, 512, 640,
|
|
||||||
64, 64, 64, 64, 256, 384, 512, 640, 128, 128, 128, 128,
|
|
||||||
320, 448, 576, 704, 128, 128, 128, 128, 320, 448, 576,
|
|
||||||
704, 192, 192, 192, 192, 384, 512, 640, 768, 192, 192,
|
|
||||||
192, 192, 384, 512, 640, 768, 256, 256, 256, 256, 448,
|
|
||||||
576, 704, 832, 256, 256, 256, 256, 448, 576, 704, 832,
|
|
||||||
320, 320, 320, 320, 512, 640, 768, 896, 320, 320, 320,
|
|
||||||
320, 512, 640, 768, 896, 384, 384, 384, 384, 576, 704,
|
|
||||||
832, 960, 384, 384, 384, 384, 576, 704, 832, 960, 448,
|
|
||||||
448, 448, 448, 640, 768, 896, 1024, 448, 448, 448, 448,
|
|
||||||
640, 768, 896, 1024, 512, 512, 512, 512, 704, 832, 960,
|
|
||||||
1088, 512, 512, 512, 512, 704, 832, 960, 1088, 576,
|
|
||||||
576, 576, 576, 768, 896, 1024, 1152, 576, 576, 576,
|
|
||||||
576, 768, 896, 1024, 1152, 640, 640, 640, 640, 832,
|
|
||||||
960, 1088, 1216, 640, 640, 640, 640, 832, 960, 1088,
|
|
||||||
1216, 704, 704, 704, 704, 896, 1024, 1152, 1280, 704,
|
|
||||||
704, 704, 704, 896, 1024, 1152, 1280, 768, 768, 768,
|
|
||||||
768, 960, 1088, 1216, 1344, 768, 768, 768, 768, 960,
|
|
||||||
1088, 1216, 1344, 832, 832, 832, 832, 1024, 1152, 1280,
|
|
||||||
1408, 832, 832, 832, 832, 1024, 1152, 1280, 1408, 896,
|
|
||||||
896, 896, 896, 1088, 1216, 1344, 1472, 896, 896, 896,
|
|
||||||
896, 1088, 1216, 1344, 1472, 960, 960, 960, 960, 1152,
|
|
||||||
1280, 1408, 1536, 960, 960, 960, 960, 1152, 1280, 1408,
|
|
||||||
1536, 1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600,
|
|
||||||
1024, 1024, 1024, 1024, 1216, 1344, 1472, 1600, 1088,
|
|
||||||
1088, 1088, 1088, 1280, 1408, 1536, 1664, 1088, 1088,
|
|
||||||
1088, 1088, 1280, 1408, 1536, 1664, 1152, 1152, 1152,
|
|
||||||
1152, 1344, 1472, 1600, 1728, 1152, 1152, 1152, 1152,
|
|
||||||
1344, 1472, 1600, 1728, 1216, 1216, 1216, 1216, 1408,
|
|
||||||
1536, 1664, 1792, 1216, 1216, 1216, 1216, 1408, 1536,
|
|
||||||
1664, 1792, 1280, 1280, 1280, 1280, 1472, 1600, 1728,
|
|
||||||
1856, 1280, 1280, 1280, 1280, 1472, 1600, 1728, 1856,
|
|
||||||
1344, 1344, 1344, 1344, 1536, 1664, 1792, 1920, 1344,
|
|
||||||
1344, 1344, 1344, 1536, 1664, 1792, 1920, 1408, 1408,
|
|
||||||
1408, 1408, 1600, 1728, 1856, 1984, 1408, 1408, 1408,
|
|
||||||
1408, 1600, 1728, 1856, 1984, 1472, 1472, 1472, 1472,
|
|
||||||
1664, 1792, 1920, 2048, 1472, 1472, 1472, 1472, 1664,
|
|
||||||
1792, 1920, 2048, 1536, 1536, 1536, 1536, 1728, 1856,
|
|
||||||
1984, 2112, 1536, 1536, 1536, 1536, 1728, 1856, 1984,
|
|
||||||
2112, 1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176,
|
|
||||||
1600, 1600, 1600, 1600, 1792, 1920, 2048, 2176, 1664,
|
|
||||||
1664, 1664, 1664, 1856, 1984, 2112, 2240, 1664, 1664,
|
|
||||||
1664, 1664, 1856, 1984, 2112, 2240, 1728, 1728, 1728,
|
|
||||||
1728, 1920, 2048, 2176, 2304, 1728, 1728, 1728, 1728,
|
|
||||||
1920, 2048, 2176, 2304, 1792, 1792, 1792, 1792, 1984,
|
|
||||||
2112, 2240, 2368, 1792, 1792, 1792, 1792, 1984, 2112,
|
|
||||||
2240, 2368, 1856, 1856, 1856, 1856, 2048, 2176, 2304,
|
|
||||||
2432, 1856, 1856, 1856, 1856, 2048, 2176, 2304, 2432,
|
|
||||||
1920, 1920, 1920, 1920, 2112, 2240, 2368, 2496, 1920,
|
|
||||||
1920, 1920, 1920, 2112, 2240, 2368, 2496, 1984, 1984,
|
|
||||||
1984, 1984, 2176, 2304, 2432, 2560, 1984, 1984, 1984,
|
|
||||||
1984, 2176, 2304, 2432, 2560, 2048, 2048, 2048, 2048,
|
|
||||||
2240, 2368, 2496, 2624, 2048, 2048, 2048, 2048, 2240,
|
|
||||||
2368, 2496, 2624, 2112, 2112, 2112, 2112, 2304, 2432,
|
|
||||||
2560, 2688, 2112, 2112, 2112, 2112, 2304, 2432, 2560,
|
|
||||||
2688, 2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752,
|
|
||||||
2176, 2176, 2176, 2176, 2368, 2496, 2624, 2752, 2240,
|
|
||||||
2240, 2240, 2240, 2432, 2560, 2688, 2816, 2240, 2240,
|
|
||||||
2240, 2240, 2432, 2560, 2688, 2816, 2304, 2304, 2304,
|
|
||||||
2304, 2496, 2624, 2752, 2880, 2304, 2304, 2304, 2304,
|
|
||||||
2496, 2624, 2752, 2880, 2368, 2368, 2368, 2368, 2560,
|
|
||||||
2688, 2816, 2944, 2368, 2368, 2368, 2368, 2560, 2688,
|
|
||||||
2816, 2944, 2432, 2432, 2432, 2432, 2624, 2752, 2880,
|
|
||||||
3008, 2432, 2432, 2432, 2432, 2624, 2752, 2880, 3008,
|
|
||||||
2496, 2496, 2496, 2496, 2688, 2816, 2944, 3072, 2496,
|
|
||||||
2496, 2496, 2496, 2688, 2816, 2944, 3072, 2560, 2560,
|
|
||||||
2560, 2560, 2752, 2880, 3008, 3136, 2560, 2560, 2560,
|
|
||||||
2560, 2752, 2880, 3008, 3136, 2624, 2624, 2624, 2624,
|
|
||||||
2816, 2944, 3072, 3200, 2624, 2624, 2624, 2624, 2816,
|
|
||||||
2944, 3072, 3200, 2688, 2688, 2688, 2688, 2880, 3008,
|
|
||||||
3136, 3264, 2688, 2688, 2688, 2688, 2880, 3008, 3136,
|
|
||||||
3264, 2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328,
|
|
||||||
2752, 2752, 2752, 2752, 2944, 3072, 3200, 3328, 2816,
|
|
||||||
2816, 2816, 2816, 3008, 3136, 3264, 3392, 2816, 2816,
|
|
||||||
2816, 2816, 3008, 3136, 3264, 3392, 2880, 2880, 2880,
|
|
||||||
2880, 3072, 3200, 3328, 3456, 2880, 2880, 2880, 2880,
|
|
||||||
3072, 3200, 3328, 3456, 2944, 2944, 2944, 2944, 3136,
|
|
||||||
3264, 3392, 3520, 2944, 2944, 2944, 2944, 3136, 3264,
|
|
||||||
3392, 3520, 3008, 3008, 3008, 3008, 3200, 3328, 3456,
|
|
||||||
3584, 3008, 3008, 3008, 3008, 3200, 3328, 3456, 3584,
|
|
||||||
3072, 3072, 3072, 3072, 3264, 3392, 3520, 3648, 3072,
|
|
||||||
3072, 3072, 3072, 3264, 3392, 3520, 3648, 3136, 3136,
|
|
||||||
3136, 3136, 3328, 3456, 3584, 3712, 3136, 3136, 3136,
|
|
||||||
3136, 3328, 3456, 3584, 3712, 3200, 3200, 3200, 3200,
|
|
||||||
3392, 3520, 3648, 3776, 3200, 3200, 3200, 3200, 3392,
|
|
||||||
3520, 3648, 3776, 3264, 3264, 3264, 3264, 3456, 3584,
|
|
||||||
3712, 3840, 3264, 3264, 3264, 3264, 3456, 3584, 3712,
|
|
||||||
3840, 3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904,
|
|
||||||
3328, 3328, 3328, 3328, 3520, 3648, 3776, 3904, 3392,
|
|
||||||
3392, 3392, 3392, 3584, 3712, 3840, 3968, 3392, 3392,
|
|
||||||
3392, 3392, 3584, 3712, 3840, 3968, 3456, 3456, 3456,
|
|
||||||
3456, 3648, 3776, 3904, 4032, 3456, 3456, 3456, 3456,
|
|
||||||
3648, 3776, 3904, 4032, 3520, 3520, 3520, 3520, 3712,
|
|
||||||
3840, 3968, 4096, 3520, 3520, 3520, 3520, 3712, 3840,
|
|
||||||
3968, 4096, 3584, 3584, 3584, 3584, 3776, 3904, 4032,
|
|
||||||
4160, 3584, 3584, 3584, 3584, 3776, 3904, 4032, 4160,
|
|
||||||
3648, 3648, 3648, 3648, 3840, 3968, 4096, 4224, 3648,
|
|
||||||
3648, 3648, 3648, 3840, 3968, 4096, 4224, 3712, 3712,
|
|
||||||
3712, 3712, 3904, 4032, 4160, 4288, 3712, 3712, 3712,
|
|
||||||
3712, 3904, 4032, 4160, 4288, 3776, 3776, 3776, 3776,
|
|
||||||
3968, 4096, 4224, 4352, 3776, 3776, 3776, 3776, 3968,
|
|
||||||
4096, 4224, 4352, 3840, 3840, 3840, 3840, 4032, 4160,
|
|
||||||
4288, 4416, 3840, 3840, 3840, 3840, 4032, 4160, 4288,
|
|
||||||
4416, 3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480,
|
|
||||||
3904, 3904, 3904, 3904, 4096, 4224, 4352, 4480, 3968,
|
|
||||||
3968, 3968, 3968, 4160, 4288, 4416, 4544, 3968, 3968,
|
|
||||||
3968, 3968, 4160, 4288, 4416, 4544, 4032, 4032, 4032,
|
|
||||||
4032, 4224, 4352, 4480, 4608, 4032, 4032, 4032, 4032,
|
|
||||||
4224, 4352, 4480, 4608, 4096, 4096, 4096, 4096, 4288,
|
|
||||||
4416, 4544, 4672, 4096, 4096, 4096, 4096, 4288, 4416,
|
|
||||||
4544, 4672, 4160, 4160, 4160, 4160, 4352, 4480, 4608,
|
|
||||||
4736, 4160, 4160, 4160, 4160, 4352, 4480, 4608, 4736,
|
|
||||||
4224, 4224, 4224, 4224, 4416, 4544, 4672, 4800, 4224,
|
|
||||||
4224, 4224, 4224, 4416, 4544, 4672, 4800, 4288, 4288,
|
|
||||||
4288, 4288, 4480, 4608, 4736, 4864, 4288, 4288, 4288,
|
|
||||||
4288, 4480, 4608, 4736, 4864, 4352, 4352, 4352, 4352,
|
|
||||||
4544, 4672, 4800, 4928, 4352, 4352, 4352, 4352, 4544,
|
|
||||||
4672, 4800, 4928, 4416, 4416, 4416, 4416, 4608, 4736,
|
|
||||||
4864, 4992, 4416, 4416, 4416, 4416, 4608, 4736, 4864,
|
|
||||||
4992, 4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056,
|
|
||||||
4480, 4480, 4480, 4480, 4672, 4800, 4928, 5056, 4544,
|
|
||||||
4544, 4544, 4544, 4736, 4864, 4992, 5120, 4544, 4544,
|
|
||||||
4544, 4544, 4736, 4864, 4992, 5120, 4608, 4608, 4608,
|
|
||||||
4608, 4800, 4928, 5056, 5184, 4608, 4608, 4608, 4608,
|
|
||||||
4800, 4928, 5056, 5184, 4672, 4672, 4672, 4672, 4864,
|
|
||||||
4992, 5120, 5248, 4672, 4672, 4672, 4672, 4864, 4992,
|
|
||||||
5120, 5248, 4736, 4736, 4736, 4736, 4928, 5056, 5184,
|
|
||||||
5312, 4736, 4736, 4736, 4736, 4928, 5056, 5184, 5312,
|
|
||||||
4800, 4800, 4800, 4800, 4992, 5120, 5248, 5376, 4800,
|
|
||||||
4800, 4800, 4800, 4992, 5120, 5248, 5376, 4864, 4864,
|
|
||||||
4864, 4864, 5056, 5184, 5312, 5440, 4864, 4864, 4864,
|
|
||||||
4864, 5056, 5184, 5312, 5440, 4928, 4928, 4928, 4928,
|
|
||||||
5120, 5248, 5376, 5504, 4928, 4928, 4928, 4928, 5120,
|
|
||||||
5248, 5376, 5504, 4992, 4992, 4992, 4992, 5184, 5312,
|
|
||||||
5440, 5568, 4992, 4992, 4992, 4992, 5184, 5312, 5440,
|
|
||||||
5568, 5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632,
|
|
||||||
5056, 5056, 5056, 5056, 5248, 5376, 5504, 5632, 5120,
|
|
||||||
5120, 5120, 5120, 5312, 5440, 5568, 5632, 5120, 5120,
|
|
||||||
5120, 5120, 5312, 5440, 5568, 5632, 5184, 5184, 5184,
|
|
||||||
5184, 5376, 5504, 5632, 5632, 5184, 5184, 5184, 5184,
|
|
||||||
5376, 5504, 5632, 5632, 5248, 5248, 5248, 5248, 5440,
|
|
||||||
5568, 5632, 5632, 5248, 5248, 5248, 5248, 5440, 5568,
|
|
||||||
5632, 5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632,
|
|
||||||
5632, 5312, 5312, 5312, 5312, 5504, 5632, 5632, 5632,
|
|
||||||
5376, 5376, 5376, 5376, 5568, 5632, 5632, 5632, 5376,
|
|
||||||
5376, 5376, 5376, 5568, 5632, 5632, 5632, 5440, 5440,
|
|
||||||
5440, 5440, 5632, 5632, 5632, 5632, 5440, 5440, 5440,
|
|
||||||
5440, 5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504,
|
|
||||||
5632, 5632, 5632, 5632, 5504, 5504, 5504, 5504, 5632,
|
|
||||||
5632, 5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632,
|
|
||||||
5632, 5632, 5568, 5568, 5568, 5568, 5632, 5632, 5632,
|
|
||||||
5632
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int filterData2[1424] = {
|
|
||||||
0, 2, 4, 6, 7, 9, 11, 13, 0, -2, -4, -6, -7, -9, -11,
|
|
||||||
-13, 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9,
|
|
||||||
-11, -13, -15, 1, 3, 5, 7, 10, 12, 14, 16, -1, -3, -5,
|
|
||||||
-7, -10, -12, -14, -16, 1, 3, 6, 8, 11, 13, 16, 18,
|
|
||||||
-1, -3, -6, -8, -11, -13, -16, -18, 1, 4, 6, 9, 12,
|
|
||||||
15, 17, 20, -1, -4, -6, -9, -12, -15, -17, -20, 1, 4,
|
|
||||||
7, 10, 13, 16, 19, 22, -1, -4, -7, -10, -13, -16, -19,
|
|
||||||
-22, 1, 4, 8, 11, 14, 17, 21, 24, -1, -4, -8, -11, -14,
|
|
||||||
-17, -21, -24, 1, 5, 8, 12, 15, 19, 22, 26, -1, -5,
|
|
||||||
-8, -12, -15, -19, -22, -26, 2, 6, 10, 14, 18, 22, 26,
|
|
||||||
30, -2, -6, -10, -14, -18, -22, -26, -30, 2, 6, 10,
|
|
||||||
14, 19, 23, 27, 31, -2, -6, -10, -14, -19, -23, -27,
|
|
||||||
-31, 2, 7, 11, 16, 21, 26, 30, 35, -2, -7, -11, -16,
|
|
||||||
-21, -26, -30, -35, 2, 7, 13, 18, 23, 28, 34, 39, -2,
|
|
||||||
-7, -13, -18, -23, -28, -34, -39, 2, 8, 14, 20, 25,
|
|
||||||
31, 37, 43, -2, -8, -14, -20, -25, -31, -37, -43, 3,
|
|
||||||
9, 15, 21, 28, 34, 40, 46, -3, -9, -15, -21, -28, -34,
|
|
||||||
-40, -46, 3, 10, 17, 24, 31, 38, 45, 52, -3, -10, -17,
|
|
||||||
-24, -31, -38, -45, -52, 3, 11, 19, 27, 34, 42, 50,
|
|
||||||
58, -3, -11, -19, -27, -34, -42, -50, -58, 4, 12, 21,
|
|
||||||
29, 38, 46, 55, 63, -4, -12, -21, -29, -38, -46, -55,
|
|
||||||
-63, 4, 13, 23, 32, 41, 50, 60, 69, -4, -13, -23, -32,
|
|
||||||
-41, -50, -60, -69, 5, 15, 25, 35, 46, 56, 66, 76, -5,
|
|
||||||
-15, -25, -35, -46, -56, -66, -76, 5, 16, 28, 39, 50,
|
|
||||||
61, 73, 84, -5, -16, -28, -39, -50, -61, -73, -84, 6,
|
|
||||||
18, 31, 43, 56, 68, 81, 93, -6, -18, -31, -43, -56,
|
|
||||||
-68, -81, -93, 6, 20, 34, 48, 61, 75, 89, 103, -6, -20,
|
|
||||||
-34, -48, -61, -75, -89, -103, 7, 22, 37, 52, 67, 82,
|
|
||||||
97, 112, -7, -22, -37, -52, -67, -82, -97, -112, 8,
|
|
||||||
24, 41, 57, 74, 90, 107, 123, -8, -24, -41, -57, -74,
|
|
||||||
-90, -107, -123, 9, 27, 45, 63, 82, 100, 118, 136, -9,
|
|
||||||
-27, -45, -63, -82, -100, -118, -136, 10, 30, 50, 70,
|
|
||||||
90, 110, 130, 150, -10, -30, -50, -70, -90, -110, -130,
|
|
||||||
-150, 11, 33, 55, 77, 99, 121, 143, 165, -11, -33, -55,
|
|
||||||
-77, -99, -121, -143, -165, 12, 36, 60, 84, 109, 133,
|
|
||||||
157, 181, -12, -36, -60, -84, -109, -133, -157, -181,
|
|
||||||
13, 40, 66, 93, 120, 147, 173, 200, -13, -40, -66, -93,
|
|
||||||
-120, -147, -173, -200, 14, 44, 73, 103, 132, 162, 191,
|
|
||||||
221, -14, -44, -73, -103, -132, -162, -191, -221, 16,
|
|
||||||
48, 81, 113, 146, 178, 211, 243, -16, -48, -81, -113,
|
|
||||||
-146, -178, -211, -243, 17, 53, 89, 125, 160, 196, 232,
|
|
||||||
268, -17, -53, -89, -125, -160, -196, -232, -268, 19,
|
|
||||||
58, 98, 137, 176, 215, 255, 294, -19, -58, -98, -137,
|
|
||||||
-176, -215, -255, -294, 21, 64, 108, 151, 194, 237,
|
|
||||||
281, 324, -21, -64, -108, -151, -194, -237, -281, -324,
|
|
||||||
23, 71, 118, 166, 213, 261, 308, 356, -23, -71, -118,
|
|
||||||
-166, -213, -261, -308, -356, 26, 78, 130, 182, 235,
|
|
||||||
287, 339, 391, -26, -78, -130, -182, -235, -287, -339,
|
|
||||||
-391, 28, 86, 143, 201, 258, 316, 373, 431, -28, -86,
|
|
||||||
-143, -201, -258, -316, -373, -431, 31, 94, 158, 221,
|
|
||||||
284, 347, 411, 474, -31, -94, -158, -221, -284, -347,
|
|
||||||
-411, -474, 34, 104, 174, 244, 313, 383, 453, 523, -34,
|
|
||||||
-104, -174, -244, -313, -383, -453, -523, 38, 115, 191,
|
|
||||||
268, 345, 422, 498, 575, -38, -115, -191, -268, -345,
|
|
||||||
-422, -498, -575, 42, 126, 210, 294, 379, 463, 547,
|
|
||||||
631, -42, -126, -210, -294, -379, -463, -547, -631,
|
|
||||||
46, 139, 231, 324, 417, 510, 602, 695, -46, -139, -231,
|
|
||||||
-324, -417, -510, -602, -695, 51, 153, 255, 357, 459,
|
|
||||||
561, 663, 765, -51, -153, -255, -357, -459, -561, -663,
|
|
||||||
-765, 56, 168, 280, 392, 505, 617, 729, 841, -56, -168,
|
|
||||||
-280, -392, -505, -617, -729, -841, 61, 185, 308, 432,
|
|
||||||
555, 679, 802, 926, -61, -185, -308, -432, -555, -679,
|
|
||||||
-802, -926, 68, 204, 340, 476, 612, 748, 884, 1020,
|
|
||||||
-68, -204, -340, -476, -612, -748, -884, -1020, 74,
|
|
||||||
224, 373, 523, 672, 822, 971, 1121, -74, -224, -373,
|
|
||||||
-523, -672, -822, -971, -1121, 82, 246, 411, 575, 740,
|
|
||||||
904, 1069, 1233, -82, -246, -411, -575, -740, -904,
|
|
||||||
-1069, -1233, 90, 271, 452, 633, 814, 995, 1176, 1357,
|
|
||||||
-90, -271, -452, -633, -814, -995, -1176, -1357, 99,
|
|
||||||
298, 497, 696, 895, 1094, 1293, 1492, -99, -298, -497,
|
|
||||||
-696, -895, -1094, -1293, -1492, 109, 328, 547, 766,
|
|
||||||
985, 1204, 1423, 1642, -109, -328, -547, -766, -985,
|
|
||||||
-1204, -1423, -1642, 120, 361, 601, 842, 1083, 1324,
|
|
||||||
1564, 1805, -120, -361, -601, -842, -1083, -1324, -1564,
|
|
||||||
-1805, 132, 397, 662, 927, 1192, 1457, 1722, 1987, -132,
|
|
||||||
-397, -662, -927, -1192, -1457, -1722, -1987, 145, 437,
|
|
||||||
728, 1020, 1311, 1603, 1894, 2186, -145, -437, -728,
|
|
||||||
-1020, -1311, -1603, -1894, -2186, 160, 480, 801, 1121,
|
|
||||||
1442, 1762, 2083, 2403, -160, -480, -801, -1121, -1442,
|
|
||||||
-1762, -2083, -2403, 176, 529, 881, 1234, 1587, 1940,
|
|
||||||
2292, 2645, -176, -529, -881, -1234, -1587, -1940, -2292,
|
|
||||||
-2645, 194, 582, 970, 1358, 1746, 2134, 2522, 2910,
|
|
||||||
-194, -582, -970, -1358, -1746, -2134, -2522, -2910,
|
|
||||||
213, 640, 1066, 1493, 1920, 2347, 2773, 3200, -213,
|
|
||||||
-640, -1066, -1493, -1920, -2347, -2773, -3200, 234,
|
|
||||||
704, 1173, 1643, 2112, 2582, 3051, 3521, -234, -704,
|
|
||||||
-1173, -1643, -2112, -2582, -3051, -3521, 258, 774,
|
|
||||||
1291, 1807, 2324, 2840, 3357, 3873, -258, -774, -1291,
|
|
||||||
-1807, -2324, -2840, -3357, -3873, 284, 852, 1420, 1988,
|
|
||||||
2556, 3124, 3692, 4260, -284, -852, -1420, -1988, -2556,
|
|
||||||
-3124, -3692, -4260, 312, 937, 1561, 2186, 2811, 3436,
|
|
||||||
4060, 4685, -312, -937, -1561, -2186, -2811, -3436,
|
|
||||||
-4060, -4685, 343, 1030, 1718, 2405, 3092, 3779, 4467,
|
|
||||||
5154, -343, -1030, -1718, -2405, -3092, -3779, -4467,
|
|
||||||
-5154, 378, 1134, 1890, 2646, 3402, 4158, 4914, 5670,
|
|
||||||
-378, -1134, -1890, -2646, -3402, -4158, -4914, -5670,
|
|
||||||
415, 1247, 2079, 2911, 3742, 4574, 5406, 6238, -415,
|
|
||||||
-1247, -2079, -2911, -3742, -4574, -5406, -6238, 457,
|
|
||||||
1372, 2287, 3202, 4117, 5032, 5947, 6862, -457, -1372,
|
|
||||||
-2287, -3202, -4117, -5032, -5947, -6862, 503, 1509,
|
|
||||||
2516, 3522, 4529, 5535, 6542, 7548, -503, -1509, -2516,
|
|
||||||
-3522, -4529, -5535, -6542, -7548, 553, 1660, 2767,
|
|
||||||
3874, 4981, 6088, 7195, 8302, -553, -1660, -2767, -3874,
|
|
||||||
-4981, -6088, -7195, -8302, 608, 1826, 3044, 4262, 5479,
|
|
||||||
6697, 7915, 9133, -608, -1826, -3044, -4262, -5479,
|
|
||||||
-6697, -7915, -9133, 669, 2009, 3348, 4688, 6027, 7367,
|
|
||||||
8706, 10046, -669, -2009, -3348, -4688, -6027, -7367,
|
|
||||||
-8706, -10046, 736, 2210, 3683, 5157, 6630, 8104, 9577,
|
|
||||||
11051, -736, -2210, -3683, -5157, -6630, -8104, -9577,
|
|
||||||
-11051, 810, 2431, 4052, 5673, 7294, 8915, 10536, 12157,
|
|
||||||
-810, -2431, -4052, -5673, -7294, -8915, -10536, -12157,
|
|
||||||
891, 2674, 4457, 6240, 8023, 9806, 11589, 13372, -891,
|
|
||||||
-2674, -4457, -6240, -8023, -9806, -11589, -13372, 980,
|
|
||||||
2941, 4903, 6864, 8825, 10786, 12748, 14709, -980, -2941,
|
|
||||||
-4903, -6864, -8825, -10786, -12748, -14709, 1078, 3236,
|
|
||||||
5393, 7551, 9708, 11866, 14023, 16181, -1078, -3236,
|
|
||||||
-5393, -7551, -9708, -11866, -14023, -16181, 1186, 3559,
|
|
||||||
5933, 8306, 10679, 13052, 15426, 17799, -1186, -3559,
|
|
||||||
-5933, -8306, -10679, -13052, -15426, -17799, 1305,
|
|
||||||
3915, 6526, 9136, 11747, 14357, 16968, 19578, -1305,
|
|
||||||
-3915, -6526, -9136, -11747, -14357, -16968, -19578,
|
|
||||||
1435, 4307, 7179, 10051, 12922, 15794, 18666, 21538,
|
|
||||||
-1435, -4307, -7179, -10051, -12922, -15794, -18666,
|
|
||||||
-21538, 1579, 4738, 7896, 11055, 14214, 17373, 20531,
|
|
||||||
23690, -1579, -4738, -7896, -11055, -14214, -17373,
|
|
||||||
-20531, -23690, 1737, 5212, 8686, 12161, 15636, 19111,
|
|
||||||
22585, 26060, -1737, -5212, -8686, -12161, -15636, -19111,
|
|
||||||
-22585, -26060, 1911, 5733, 9555, 13377, 17200, 21022,
|
|
||||||
24844, 28666, -1911, -5733, -9555, -13377, -17200, -21022,
|
|
||||||
-24844, -28666, 2102, 6306, 10511, 14715, 18920, 23124,
|
|
||||||
27329, 31533, -2102, -6306, -10511, -14715, -18920,
|
|
||||||
-23124, -27329, -31533, 2312, 6937, 11562, 16187, 20812,
|
|
||||||
25437, 30062, 32767, -2312, -6937, -11562, -16187, -20812,
|
|
||||||
-25437, -30062, -32767, 2543, 7631, 12718, 17806, 22893,
|
|
||||||
27981, 32767, 32767, -2543, -7631, -12718, -17806, -22893,
|
|
||||||
-27981, -32767, -32767, 2798, 8394, 13990, 19586, 25183,
|
|
||||||
30779, 32767, 32767, -2798, -8394, -13990, -19586, -25183,
|
|
||||||
-30779, -32767, -32767, 3077, 9233, 15389, 21545, 27700,
|
|
||||||
32767, 32767, 32767, -3077, -9233, -15389, -21545, -27700,
|
|
||||||
-32767, -32767, -32767, 3385, 10157, 16928, 23700, 30471,
|
|
||||||
32767, 32767, 32767, -3385, -10157, -16928, -23700,
|
|
||||||
-30471, -32767, -32767, -32767, 3724, 11172, 18621,
|
|
||||||
26069, 32767, 32767, 32767, 32767, -3724, -11172, -18621,
|
|
||||||
-26069, -32767, -32767, -32767, -32767, 4095, 12287,
|
|
||||||
20479, 28671, 32767, 32767, 32767, 32767, -4095, -12287,
|
|
||||||
-20479, -28671, -32767, -32767, -32767, -32767
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int p1s[17] = { 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4, 0 };
|
|
||||||
static const int p2s[17] = { 0, 1, 1, 3, 1, 5, 3, 7, 1, 9, 5, 11, 3, 13, 7, 15, 1 };
|
|
||||||
|
|
||||||
static void soundFilter(byte *data, int16 *buffer, int p1, int p2);
|
|
||||||
|
|
||||||
void SoundQueue::applyFilter(SoundEntry *entry, int16 *buffer) {
|
|
||||||
if ((((byte *)entry->_soundData)[1] << 6) > 0x1600) {
|
|
||||||
entry->setStatus(entry->getStatus().status | kSoundStatus_20000000);
|
|
||||||
} else {
|
|
||||||
int variant = entry->getStatus().status & 0x1f;
|
|
||||||
|
|
||||||
soundFilter((byte *)entry->_soundData, buffer, p1s[variant], p2s[variant]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void soundFilter(byte *data, int16 *buffer, int p1, int p2) {
|
|
||||||
int data1, data2, data1p, data2p;
|
|
||||||
byte idx;
|
|
||||||
|
|
||||||
data2 = data[0];
|
|
||||||
data1 = data[1] << 6;
|
|
||||||
|
|
||||||
data += 2;
|
|
||||||
|
|
||||||
for (int count = 0; count < 735; count++) {
|
|
||||||
idx = data[count] >> 4;
|
|
||||||
data1p = filterData[idx + data1];
|
|
||||||
data2p = CLIP(filterData2[idx + data1] + data2, -32767, 32767);
|
|
||||||
|
|
||||||
buffer[2 * count] = (p2 * data2p) >> p1;
|
|
||||||
|
|
||||||
idx = data[count] & 0xF;
|
|
||||||
|
|
||||||
data1 = filterData[idx + data1p];
|
|
||||||
data2 = CLIP(filterData2[idx + data1p] + data2p, -32767, 32767);
|
|
||||||
buffer[2 * count + 1] = (p2 * data2) >> p1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Debug
|
// Debug
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -787,7 +440,7 @@ void SoundQueue::stopAllSound() {
|
||||||
Common::StackLock locker(_mutex);
|
Common::StackLock locker(_mutex);
|
||||||
|
|
||||||
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
for (Common::List<SoundEntry *>::iterator i = _soundList.begin(); i != _soundList.end(); ++i)
|
||||||
(*i)->getStreamedSound()->stop();
|
(*i)->getSoundStream()->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace LastExpress
|
} // End of namespace LastExpress
|
||||||
|
|
|
@ -78,9 +78,6 @@ public:
|
||||||
void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
|
void setCurrentSubtitle(SubtitleEntry *entry) { _currentSubtitle = entry; }
|
||||||
SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
|
SubtitleEntry *getCurrentSubtitle() { return _currentSubtitle; }
|
||||||
|
|
||||||
// Cache
|
|
||||||
bool setupCache(SoundEntry *entry);
|
|
||||||
|
|
||||||
// Serializable
|
// Serializable
|
||||||
void saveLoadWithSerializer(Common::Serializer &ser);
|
void saveLoadWithSerializer(Common::Serializer &ser);
|
||||||
uint32 count();
|
uint32 count();
|
||||||
|
@ -109,7 +106,6 @@ private:
|
||||||
|
|
||||||
// Entries
|
// Entries
|
||||||
Common::List<SoundEntry *> _soundList; ///< List of all sound entries
|
Common::List<SoundEntry *> _soundList; ///< List of all sound entries
|
||||||
Common::List<SoundEntry *> _soundCache; ///< List of entries with a data buffer
|
|
||||||
void *_soundCacheData;
|
void *_soundCacheData;
|
||||||
|
|
||||||
// Subtitles
|
// Subtitles
|
||||||
|
@ -117,12 +113,6 @@ private:
|
||||||
Common::List<SubtitleEntry *> _subtitles;
|
Common::List<SubtitleEntry *> _subtitles;
|
||||||
SubtitleEntry *_currentSubtitle;
|
SubtitleEntry *_currentSubtitle;
|
||||||
|
|
||||||
// Filters
|
|
||||||
int32 _buffer[2940]; ///< Static sound buffer
|
|
||||||
|
|
||||||
void removeFromCache(SoundEntry *entry);
|
|
||||||
void applyFilter(SoundEntry *entry, int16 *buffer);
|
|
||||||
|
|
||||||
friend class Debugger;
|
friend class Debugger;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -162,13 +162,17 @@ bool SoundManager::playSoundWithSubtitles(Common::String filename, SoundFlag fla
|
||||||
entry->setStatus(entry->getStatus().status | kSoundStatus_8000);
|
entry->setStatus(entry->getStatus().status | kSoundStatus_8000);
|
||||||
} else {
|
} else {
|
||||||
// Get subtitles name
|
// Get subtitles name
|
||||||
while (filename.size() > 4)
|
uint32 size = filename.size();
|
||||||
|
while (filename.size() > size - 4)
|
||||||
filename.deleteLastChar();
|
filename.deleteLastChar();
|
||||||
|
|
||||||
entry->showSubtitle(filename);
|
entry->showSubtitle(filename);
|
||||||
entry->updateState();
|
entry->updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add entry to sound list
|
||||||
|
_queue->addToQueue(entry);
|
||||||
|
|
||||||
return (entry->getType() != kSoundTypeNone);
|
return (entry->getType() != kSoundTypeNone);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,13 @@ public:
|
||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
SoundQueue *getQueue() { return _queue; }
|
SoundQueue *getQueue() { return _queue; }
|
||||||
uint32 getData2() { return _data2; }
|
uint32 getData0() { return _data0; }
|
||||||
|
int32 getData1() { return _data1; }
|
||||||
|
int32 getData2() { return _data2; }
|
||||||
|
uint32 getLoopingSoundDuration() { return _loopingSoundDuration; }
|
||||||
|
|
||||||
|
// Setters
|
||||||
|
void setData1(int32 data) { _data1 = data; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LastExpressEngine *_engine;
|
LastExpressEngine *_engine;
|
||||||
|
@ -78,8 +84,8 @@ private:
|
||||||
|
|
||||||
// Unknown data
|
// Unknown data
|
||||||
uint32 _data0;
|
uint32 _data0;
|
||||||
uint32 _data1;
|
int32 _data1;
|
||||||
uint32 _data2;
|
int32 _data2;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace LastExpress
|
} // End of namespace LastExpress
|
||||||
|
|
|
@ -98,7 +98,6 @@ void Disk::openFile(uint8 fileNum) {
|
||||||
error("Could not open %s", sFilename);
|
error("Could not open %s", sFilename);
|
||||||
|
|
||||||
char buffer[7];
|
char buffer[7];
|
||||||
uint32 bytesRead;
|
|
||||||
|
|
||||||
// If it's the support file, then move to the correct language area
|
// If it's the support file, then move to the correct language area
|
||||||
|
|
||||||
|
@ -130,7 +129,7 @@ void Disk::openFile(uint8 fileNum) {
|
||||||
|
|
||||||
// Validate the header
|
// Validate the header
|
||||||
|
|
||||||
bytesRead = _fileHandle->read(buffer, 6);
|
_fileHandle->read(buffer, 6);
|
||||||
buffer[6] = '\0';
|
buffer[6] = '\0';
|
||||||
if (strcmp(buffer, HEADER_IDENT_STRING) != 0)
|
if (strcmp(buffer, HEADER_IDENT_STRING) != 0)
|
||||||
error("The file %s was not a valid VGA file", sFilename);
|
error("The file %s was not a valid VGA file", sFilename);
|
||||||
|
|
|
@ -763,7 +763,7 @@ void Hotspot::showMessage(uint16 messageId, uint16 destCharacterId) {
|
||||||
MemoryBlock *data = res.messagesData();
|
MemoryBlock *data = res.messagesData();
|
||||||
Hotspot *hotspot;
|
Hotspot *hotspot;
|
||||||
uint8 *msgData = (uint8 *) data->data();
|
uint8 *msgData = (uint8 *) data->data();
|
||||||
uint16 v2, idVal;
|
uint16 idVal;
|
||||||
messageId &= 0x7fff;
|
messageId &= 0x7fff;
|
||||||
|
|
||||||
// Skip through header to find table for given character
|
// Skip through header to find table for given character
|
||||||
|
@ -781,7 +781,6 @@ void Hotspot::showMessage(uint16 messageId, uint16 destCharacterId) {
|
||||||
|
|
||||||
// Scan through secondary list
|
// Scan through secondary list
|
||||||
uint16 *v = (uint16 *) (msgData + READ_LE_UINT16(msgData + idx + sizeof(uint16)));
|
uint16 *v = (uint16 *) (msgData + READ_LE_UINT16(msgData + idx + sizeof(uint16)));
|
||||||
v2 = 0;
|
|
||||||
while ((idVal = READ_LE_UINT16(v)) != 0xffff) {
|
while ((idVal = READ_LE_UINT16(v)) != 0xffff) {
|
||||||
++v;
|
++v;
|
||||||
if (READ_LE_UINT16(v) == messageId) break;
|
if (READ_LE_UINT16(v) == messageId) break;
|
||||||
|
|
|
@ -31,7 +31,9 @@
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
#include "audio/midiparser.h"
|
#include "audio/midiparser.h"
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
DECLARE_SINGLETON(Lure::SoundManager);
|
DECLARE_SINGLETON(Lure::SoundManager);
|
||||||
|
}
|
||||||
|
|
||||||
namespace Lure {
|
namespace Lure {
|
||||||
|
|
||||||
|
|
|
@ -542,7 +542,7 @@ public:
|
||||||
virtual bool hasFeature(MetaEngineFeature f) const;
|
virtual bool hasFeature(MetaEngineFeature f) const;
|
||||||
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
|
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
|
||||||
|
|
||||||
const ADGameDescription *fallbackDetect(const Common::FSList &fslist, const FileMap &allFiles) const;
|
const ADGameDescription *fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -564,7 +564,7 @@ bool MadeMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGame
|
||||||
return gd != 0;
|
return gd != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ADGameDescription *MadeMetaEngine::fallbackDetect(const Common::FSList &fslist, const FileMap &allFiles) const {
|
const ADGameDescription *MadeMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
|
||||||
// Set the default values for the fallback descriptor's ADGameDescription part.
|
// Set the default values for the fallback descriptor's ADGameDescription part.
|
||||||
Made::g_fallbackDesc.desc.language = Common::UNK_LANG;
|
Made::g_fallbackDesc.desc.language = Common::UNK_LANG;
|
||||||
Made::g_fallbackDesc.desc.platform = Common::kPlatformPC;
|
Made::g_fallbackDesc.desc.platform = Common::kPlatformPC;
|
||||||
|
|
|
@ -700,14 +700,25 @@ bool LivingBooksConsole::Cmd_DrawImage(int argc, const char **argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LivingBooksConsole::Cmd_ChangePage(int argc, const char **argv) {
|
bool LivingBooksConsole::Cmd_ChangePage(int argc, const char **argv) {
|
||||||
if (argc == 1) {
|
if (argc < 2 || argc > 3) {
|
||||||
DebugPrintf("Usage: changePage <page> [<mode>]\n");
|
DebugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm->tryLoadPageStart(argc == 2 ? _vm->getCurMode() : (LBMode)atoi(argv[2]), atoi(argv[1])))
|
int page, subpage = 0;
|
||||||
|
if (sscanf(argv[1], "%d.%d", &page, &subpage) == 0) {
|
||||||
|
DebugPrintf("Usage: changePage <page>[.<subpage>] [<mode>]\n");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
LBMode mode = argc == 2 ? _vm->getCurMode() : (LBMode)atoi(argv[2]);
|
||||||
|
if (subpage == 0) {
|
||||||
|
if (_vm->tryLoadPageStart(mode, page))
|
||||||
return false;
|
return false;
|
||||||
DebugPrintf("no such page %d\n", atoi(argv[1]));
|
} else {
|
||||||
|
if (_vm->loadPage(mode, page, subpage))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DebugPrintf("no such page %d.%d\n", page, subpage);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,6 +252,17 @@ void LivingBooksCursorManager_v2::setCursor(uint16 id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LivingBooksCursorManager_v2::setCursor(const Common::String &name) {
|
||||||
|
if (!_sysArchive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint16 id = _sysArchive->findResourceID(ID_TCUR, name);
|
||||||
|
if (id == 0xffff)
|
||||||
|
error("Could not find cursor '%s'", name.c_str());
|
||||||
|
else
|
||||||
|
setCursor(id);
|
||||||
|
}
|
||||||
|
|
||||||
PECursorManager::PECursorManager(const Common::String &appName) {
|
PECursorManager::PECursorManager(const Common::String &appName) {
|
||||||
_exe = new Common::PEResources();
|
_exe = new Common::PEResources();
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
virtual void showCursor();
|
virtual void showCursor();
|
||||||
virtual void hideCursor();
|
virtual void hideCursor();
|
||||||
virtual void setCursor(uint16 id);
|
virtual void setCursor(uint16 id);
|
||||||
|
virtual void setCursor(const Common::String &name) {}
|
||||||
virtual void setDefaultCursor();
|
virtual void setDefaultCursor();
|
||||||
virtual bool hasSource() const { return false; }
|
virtual bool hasSource() const { return false; }
|
||||||
|
|
||||||
|
@ -157,6 +158,7 @@ public:
|
||||||
~LivingBooksCursorManager_v2();
|
~LivingBooksCursorManager_v2();
|
||||||
|
|
||||||
void setCursor(uint16 id);
|
void setCursor(uint16 id);
|
||||||
|
void setCursor(const Common::String &name);
|
||||||
bool hasSource() const { return _sysArchive != 0; }
|
bool hasSource() const { return _sysArchive != 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1474,6 +1474,21 @@ static const MohawkGameDescription gameDescriptions[] = {
|
||||||
0
|
0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"arthurrace",
|
||||||
|
"",
|
||||||
|
AD_ENTRY1("BookOutline", "f0a9251824a648fce1b49cb7c1a0ba67"),
|
||||||
|
Common::EN_ANY,
|
||||||
|
Common::kPlatformMacintosh,
|
||||||
|
ADGF_UNSTABLE,
|
||||||
|
Common::GUIO_NONE
|
||||||
|
},
|
||||||
|
GType_LIVINGBOOKSV3,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
},
|
||||||
|
|
||||||
// From zerep in bug #3287894
|
// From zerep in bug #3287894
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,8 +87,14 @@ void LBPage::open(Archive *mhk, uint16 baseId) {
|
||||||
_baseId = baseId;
|
_baseId = baseId;
|
||||||
|
|
||||||
_vm->addArchive(_mhk);
|
_vm->addArchive(_mhk);
|
||||||
if (_vm->hasResource(ID_BCOD, baseId))
|
if (!_vm->hasResource(ID_BCOD, baseId)) {
|
||||||
|
// assume that BCOD is mandatory for v4/v5
|
||||||
|
if (_vm->getGameType() == GType_LIVINGBOOKSV4 || _vm->getGameType() == GType_LIVINGBOOKSV5)
|
||||||
|
error("missing BCOD resource (id %d)", baseId);
|
||||||
|
_code = new LBCode(_vm, 0);
|
||||||
|
} else {
|
||||||
_code = new LBCode(_vm, baseId);
|
_code = new LBCode(_vm, baseId);
|
||||||
|
}
|
||||||
|
|
||||||
loadBITL(baseId);
|
loadBITL(baseId);
|
||||||
for (uint i = 0; i < _items.size(); i++)
|
for (uint i = 0; i < _items.size(); i++)
|
||||||
|
@ -2300,8 +2306,6 @@ void LBItem::readData(uint16 type, uint16 size, Common::MemoryReadStreamEndian *
|
||||||
{
|
{
|
||||||
assert(size == 4);
|
assert(size == 4);
|
||||||
uint offset = stream->readUint32();
|
uint offset = stream->readUint32();
|
||||||
if (!_page->_code)
|
|
||||||
error("no BCOD?");
|
|
||||||
_page->_code->runCode(this, offset);
|
_page->_code->runCode(this, offset);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2823,8 +2827,6 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kLBOpSendExpression:
|
case kLBOpSendExpression:
|
||||||
if (!_page->_code)
|
|
||||||
error("no BCOD?");
|
|
||||||
_page->_code->runCode(this, entry->offset);
|
_page->_code->runCode(this, entry->offset);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2858,8 +2860,6 @@ int LBItem::runScriptEntry(LBScriptEntry *entry) {
|
||||||
case kLBOpJumpUnlessExpression:
|
case kLBOpJumpUnlessExpression:
|
||||||
case kLBOpBreakExpression:
|
case kLBOpBreakExpression:
|
||||||
case kLBOpJumpToExpression:
|
case kLBOpJumpToExpression:
|
||||||
if (!_page->_code)
|
|
||||||
error("no BCOD?");
|
|
||||||
{
|
{
|
||||||
LBValue r = _page->_code->runCode(this, entry->offset);
|
LBValue r = _page->_code->runCode(this, entry->offset);
|
||||||
// FIXME
|
// FIXME
|
||||||
|
@ -2884,257 +2884,24 @@ void LBItem::setNextTime(uint16 min, uint16 max, uint32 start) {
|
||||||
debug(9, "nextTime is now %d frames away", _nextTime - (uint)(_vm->_system->getMillis() / 16));
|
debug(9, "nextTime is now %d frames away", _nextTime - (uint)(_vm->_system->getMillis() / 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LBTokenType {
|
|
||||||
kLBNoToken,
|
|
||||||
kLBNameToken,
|
|
||||||
kLBStringToken,
|
|
||||||
kLBOperatorToken,
|
|
||||||
kLBIntegerToken,
|
|
||||||
kLBEndToken
|
|
||||||
};
|
|
||||||
|
|
||||||
static Common::String readToken(const Common::String &source, uint &pos, LBTokenType &type) {
|
|
||||||
Common::String token;
|
|
||||||
type = kLBNoToken;
|
|
||||||
|
|
||||||
bool done = false;
|
|
||||||
while (pos < source.size() && !done) {
|
|
||||||
if (type == kLBStringToken) {
|
|
||||||
if (source[pos] == '"') {
|
|
||||||
pos++;
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
token += source[pos];
|
|
||||||
pos++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (source[pos]) {
|
|
||||||
case ' ':
|
|
||||||
pos++;
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ')':
|
|
||||||
if (type == kLBNoToken) {
|
|
||||||
type = kLBEndToken;
|
|
||||||
return Common::String();
|
|
||||||
}
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ';':
|
|
||||||
if (type == kLBNoToken) {
|
|
||||||
pos++;
|
|
||||||
type = kLBEndToken;
|
|
||||||
return Common::String();
|
|
||||||
}
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '@':
|
|
||||||
// FIXME
|
|
||||||
error("found @ in string '%s', not supported yet", source.c_str());
|
|
||||||
|
|
||||||
case '+':
|
|
||||||
case '-':
|
|
||||||
case '!':
|
|
||||||
case '=':
|
|
||||||
case '>':
|
|
||||||
case '<':
|
|
||||||
if (type == kLBNoToken)
|
|
||||||
type = kLBOperatorToken;
|
|
||||||
if (type == kLBOperatorToken)
|
|
||||||
token += source[pos];
|
|
||||||
else
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
if (type == kLBNoToken)
|
|
||||||
type = kLBStringToken;
|
|
||||||
else
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '0':
|
|
||||||
case '1':
|
|
||||||
case '2':
|
|
||||||
case '3':
|
|
||||||
case '4':
|
|
||||||
case '5':
|
|
||||||
case '6':
|
|
||||||
case '7':
|
|
||||||
case '8':
|
|
||||||
case '9':
|
|
||||||
if (type == kLBNoToken)
|
|
||||||
type = kLBIntegerToken;
|
|
||||||
if (type == kLBNameToken || type == kLBIntegerToken)
|
|
||||||
token += source[pos];
|
|
||||||
else
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (type == kLBNoToken)
|
|
||||||
type = kLBNameToken;
|
|
||||||
if (type == kLBNameToken)
|
|
||||||
token += source[pos];
|
|
||||||
else
|
|
||||||
done = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!done)
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == kLBStringToken)
|
|
||||||
error("readToken: ran out of input while parsing string from '%s'", source.c_str());
|
|
||||||
|
|
||||||
if (!token.size()) {
|
|
||||||
assert(type == kLBNoToken);
|
|
||||||
type = kLBEndToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
|
|
||||||
LBValue LBItem::parseValue(const Common::String &source, uint &pos) {
|
|
||||||
LBTokenType type, postOpType;
|
|
||||||
Common::String preOp, postOp;
|
|
||||||
|
|
||||||
Common::String str = readToken(source, pos, type);
|
|
||||||
if (type == kLBOperatorToken) {
|
|
||||||
preOp = str;
|
|
||||||
str = readToken(source, pos, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
LBValue value;
|
|
||||||
if (type == kLBStringToken) {
|
|
||||||
value.type = kLBValueString;
|
|
||||||
value.string = str;
|
|
||||||
} else if (type == kLBIntegerToken) {
|
|
||||||
value.type = kLBValueInteger;
|
|
||||||
value.integer = atoi(str.c_str());
|
|
||||||
} else if (type == kLBNameToken) {
|
|
||||||
value = _vm->_variables[str];
|
|
||||||
} else {
|
|
||||||
error("expected string/integer as value in '%s', got '%s'", source.c_str(), str.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint readAheadPos = pos;
|
|
||||||
postOp = readToken(source, readAheadPos, postOpType);
|
|
||||||
if (postOpType != kLBEndToken) {
|
|
||||||
if (postOpType != kLBOperatorToken)
|
|
||||||
error("expected operator after '%s' in '%s', got '%s'", str.c_str(), source.c_str(), postOp.c_str());
|
|
||||||
// might be a comparison operator, caller will handle other cases if valid
|
|
||||||
if (postOp == "-" || postOp == "+") {
|
|
||||||
pos = readAheadPos;
|
|
||||||
LBValue nextValue = parseValue(source, pos);
|
|
||||||
if (value.type != kLBValueInteger || nextValue.type != kLBValueInteger)
|
|
||||||
error("expected integer for arthmetic operator in '%s'", source.c_str());
|
|
||||||
if (postOp == "+")
|
|
||||||
value.integer += nextValue.integer;
|
|
||||||
else if (postOp == "-")
|
|
||||||
value.integer -= nextValue.integer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preOp.size()) {
|
|
||||||
if (preOp == "!") {
|
|
||||||
if (value.type == kLBValueInteger)
|
|
||||||
value.integer = !value.integer;
|
|
||||||
else
|
|
||||||
error("expected integer after ! operator in '%s'", source.c_str());
|
|
||||||
} else {
|
|
||||||
error("expected valid operator before '%s' in '%s', got '%s'", str.c_str(), source.c_str(), preOp.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LBItem::runCommand(const Common::String &command) {
|
void LBItem::runCommand(const Common::String &command) {
|
||||||
uint pos = 0;
|
LBCode tempCode(_vm, 0);
|
||||||
LBTokenType type;
|
|
||||||
|
|
||||||
debug(2, "running command '%s'", command.c_str());
|
debug(2, "running command '%s'", command.c_str());
|
||||||
|
|
||||||
while (pos < command.size()) {
|
uint offset = tempCode.parseCode(command);
|
||||||
Common::String varname = readToken(command, pos, type);
|
tempCode.runCode(this, offset);
|
||||||
if (type != kLBNameToken)
|
|
||||||
error("expected name as lvalue of command '%s', got '%s'", command.c_str(), varname.c_str());
|
|
||||||
Common::String op = readToken(command, pos, type);
|
|
||||||
if (type != kLBOperatorToken || (op != "=" && op != "++" && op != "--"))
|
|
||||||
error("expected assignment/postincrement/postdecrement operator for command '%s', got '%s'", command.c_str(), op.c_str());
|
|
||||||
|
|
||||||
if (op == "=") {
|
|
||||||
LBValue value = parseValue(command, pos);
|
|
||||||
_vm->_variables[varname] = value;
|
|
||||||
} else {
|
|
||||||
if (_vm->_variables[varname].type != kLBValueInteger)
|
|
||||||
error("expected integer after postincrement/postdecrement operator in '%s'", command.c_str());
|
|
||||||
if (op == "++")
|
|
||||||
_vm->_variables[varname].integer++;
|
|
||||||
else if (op == "--")
|
|
||||||
_vm->_variables[varname].integer--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos < command.size() && command[pos] == ';')
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LBItem::checkCondition(const Common::String &condition) {
|
bool LBItem::checkCondition(const Common::String &condition) {
|
||||||
uint pos = 0;
|
LBCode tempCode(_vm, 0);
|
||||||
LBTokenType type;
|
|
||||||
|
|
||||||
debug(3, "checking condition '%s'", condition.c_str());
|
debug(3, "checking condition '%s'", condition.c_str());
|
||||||
|
|
||||||
if (condition.size() <= pos || condition[pos] != '(')
|
uint offset = tempCode.parseCode(condition);
|
||||||
error("bad condition '%s' (started wrong)", condition.c_str());
|
LBValue result = tempCode.runCode(this, offset);
|
||||||
pos++;
|
|
||||||
|
|
||||||
LBValue value1 = parseValue(condition, pos);
|
return result.toInt();
|
||||||
|
|
||||||
Common::String op = readToken(condition, pos, type);
|
|
||||||
if (type == kLBEndToken) {
|
|
||||||
if (condition.size() != pos + 1 || condition[pos] != ')')
|
|
||||||
error("bad condition '%s' (ended wrong)", condition.c_str());
|
|
||||||
|
|
||||||
if (value1.type == kLBValueInteger)
|
|
||||||
return value1.integer;
|
|
||||||
else
|
|
||||||
error("expected comparison operator for condition '%s'", condition.c_str());
|
|
||||||
}
|
|
||||||
if (type != kLBOperatorToken || (op != "!=" && op != "==" && op != ">" && op != "<" && op != ">=" && op != "<="))
|
|
||||||
error("expected comparison operator for condition '%s', got '%s'", condition.c_str(), op.c_str());
|
|
||||||
|
|
||||||
LBValue value2 = parseValue(condition, pos);
|
|
||||||
|
|
||||||
if (condition.size() != pos + 1 || condition[pos] != ')')
|
|
||||||
error("bad condition '%s' (ended wrong)", condition.c_str());
|
|
||||||
|
|
||||||
if (op == "!=")
|
|
||||||
return (value1 != value2);
|
|
||||||
else if (op == "==")
|
|
||||||
return (value1 == value2);
|
|
||||||
|
|
||||||
if (value1.type != kLBValueInteger || value2.type != kLBValueInteger)
|
|
||||||
error("evaluation operator %s in condition '%s' expected two integer operands!", op.c_str(), condition.c_str());
|
|
||||||
|
|
||||||
if (op == ">")
|
|
||||||
return (value1.integer > value2.integer);
|
|
||||||
else if (op == ">=")
|
|
||||||
return (value1.integer >= value2.integer);
|
|
||||||
else if (op == "<")
|
|
||||||
return (value1.integer < value2.integer);
|
|
||||||
else if (op == "<=")
|
|
||||||
return (value1.integer <= value2.integer);
|
|
||||||
|
|
||||||
return false; // unreachable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LBSoundItem::LBSoundItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
|
LBSoundItem::LBSoundItem(MohawkEngine_LivingBooks *vm, LBPage *page, Common::Rect rect) : LBItem(vm, page, rect) {
|
||||||
|
|
|
@ -434,7 +434,6 @@ protected:
|
||||||
void runScript(uint event, uint16 data = 0, uint16 from = 0);
|
void runScript(uint event, uint16 data = 0, uint16 from = 0);
|
||||||
int runScriptEntry(LBScriptEntry *entry);
|
int runScriptEntry(LBScriptEntry *entry);
|
||||||
|
|
||||||
LBValue parseValue(const Common::String &command, uint &pos);
|
|
||||||
void runCommand(const Common::String &command);
|
void runCommand(const Common::String &command);
|
||||||
bool checkCondition(const Common::String &condition);
|
bool checkCondition(const Common::String &condition);
|
||||||
|
|
||||||
|
@ -689,6 +688,7 @@ public:
|
||||||
LBMode getCurMode() { return _curMode; }
|
LBMode getCurMode() { return _curMode; }
|
||||||
|
|
||||||
bool tryLoadPageStart(LBMode mode, uint page);
|
bool tryLoadPageStart(LBMode mode, uint page);
|
||||||
|
bool loadPage(LBMode mode, uint page, uint subpage);
|
||||||
void prevPage();
|
void prevPage();
|
||||||
void nextPage();
|
void nextPage();
|
||||||
|
|
||||||
|
@ -717,7 +717,6 @@ private:
|
||||||
Common::Queue<DelayedEvent> _eventQueue;
|
Common::Queue<DelayedEvent> _eventQueue;
|
||||||
LBItem *_focus;
|
LBItem *_focus;
|
||||||
void destroyPage();
|
void destroyPage();
|
||||||
bool loadPage(LBMode mode, uint page, uint subpage);
|
|
||||||
void updatePage();
|
void updatePage();
|
||||||
|
|
||||||
uint16 _lastSoundOwner, _lastSoundId;
|
uint16 _lastSoundOwner, _lastSoundId;
|
||||||
|
|
|
@ -127,6 +127,12 @@ Common::Rect LBValue::toRect() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
LBCode::LBCode(MohawkEngine_LivingBooks *vm, uint16 baseId) : _vm(vm) {
|
LBCode::LBCode(MohawkEngine_LivingBooks *vm, uint16 baseId) : _vm(vm) {
|
||||||
|
if (!baseId) {
|
||||||
|
_data = NULL;
|
||||||
|
_size = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Common::SeekableSubReadStreamEndian *bcodStream = _vm->wrapStreamEndian(ID_BCOD, baseId);
|
Common::SeekableSubReadStreamEndian *bcodStream = _vm->wrapStreamEndian(ID_BCOD, baseId);
|
||||||
|
|
||||||
uint32 totalSize = bcodStream->readUint32();
|
uint32 totalSize = bcodStream->readUint32();
|
||||||
|
@ -172,12 +178,8 @@ LBValue LBCode::runCode(LBItem *src, uint32 offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LBCode::nextToken() {
|
void LBCode::nextToken() {
|
||||||
if (_currOffset + 1 >= _size) {
|
if (_currOffset >= _size) {
|
||||||
// TODO
|
error("went off the end of code");
|
||||||
warning("went off the end of code");
|
|
||||||
_currToken = kTokenEndOfFile;
|
|
||||||
_currValue = LBValue();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_currToken = _data[_currOffset++];
|
_currToken = _data[_currOffset++];
|
||||||
|
@ -186,6 +188,8 @@ void LBCode::nextToken() {
|
||||||
switch (_currToken) {
|
switch (_currToken) {
|
||||||
case kTokenIdentifier:
|
case kTokenIdentifier:
|
||||||
{
|
{
|
||||||
|
if (_currOffset + 2 > _size)
|
||||||
|
error("went off the end of code reading identifier");
|
||||||
uint16 offset = READ_BE_UINT16(_data + _currOffset);
|
uint16 offset = READ_BE_UINT16(_data + _currOffset);
|
||||||
// TODO: check string exists
|
// TODO: check string exists
|
||||||
_currValue = _strings[offset];
|
_currValue = _strings[offset];
|
||||||
|
@ -195,9 +199,13 @@ void LBCode::nextToken() {
|
||||||
|
|
||||||
case kTokenLiteral:
|
case kTokenLiteral:
|
||||||
{
|
{
|
||||||
|
if (_currOffset + 1 > _size)
|
||||||
|
error("went off the end of code reading literal");
|
||||||
byte literalType = _data[_currOffset++];
|
byte literalType = _data[_currOffset++];
|
||||||
switch (literalType) {
|
switch (literalType) {
|
||||||
case kLBCodeLiteralInteger:
|
case kLBCodeLiteralInteger:
|
||||||
|
if (_currOffset + 2 > _size)
|
||||||
|
error("went off the end of code reading literal integer");
|
||||||
_currValue = READ_BE_UINT16(_data + _currOffset);
|
_currValue = READ_BE_UINT16(_data + _currOffset);
|
||||||
_currOffset += 2;
|
_currOffset += 2;
|
||||||
break;
|
break;
|
||||||
|
@ -211,6 +219,8 @@ void LBCode::nextToken() {
|
||||||
case kTokenConstEventId:
|
case kTokenConstEventId:
|
||||||
case 0x5e: // TODO: ??
|
case 0x5e: // TODO: ??
|
||||||
case kTokenKeycode:
|
case kTokenKeycode:
|
||||||
|
if (_currOffset + 2 > _size)
|
||||||
|
error("went off the end of code reading immediate");
|
||||||
_currValue = READ_BE_UINT16(_data + _currOffset);
|
_currValue = READ_BE_UINT16(_data + _currOffset);
|
||||||
_currOffset += 2;
|
_currOffset += 2;
|
||||||
break;
|
break;
|
||||||
|
@ -227,6 +237,8 @@ void LBCode::nextToken() {
|
||||||
|
|
||||||
case kTokenString:
|
case kTokenString:
|
||||||
{
|
{
|
||||||
|
if (_currOffset + 2 > _size)
|
||||||
|
error("went off the end of code reading string");
|
||||||
uint16 offset = READ_BE_UINT16(_data + _currOffset);
|
uint16 offset = READ_BE_UINT16(_data + _currOffset);
|
||||||
// TODO: check string exists
|
// TODO: check string exists
|
||||||
_currValue = _strings[offset];
|
_currValue = _strings[offset];
|
||||||
|
@ -265,8 +277,7 @@ LBValue LBCode::runCode(byte terminator) {
|
||||||
void LBCode::parseStatement() {
|
void LBCode::parseStatement() {
|
||||||
parseComparisons();
|
parseComparisons();
|
||||||
|
|
||||||
if (_currToken != kTokenAnd && _currToken != kTokenOr)
|
while (_currToken == kTokenAnd || _currToken == kTokenOr) {
|
||||||
return;
|
|
||||||
byte op = _currToken;
|
byte op = _currToken;
|
||||||
if (op == kTokenAnd)
|
if (op == kTokenAnd)
|
||||||
debugN(" && ");
|
debugN(" && ");
|
||||||
|
@ -287,6 +298,7 @@ void LBCode::parseStatement() {
|
||||||
debugN(" [--> %s]", result ? "true" : "false");
|
debugN(" [--> %s]", result ? "true" : "false");
|
||||||
_stack.push(result);
|
_stack.push(result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LBCode::parseComparisons() {
|
void LBCode::parseComparisons() {
|
||||||
parseConcat();
|
parseConcat();
|
||||||
|
@ -353,9 +365,7 @@ void LBCode::parseComparisons() {
|
||||||
void LBCode::parseConcat() {
|
void LBCode::parseConcat() {
|
||||||
parseArithmetic1();
|
parseArithmetic1();
|
||||||
|
|
||||||
if (_currToken != kTokenConcat)
|
while (_currToken == kTokenConcat) {
|
||||||
return;
|
|
||||||
|
|
||||||
debugN(" & ");
|
debugN(" & ");
|
||||||
nextToken();
|
nextToken();
|
||||||
parseArithmetic1();
|
parseArithmetic1();
|
||||||
|
@ -366,13 +376,12 @@ void LBCode::parseConcat() {
|
||||||
debugN(" [--> \"%s\"]", result.c_str());
|
debugN(" [--> \"%s\"]", result.c_str());
|
||||||
_stack.push(result);
|
_stack.push(result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LBCode::parseArithmetic1() {
|
void LBCode::parseArithmetic1() {
|
||||||
parseArithmetic2();
|
parseArithmetic2();
|
||||||
|
|
||||||
if (_currToken != kTokenMinus && _currToken != kTokenPlus)
|
while (_currToken == kTokenMinus || _currToken == kTokenPlus) {
|
||||||
return;
|
|
||||||
|
|
||||||
byte op = _currToken;
|
byte op = _currToken;
|
||||||
if (op == kTokenMinus)
|
if (op == kTokenMinus)
|
||||||
debugN(" - ");
|
debugN(" - ");
|
||||||
|
@ -390,12 +399,61 @@ void LBCode::parseArithmetic1() {
|
||||||
result = val1.toInt() - val2.toInt();
|
result = val1.toInt() - val2.toInt();
|
||||||
else
|
else
|
||||||
result = val1.toInt() + val2.toInt();
|
result = val1.toInt() + val2.toInt();
|
||||||
|
debugN(" [--> %d]", result.toInt());
|
||||||
_stack.push(result);
|
_stack.push(result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LBCode::parseArithmetic2() {
|
void LBCode::parseArithmetic2() {
|
||||||
// FIXME: other math operators
|
|
||||||
parseMain();
|
parseMain();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
byte op = _currToken;
|
||||||
|
switch (op) {
|
||||||
|
case kTokenMultiply:
|
||||||
|
debugN(" * ");
|
||||||
|
break;
|
||||||
|
case kTokenDivide:
|
||||||
|
debugN(" / ");
|
||||||
|
break;
|
||||||
|
case kTokenIntDivide:
|
||||||
|
debugN(" div ");
|
||||||
|
break;
|
||||||
|
case kTokenModulo:
|
||||||
|
debugN(" %% ");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextToken();
|
||||||
|
parseMain();
|
||||||
|
|
||||||
|
LBValue val2 = _stack.pop();
|
||||||
|
LBValue val1 = _stack.pop();
|
||||||
|
LBValue result;
|
||||||
|
// TODO: cope with non-integers
|
||||||
|
if (op == kTokenMultiply) {
|
||||||
|
result = val1.toInt() * val2.toInt();
|
||||||
|
} else if (val2.toInt() == 0) {
|
||||||
|
result = 1;
|
||||||
|
} else {
|
||||||
|
switch (op) {
|
||||||
|
case kTokenDivide:
|
||||||
|
// TODO: fp divide
|
||||||
|
result = val1.toInt() / val2.toInt();
|
||||||
|
break;
|
||||||
|
case kTokenIntDivide:
|
||||||
|
result = val1.toInt() / val2.toInt();
|
||||||
|
break;
|
||||||
|
case kTokenModulo:
|
||||||
|
result = val1.toInt() % val2.toInt();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stack.push(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LBCode::parseMain() {
|
void LBCode::parseMain() {
|
||||||
|
@ -549,6 +607,16 @@ void LBCode::parseMain() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LBItem *LBCode::resolveItem(const LBValue &value) {
|
||||||
|
if (value.type == kLBValueItemPtr)
|
||||||
|
return value.item;
|
||||||
|
if (value.type == kLBValueString)
|
||||||
|
return _vm->getItemByName(value.string);
|
||||||
|
if (value.type == kLBValueInteger)
|
||||||
|
return _vm->getItemById(value.integer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Common::Array<LBValue> LBCode::readParams() {
|
Common::Array<LBValue> LBCode::readParams() {
|
||||||
Common::Array<LBValue> params;
|
Common::Array<LBValue> params;
|
||||||
|
|
||||||
|
@ -616,8 +684,8 @@ struct CodeCommandInfo {
|
||||||
|
|
||||||
#define NUM_GENERAL_COMMANDS 129
|
#define NUM_GENERAL_COMMANDS 129
|
||||||
CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
|
CodeCommandInfo generalCommandInfo[NUM_GENERAL_COMMANDS] = {
|
||||||
{ "eval", 0 },
|
{ "eval", &LBCode::cmdEval },
|
||||||
{ "random", 0 },
|
{ "random", &LBCode::cmdRandom },
|
||||||
{ "stringLen", 0 },
|
{ "stringLen", 0 },
|
||||||
{ "substring", 0 },
|
{ "substring", 0 },
|
||||||
{ "max", 0 },
|
{ "max", 0 },
|
||||||
|
@ -773,6 +841,26 @@ void LBCode::cmdUnimplemented(const Common::Array<LBValue> ¶ms) {
|
||||||
warning("unimplemented command called");
|
warning("unimplemented command called");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LBCode::cmdEval(const Common::Array<LBValue> ¶ms) {
|
||||||
|
// FIXME: v4 eval is different?
|
||||||
|
if (params.size() != 1)
|
||||||
|
error("incorrect number of parameters (%d) to eval", params.size());
|
||||||
|
|
||||||
|
LBCode tempCode(_vm, 0);
|
||||||
|
|
||||||
|
uint offset = tempCode.parseCode(params[0].toString());
|
||||||
|
_stack.push(tempCode.runCode(_currSource, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LBCode::cmdRandom(const Common::Array<LBValue> ¶ms) {
|
||||||
|
if (params.size() != 2)
|
||||||
|
error("incorrect number of parameters (%d) to random", params.size());
|
||||||
|
|
||||||
|
int min = params[0].toInt();
|
||||||
|
int max = params[1].toInt();
|
||||||
|
_stack.push(_vm->_rnd->getRandomNumberRng(min, max));
|
||||||
|
}
|
||||||
|
|
||||||
void LBCode::cmdGetRect(const Common::Array<LBValue> ¶ms) {
|
void LBCode::cmdGetRect(const Common::Array<LBValue> ¶ms) {
|
||||||
if (params.size() < 2) {
|
if (params.size() < 2) {
|
||||||
_stack.push(getRectFromParams(params));
|
_stack.push(getRectFromParams(params));
|
||||||
|
@ -915,7 +1003,7 @@ CodeCommandInfo itemCommandInfo[NUM_ITEM_COMMANDS] = {
|
||||||
{ "moveTo", &LBCode::itemMoveTo },
|
{ "moveTo", &LBCode::itemMoveTo },
|
||||||
{ "mute", 0 },
|
{ "mute", 0 },
|
||||||
{ "play", 0 },
|
{ "play", 0 },
|
||||||
{ "seek", 0 },
|
{ "seek", &LBCode::itemSeek },
|
||||||
{ "seekToFrame", 0 },
|
{ "seekToFrame", 0 },
|
||||||
{ "setParent", &LBCode::itemSetParent },
|
{ "setParent", &LBCode::itemSetParent },
|
||||||
{ "setZOrder", 0 },
|
{ "setZOrder", 0 },
|
||||||
|
@ -951,6 +1039,17 @@ void LBCode::itemMoveTo(const Common::Array<LBValue> ¶ms) {
|
||||||
warning("ignoring moveTo");
|
warning("ignoring moveTo");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LBCode::itemSeek(const Common::Array<LBValue> ¶ms) {
|
||||||
|
if (params.size() != 2)
|
||||||
|
error("incorrect number of parameters (%d) to seek", params.size());
|
||||||
|
|
||||||
|
LBItem *item = resolveItem(params[0]);
|
||||||
|
if (!item)
|
||||||
|
error("attempted seek on invalid item (%s)", params[0].toString().c_str());
|
||||||
|
uint seekTo = params[1].toInt();
|
||||||
|
item->seek(seekTo);
|
||||||
|
}
|
||||||
|
|
||||||
void LBCode::itemSetParent(const Common::Array<LBValue> ¶ms) {
|
void LBCode::itemSetParent(const Common::Array<LBValue> ¶ms) {
|
||||||
if (params.size() > 2)
|
if (params.size() > 2)
|
||||||
error("incorrect number of parameters (%d) to setParent", params.size());
|
error("incorrect number of parameters (%d) to setParent", params.size());
|
||||||
|
@ -1035,4 +1134,278 @@ void LBCode::runNotifyCommand() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function for parseCode/parseCodeSymbol:
|
||||||
|
* Returns an unused string id.
|
||||||
|
*/
|
||||||
|
uint LBCode::nextFreeString() {
|
||||||
|
for (uint i = 0; i <= 0xffff; i++) {
|
||||||
|
if (!_strings.contains(i))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
error("nextFreeString couldn't find a space");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function for parseCode:
|
||||||
|
* Given a name, appends the appropriate data to the provided code array and
|
||||||
|
* returns true if it's a function, or false otherwise.
|
||||||
|
*/
|
||||||
|
bool LBCode::parseCodeSymbol(const Common::String &name, uint &pos, Common::Array<byte> &code) {
|
||||||
|
// first, check whether the name matches a known function
|
||||||
|
for (uint i = 0; i < 2; i++) {
|
||||||
|
byte cmdToken;
|
||||||
|
CodeCommandInfo *cmdInfo;
|
||||||
|
uint cmdCount;
|
||||||
|
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
cmdInfo = generalCommandInfo;
|
||||||
|
cmdToken = kTokenGeneralCommand;
|
||||||
|
cmdCount = NUM_GENERAL_COMMANDS;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
cmdInfo = itemCommandInfo;
|
||||||
|
cmdToken = kTokenItemCommand;
|
||||||
|
cmdCount = NUM_ITEM_COMMANDS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint n = 0; n < cmdCount; n++) {
|
||||||
|
const char *cmdName = cmdInfo[n].name;
|
||||||
|
if (!cmdName)
|
||||||
|
continue;
|
||||||
|
if (!name.equalsIgnoreCase(cmdName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// found a matching function
|
||||||
|
code.push_back(cmdToken);
|
||||||
|
code.push_back(n + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a function, so must be an identifier
|
||||||
|
code.push_back(kTokenIdentifier);
|
||||||
|
|
||||||
|
uint stringId = nextFreeString();
|
||||||
|
_strings[stringId] = name;
|
||||||
|
|
||||||
|
char tmp[2];
|
||||||
|
WRITE_BE_UINT16(tmp, (int16)stringId);
|
||||||
|
code.push_back(tmp[0]);
|
||||||
|
code.push_back(tmp[1]);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse a string for later execution, and return the offset where it was
|
||||||
|
* stored.
|
||||||
|
*/
|
||||||
|
uint LBCode::parseCode(const Common::String &source) {
|
||||||
|
struct LBCodeOperator {
|
||||||
|
byte token;
|
||||||
|
byte op;
|
||||||
|
byte lookahead1;
|
||||||
|
byte lookahead1Op;
|
||||||
|
byte lookahead2;
|
||||||
|
byte lookahead2Op;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_LB_OPERATORS 11
|
||||||
|
static const LBCodeOperator operators[NUM_LB_OPERATORS] = {
|
||||||
|
{ '+', kTokenPlus, '+', kTokenPlusPlus, '=', kTokenPlusEquals },
|
||||||
|
{ '-', kTokenMinus, '-', kTokenMinusMinus, '=', kTokenMinusEquals },
|
||||||
|
{ '/', kTokenDivide, '=', kTokenDivideEquals, 0, 0 },
|
||||||
|
{ '*', kTokenMultiply, '=', kTokenMultiplyEquals, 0, 0 },
|
||||||
|
{ '=', kTokenAssign, '=', kTokenEquals, 0, 0 },
|
||||||
|
{ '>', kTokenGreaterThan, '=', kTokenGreaterThanEq, 0, 0 },
|
||||||
|
{ '<', kTokenLessThan, '=', kTokenLessThanEq, 0, 0 },
|
||||||
|
{ '!', kTokenNot, '=', kTokenNotEq, 0, 0 },
|
||||||
|
{ '&', kTokenConcat, '&', kTokenAnd, '=', kTokenAndEquals },
|
||||||
|
{ '|', 0, '|', kTokenOr, 0, 0 },
|
||||||
|
{ ';', kTokenEndOfStatement, 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
uint pos = 0;
|
||||||
|
Common::Array<byte> code;
|
||||||
|
Common::Array<uint> counterPositions;
|
||||||
|
bool wasFunction = false;
|
||||||
|
|
||||||
|
while (pos < source.size()) {
|
||||||
|
byte token = source[pos];
|
||||||
|
byte lookahead = 0;
|
||||||
|
if (pos + 1 < source.size())
|
||||||
|
lookahead = source[pos + 1];
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if (token != ' ' && token != '(' && wasFunction)
|
||||||
|
error("while parsing script '%s', encountered incomplete function call", source.c_str());
|
||||||
|
|
||||||
|
// First, we check for simple operators.
|
||||||
|
for (uint i = 0; i < NUM_LB_OPERATORS; i++) {
|
||||||
|
if (token != operators[i].token)
|
||||||
|
continue;
|
||||||
|
if (lookahead) {
|
||||||
|
if (lookahead == operators[i].lookahead1) {
|
||||||
|
code.push_back(operators[i].lookahead1Op);
|
||||||
|
token = 0;
|
||||||
|
} else if (lookahead == operators[i].lookahead2) {
|
||||||
|
code.push_back(operators[i].lookahead2Op);
|
||||||
|
token = 0;
|
||||||
|
}
|
||||||
|
if (!token) {
|
||||||
|
pos++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (operators[i].op) {
|
||||||
|
code.push_back(operators[i].op);
|
||||||
|
token = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!token)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Then, we check for more complex tokens.
|
||||||
|
switch (token) {
|
||||||
|
// whitespace
|
||||||
|
case ' ':
|
||||||
|
// ignore
|
||||||
|
break;
|
||||||
|
// literal string
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
{
|
||||||
|
Common::String tempString;
|
||||||
|
while (pos < source.size()) {
|
||||||
|
if (source[pos] == token)
|
||||||
|
break;
|
||||||
|
tempString += source[pos++];
|
||||||
|
}
|
||||||
|
if (pos++ == source.size())
|
||||||
|
error("while parsing script '%s', string had no end", source.c_str());
|
||||||
|
|
||||||
|
code.push_back(kTokenString);
|
||||||
|
|
||||||
|
uint stringId = nextFreeString();
|
||||||
|
_strings[stringId] = tempString;
|
||||||
|
|
||||||
|
char tmp[2];
|
||||||
|
WRITE_BE_UINT16(tmp, (int16)stringId);
|
||||||
|
code.push_back(tmp[0]);
|
||||||
|
code.push_back(tmp[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// open bracket
|
||||||
|
case '(':
|
||||||
|
if (wasFunction) {
|
||||||
|
// function call parameters
|
||||||
|
wasFunction = false;
|
||||||
|
// we will need to back-patch the parameter count,
|
||||||
|
// if parameters are encountered
|
||||||
|
counterPositions.push_back(code.size());
|
||||||
|
code.push_back(1);
|
||||||
|
// if the next token is a ) then there are no
|
||||||
|
// parameters, otherwise start with 1 and increment
|
||||||
|
// if/when we encounter commas
|
||||||
|
for (uint i = pos; i < source.size(); i++) {
|
||||||
|
if (source[i] == ' ')
|
||||||
|
continue;
|
||||||
|
if (source[i] != ')')
|
||||||
|
break;
|
||||||
|
code[code.size() - 1] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// brackets around expression
|
||||||
|
counterPositions.push_back(0);
|
||||||
|
}
|
||||||
|
code.push_back(kTokenOpenBracket);
|
||||||
|
break;
|
||||||
|
// close bracket
|
||||||
|
case ')':
|
||||||
|
if (counterPositions.empty())
|
||||||
|
error("while parsing script '%s', encountered unmatched )", source.c_str());
|
||||||
|
counterPositions.pop_back();
|
||||||
|
code.push_back(kTokenCloseBracket);
|
||||||
|
break;
|
||||||
|
// comma (seperating function params)
|
||||||
|
case ',':
|
||||||
|
{
|
||||||
|
if (counterPositions.empty())
|
||||||
|
error("while parsing script '%s', encountered unexpected ,", source.c_str());
|
||||||
|
code.push_back(kTokenComma);
|
||||||
|
uint counterPos = counterPositions.back();
|
||||||
|
if (!counterPos)
|
||||||
|
error("while parsing script '%s', encountered , outside parameter list", source.c_str());
|
||||||
|
code[counterPos]++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
// old-style explicit function call
|
||||||
|
case '@':
|
||||||
|
{
|
||||||
|
Common::String tempString;
|
||||||
|
while (pos < source.size()) {
|
||||||
|
if (!isalpha(source[pos]) && !isdigit(source[pos]))
|
||||||
|
break;
|
||||||
|
tempString += source[pos++];
|
||||||
|
}
|
||||||
|
wasFunction = parseCodeSymbol(tempString, pos, code);
|
||||||
|
if (!wasFunction)
|
||||||
|
error("while parsing script '%s', encountered explicit function call to unknown function '%s'",
|
||||||
|
source.c_str(), tempString.c_str());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (isdigit(token)) {
|
||||||
|
const char *in = source.c_str() + pos - 1;
|
||||||
|
// FIXME: handle floats?
|
||||||
|
char *endptr;
|
||||||
|
long int intValue = strtol(in, &endptr, 0);
|
||||||
|
assert(endptr > in);
|
||||||
|
pos += (endptr - in) - 1;
|
||||||
|
|
||||||
|
// FIXME: handle storing longs if needed
|
||||||
|
code.push_back(kTokenLiteral);
|
||||||
|
code.push_back(kLBCodeLiteralInteger);
|
||||||
|
char tmp[2];
|
||||||
|
WRITE_BE_UINT16(tmp, (int16)intValue);
|
||||||
|
code.push_back(tmp[0]);
|
||||||
|
code.push_back(tmp[1]);
|
||||||
|
} else if (isalpha(token)) {
|
||||||
|
Common::String tempString;
|
||||||
|
tempString += token;
|
||||||
|
while (pos < source.size()) {
|
||||||
|
if (!isalpha(source[pos]) && !isdigit(source[pos]))
|
||||||
|
break;
|
||||||
|
tempString += source[pos++];
|
||||||
|
}
|
||||||
|
wasFunction = parseCodeSymbol(tempString, pos, code);
|
||||||
|
} else {
|
||||||
|
error("while parsing script '%s', couldn't parse '%c'", source.c_str(), token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasFunction)
|
||||||
|
error("while parsing script '%s', encountered incomplete function call", source.c_str());
|
||||||
|
if (counterPositions.size())
|
||||||
|
error("while parsing script '%s', unmatched (", source.c_str());
|
||||||
|
|
||||||
|
code.push_back(kTokenEndOfFile);
|
||||||
|
|
||||||
|
uint codeOffset = _size;
|
||||||
|
byte *newData = new byte[_size + code.size()];
|
||||||
|
memcpy(newData, _data, _size);
|
||||||
|
memcpy(newData, &code[0], code.size());
|
||||||
|
delete[] _data;
|
||||||
|
_data = newData;
|
||||||
|
_size += code.size();
|
||||||
|
return codeOffset;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Mohawk
|
} // End of namespace Mohawk
|
||||||
|
|
|
@ -181,6 +181,7 @@ public:
|
||||||
~LBCode();
|
~LBCode();
|
||||||
|
|
||||||
LBValue runCode(LBItem *src, uint32 offset);
|
LBValue runCode(LBItem *src, uint32 offset);
|
||||||
|
uint parseCode(const Common::String &source);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MohawkEngine_LivingBooks *_vm;
|
MohawkEngine_LivingBooks *_vm;
|
||||||
|
@ -206,6 +207,7 @@ protected:
|
||||||
void parseArithmetic2();
|
void parseArithmetic2();
|
||||||
void parseMain();
|
void parseMain();
|
||||||
|
|
||||||
|
LBItem *resolveItem(const LBValue &value);
|
||||||
Common::Array<LBValue> readParams();
|
Common::Array<LBValue> readParams();
|
||||||
Common::Rect getRectFromParams(const Common::Array<LBValue> ¶ms);
|
Common::Rect getRectFromParams(const Common::Array<LBValue> ¶ms);
|
||||||
|
|
||||||
|
@ -213,8 +215,13 @@ protected:
|
||||||
void runItemCommand();
|
void runItemCommand();
|
||||||
void runNotifyCommand();
|
void runNotifyCommand();
|
||||||
|
|
||||||
|
uint nextFreeString();
|
||||||
|
bool parseCodeSymbol(const Common::String &name, uint &pos, Common::Array<byte> &code);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void cmdUnimplemented(const Common::Array<LBValue> ¶ms);
|
void cmdUnimplemented(const Common::Array<LBValue> ¶ms);
|
||||||
|
void cmdEval(const Common::Array<LBValue> ¶ms);
|
||||||
|
void cmdRandom(const Common::Array<LBValue> ¶ms);
|
||||||
void cmdGetRect(const Common::Array<LBValue> ¶ms);
|
void cmdGetRect(const Common::Array<LBValue> ¶ms);
|
||||||
void cmdTopLeft(const Common::Array<LBValue> ¶ms);
|
void cmdTopLeft(const Common::Array<LBValue> ¶ms);
|
||||||
void cmdBottomRight(const Common::Array<LBValue> ¶ms);
|
void cmdBottomRight(const Common::Array<LBValue> ¶ms);
|
||||||
|
@ -228,9 +235,10 @@ public:
|
||||||
void cmdSetHitTest(const Common::Array<LBValue> ¶ms);
|
void cmdSetHitTest(const Common::Array<LBValue> ¶ms);
|
||||||
void cmdKey(const Common::Array<LBValue> ¶ms);
|
void cmdKey(const Common::Array<LBValue> ¶ms);
|
||||||
|
|
||||||
void itemSetParent(const Common::Array<LBValue> ¶ms);
|
|
||||||
void itemMoveTo(const Common::Array<LBValue> ¶ms);
|
|
||||||
void itemIsPlaying(const Common::Array<LBValue> ¶ms);
|
void itemIsPlaying(const Common::Array<LBValue> ¶ms);
|
||||||
|
void itemMoveTo(const Common::Array<LBValue> ¶ms);
|
||||||
|
void itemSeek(const Common::Array<LBValue> ¶ms);
|
||||||
|
void itemSetParent(const Common::Array<LBValue> ¶ms);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Mohawk
|
} // End of namespace Mohawk
|
||||||
|
|
|
@ -560,6 +560,7 @@ void MystScriptParser::o_playSoundBlocking(uint16 op, uint16 var, uint16 argc, u
|
||||||
debugC(kDebugScript, "Opcode %d: playSoundBlocking", op);
|
debugC(kDebugScript, "Opcode %d: playSoundBlocking", op);
|
||||||
debugC(kDebugScript, "\tsoundId: %d", soundId);
|
debugC(kDebugScript, "\tsoundId: %d", soundId);
|
||||||
|
|
||||||
|
_vm->_sound->stopSound();
|
||||||
_vm->_sound->playSoundBlocking(soundId);
|
_vm->_sound->playSoundBlocking(soundId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,7 @@ void Mechanical::setupOpcodes() {
|
||||||
|
|
||||||
void Mechanical::disablePersistentScripts() {
|
void Mechanical::disablePersistentScripts() {
|
||||||
_fortressSimulationRunning = false;
|
_fortressSimulationRunning = false;
|
||||||
|
_elevatorRotationLeverMoving = false;
|
||||||
_elevatorGoingMiddle = false;
|
_elevatorGoingMiddle = false;
|
||||||
_birdSinging = false;
|
_birdSinging = false;
|
||||||
_fortressRotationRunning = false;
|
_fortressRotationRunning = false;
|
||||||
|
@ -126,10 +127,10 @@ void Mechanical::runPersistentScripts() {
|
||||||
|
|
||||||
uint16 Mechanical::getVar(uint16 var) {
|
uint16 Mechanical::getVar(uint16 var) {
|
||||||
switch(var) {
|
switch(var) {
|
||||||
case 0: // Sirrus's Secret Panel State
|
case 0: // Achenar's Secret Panel State
|
||||||
return _state.sirrusPanelState;
|
|
||||||
case 1: // Achenar's Secret Panel State
|
|
||||||
return _state.achenarPanelState;
|
return _state.achenarPanelState;
|
||||||
|
case 1: // Sirrus's Secret Panel State
|
||||||
|
return _state.sirrusPanelState;
|
||||||
case 2: // Achenar's Secret Room Crate Lid Open and Blue Page Present
|
case 2: // Achenar's Secret Room Crate Lid Open and Blue Page Present
|
||||||
if (_state.achenarCrateOpened) {
|
if (_state.achenarCrateOpened) {
|
||||||
if (_globals.bluePagesInBook & 4 || _globals.heldPage == 3)
|
if (_globals.bluePagesInBook & 4 || _globals.heldPage == 3)
|
||||||
|
@ -195,16 +196,21 @@ uint16 Mechanical::getVar(uint16 var) {
|
||||||
|
|
||||||
void Mechanical::toggleVar(uint16 var) {
|
void Mechanical::toggleVar(uint16 var) {
|
||||||
switch(var) {
|
switch(var) {
|
||||||
case 0: // Sirrus's Secret Panel State
|
case 0: // Achenar's Secret Panel State
|
||||||
_state.sirrusPanelState ^= 1;
|
|
||||||
case 1: // Achenar's Secret Panel State
|
|
||||||
_state.achenarPanelState ^= 1;
|
_state.achenarPanelState ^= 1;
|
||||||
|
break;
|
||||||
|
case 1: // Sirrus's Secret Panel State
|
||||||
|
_state.sirrusPanelState ^= 1;
|
||||||
|
break;
|
||||||
case 3: // Achenar's Secret Room Crate State
|
case 3: // Achenar's Secret Room Crate State
|
||||||
_state.achenarCrateOpened ^= 1;
|
_state.achenarCrateOpened ^= 1;
|
||||||
|
break;
|
||||||
case 4: // Myst Book Room Staircase State
|
case 4: // Myst Book Room Staircase State
|
||||||
_mystStaircaseState ^= 1;
|
_mystStaircaseState ^= 1;
|
||||||
|
break;
|
||||||
case 10: // Fortress Staircase State
|
case 10: // Fortress Staircase State
|
||||||
_state.staircaseState ^= 1;
|
_state.staircaseState ^= 1;
|
||||||
|
break;
|
||||||
case 16: // Code Lock Shape #1 - Left
|
case 16: // Code Lock Shape #1 - Left
|
||||||
case 17: // Code Lock Shape #2
|
case 17: // Code Lock Shape #2
|
||||||
case 18: // Code Lock Shape #3
|
case 18: // Code Lock Shape #3
|
||||||
|
@ -242,6 +248,7 @@ bool Mechanical::setVarValue(uint16 var, uint16 value) {
|
||||||
switch (var) {
|
switch (var) {
|
||||||
case 13:
|
case 13:
|
||||||
_elevatorPosition = value;
|
_elevatorPosition = value;
|
||||||
|
break;
|
||||||
case 14: // Elevator going down when at top
|
case 14: // Elevator going down when at top
|
||||||
_elevatorGoingDown = value;
|
_elevatorGoingDown = value;
|
||||||
break;
|
break;
|
||||||
|
@ -724,6 +731,7 @@ void Mechanical::birdSing_run() {
|
||||||
uint32 time = _vm->_system->getMillis();
|
uint32 time = _vm->_system->getMillis();
|
||||||
if (_birdSingEndTime < time) {
|
if (_birdSingEndTime < time) {
|
||||||
_bird->pauseMovie(true);
|
_bird->pauseMovie(true);
|
||||||
|
_vm->_sound->stopSound();
|
||||||
_birdSinging = false;
|
_birdSinging = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,7 +294,7 @@ bool MohawkArchive::openStream(Common::SeekableReadStream *stream) {
|
||||||
// We need to do this because of the way Mohawk is set up (this is much more "proper"
|
// We need to do this because of the way Mohawk is set up (this is much more "proper"
|
||||||
// than passing _stream at the right offset). We may want to do that in the future, though.
|
// than passing _stream at the right offset). We may want to do that in the future, though.
|
||||||
if (tag == ID_TMOV) {
|
if (tag == ID_TMOV) {
|
||||||
if (index == fileTable.size() - 1)
|
if (index == fileTable.size())
|
||||||
res.size = stream->size() - fileTable[index - 1].offset;
|
res.size = stream->size() - fileTable[index - 1].offset;
|
||||||
else
|
else
|
||||||
res.size = fileTable[index].offset - fileTable[index - 1].offset;
|
res.size = fileTable[index].offset - fileTable[index - 1].offset;
|
||||||
|
@ -304,7 +304,6 @@ bool MohawkArchive::openStream(Common::SeekableReadStream *stream) {
|
||||||
debug(4, "Entry[%02x]: ID = %04x (%d) Index = %04x", j, id, id, index);
|
debug(4, "Entry[%02x]: ID = %04x (%d) Index = %04x", j, id, id, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Return to next TypeTable entry
|
// Return to next TypeTable entry
|
||||||
stream->seek(absOffset + (i + 1) * 8 + 4);
|
stream->seek(absOffset + (i + 1) * 8 + 4);
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,19 @@ Audio::SoundHandle *Sound::replaceSoundMyst(uint16 id, byte volume, bool loop) {
|
||||||
&& name.equals(_vm->getResourceName(ID_MSND, convertMystID(_handles[i].id))))
|
&& name.equals(_vm->getResourceName(ID_MSND, convertMystID(_handles[i].id))))
|
||||||
return &_handles[i].handle;
|
return &_handles[i].handle;
|
||||||
|
|
||||||
|
// The original engine also forces looping for those sounds
|
||||||
|
switch (id) {
|
||||||
|
case 2205:
|
||||||
|
case 2207:
|
||||||
|
case 5378:
|
||||||
|
case 7220:
|
||||||
|
case 9119: // Elevator engine sound in mechanical age is looping.
|
||||||
|
case 9120:
|
||||||
|
case 9327:
|
||||||
|
loop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
stopSound();
|
stopSound();
|
||||||
return playSound(id, volume, loop);
|
return playSound(id, volume, loop);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include "common/hashmap.h"
|
#include "common/hashmap.h"
|
||||||
#include "common/hash-str.h"
|
#include "common/hash-str.h"
|
||||||
#include "common/stream.h"
|
#include "common/stream.h"
|
||||||
|
#include "common/array.h"
|
||||||
|
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,17 @@
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
SaveStateDescriptor::SaveStateDescriptor()
|
||||||
|
// FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
|
||||||
|
: _slot(-1), _description(), _isDeletable(true), _isWriteProtected(false),
|
||||||
|
_saveDate(), _saveTime(), _playTime(), _thumbnail() {
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveStateDescriptor::SaveStateDescriptor(int s, const Common::String &d)
|
||||||
|
: _slot(s), _description(d), _isDeletable(true), _isWriteProtected(false),
|
||||||
|
_saveDate(), _saveTime(), _playTime(), _thumbnail() {
|
||||||
|
}
|
||||||
|
|
||||||
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
||||||
if (_thumbnail.get() == t)
|
if (_thumbnail.get() == t)
|
||||||
return;
|
return;
|
||||||
|
@ -31,42 +42,16 @@ void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
||||||
_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter());
|
_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SaveStateDescriptor::getBool(const Common::String &key) const {
|
|
||||||
if (contains(key)) {
|
|
||||||
const Common::String value = getVal(key);
|
|
||||||
bool valueAsBool;
|
|
||||||
if (Common::parseBool(value, valueAsBool))
|
|
||||||
return valueAsBool;
|
|
||||||
error("SaveStateDescriptor: %s '%s' has unknown value '%s' for boolean '%s'",
|
|
||||||
save_slot().c_str(), description().c_str(), value.c_str(), key.c_str());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveStateDescriptor::setDeletableFlag(bool state) {
|
|
||||||
setVal("is_deletable", state ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveStateDescriptor::setWriteProtectedFlag(bool state) {
|
|
||||||
setVal("is_write_protected", state ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
void SaveStateDescriptor::setSaveDate(int year, int month, int day) {
|
void SaveStateDescriptor::setSaveDate(int year, int month, int day) {
|
||||||
Common::String buffer;
|
_saveDate = Common::String::format("%.2d.%.2d.%.4d", day, month, year);
|
||||||
buffer = Common::String::format("%.2d.%.2d.%.4d", day, month, year);
|
|
||||||
setVal("save_date", buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateDescriptor::setSaveTime(int hour, int min) {
|
void SaveStateDescriptor::setSaveTime(int hour, int min) {
|
||||||
Common::String buffer;
|
_saveTime = Common::String::format("%.2d:%.2d", hour, min);
|
||||||
buffer = Common::String::format("%.2d:%.2d", hour, min);
|
|
||||||
setVal("save_time", buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateDescriptor::setPlayTime(int hours, int minutes) {
|
void SaveStateDescriptor::setPlayTime(int hours, int minutes) {
|
||||||
Common::String buffer;
|
_playTime = Common::String::format("%.2d:%.2d", hours, minutes);
|
||||||
buffer = Common::String::format("%.2d:%.2d", hours, minutes);
|
|
||||||
setVal("play_time", buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateDescriptor::setPlayTime(uint32 msecs) {
|
void SaveStateDescriptor::setPlayTime(uint32 msecs) {
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define ENGINES_SAVESTATE_H
|
#define ENGINES_SAVESTATE_H
|
||||||
|
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
#include "common/hash-str.h"
|
#include "common/str.h"
|
||||||
#include "common/ptr.h"
|
#include "common/ptr.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,65 +33,60 @@ struct Surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A hashmap describing details about a given save state.
|
* Object describing a save state.
|
||||||
* TODO
|
*
|
||||||
* Guaranteed to contain save_slot and description values.
|
* This at least includes the save slot number and a human readable
|
||||||
* Additional ideas: Playtime, creation date, thumbnail, ...
|
* description of the save state.
|
||||||
|
*
|
||||||
|
* Further possibilites are a thumbnail, play time, creation date,
|
||||||
|
* creation time, delete protected, write protection.
|
||||||
*/
|
*/
|
||||||
class SaveStateDescriptor : public Common::StringMap {
|
class SaveStateDescriptor {
|
||||||
protected:
|
|
||||||
Common::SharedPtr<Graphics::Surface> _thumbnail; // can be 0
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SaveStateDescriptor() : _thumbnail() {
|
SaveStateDescriptor();
|
||||||
setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
|
SaveStateDescriptor(int s, const Common::String &d);
|
||||||
setVal("description", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
SaveStateDescriptor(int s, const Common::String &d) : _thumbnail() {
|
/**
|
||||||
setVal("save_slot", Common::String::format("%d", s));
|
* @param slot The saveslot id, as it would be passed to the "-x" command line switch.
|
||||||
setVal("description", d);
|
*/
|
||||||
}
|
void setSaveSlot(int slot) { _slot = slot; }
|
||||||
|
|
||||||
SaveStateDescriptor(const Common::String &s, const Common::String &d) : _thumbnail() {
|
/**
|
||||||
setVal("save_slot", s);
|
* @return The saveslot id, as it would be passed to the "-x" command line switch.
|
||||||
setVal("description", d);
|
*/
|
||||||
}
|
int getSaveSlot() const { return _slot; }
|
||||||
|
|
||||||
/** The saveslot id, as it would be passed to the "-x" command line switch. */
|
/**
|
||||||
Common::String &save_slot() { return getVal("save_slot"); }
|
* @param desc A human readable description of the save state.
|
||||||
|
*/
|
||||||
|
void setDescription(const Common::String &desc) { _description = desc; }
|
||||||
|
|
||||||
/** The saveslot id, as it would be passed to the "-x" command line switch (read-only variant). */
|
/**
|
||||||
const Common::String &save_slot() const { return getVal("save_slot"); }
|
* @return A human readable description of the save state.
|
||||||
|
*/
|
||||||
/** A human readable description of the save state. */
|
const Common::String &getDescription() const { return _description; }
|
||||||
Common::String &description() { return getVal("description"); }
|
|
||||||
|
|
||||||
/** A human readable description of the save state (read-only variant). */
|
|
||||||
const Common::String &description() const { return getVal("description"); }
|
|
||||||
|
|
||||||
/** Optional entries only included when querying via MetaEngine::querySaveMetaInfo */
|
/** Optional entries only included when querying via MetaEngine::querySaveMetaInfo */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of a given key as boolean.
|
* Defines whether the save state is allowed to be deleted.
|
||||||
* It accepts 'true', 'yes' and '1' for true and
|
|
||||||
* 'false', 'no' and '0' for false.
|
|
||||||
* (FIXME:) On unknown value it errors out ScummVM.
|
|
||||||
* On unknown key it returns false as default.
|
|
||||||
*/
|
*/
|
||||||
bool getBool(const Common::String &key) const;
|
void setDeletableFlag(bool state) { _isDeletable = state; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the 'is_deletable' key, which indicates if the
|
* Queries whether the save state is allowed to be deleted.
|
||||||
* given savestate is safe for deletion.
|
|
||||||
*/
|
*/
|
||||||
void setDeletableFlag(bool state);
|
bool getDeletableFlag() const { return _isDeletable; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the 'is_write_protected' key, which indicates if the
|
* Defines whether the save state is write protected.
|
||||||
* given savestate can be overwritten or not
|
|
||||||
*/
|
*/
|
||||||
void setWriteProtectedFlag(bool state);
|
void setWriteProtectedFlag(bool state) { _isWriteProtected = state; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries whether the save state is write protected.
|
||||||
|
*/
|
||||||
|
bool getWriteProtectedFlag() const { return _isWriteProtected; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a thumbnail graphics surface representing the savestate visually.
|
* Return a thumbnail graphics surface representing the savestate visually.
|
||||||
|
@ -109,24 +104,100 @@ public:
|
||||||
void setThumbnail(Graphics::Surface *t);
|
void setThumbnail(Graphics::Surface *t);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the 'save_date' key properly, based on the given values.
|
* Sets the date the save state was created.
|
||||||
|
*
|
||||||
|
* @param year Year of creation.
|
||||||
|
* @param month Month of creation.
|
||||||
|
* @param day Day of creation.
|
||||||
*/
|
*/
|
||||||
void setSaveDate(int year, int month, int day);
|
void setSaveDate(int year, int month, int day);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the 'save_time' key properly, based on the given values.
|
* Queries a human readable description of the date the save state was created.
|
||||||
|
*
|
||||||
|
* This will return an empty string in case the value is not set.
|
||||||
|
*/
|
||||||
|
const Common::String &getSaveDate() const { return _saveDate; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the time the save state was created.
|
||||||
|
*
|
||||||
|
* @param hour Hour of creation.
|
||||||
|
* @param min Minute of creation.
|
||||||
*/
|
*/
|
||||||
void setSaveTime(int hour, int min);
|
void setSaveTime(int hour, int min);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the 'play_time' key properly, based on the given values.
|
* Queries a human readable description of the time the save state was created.
|
||||||
|
*
|
||||||
|
* This will return an empty string in case the value is not set.
|
||||||
|
*/
|
||||||
|
const Common::String &getSaveTime() const { return _saveTime; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the time the game was played before the save state was created.
|
||||||
|
*
|
||||||
|
* @param hours How many hours the user played the game so far.
|
||||||
|
* @param min How many minutes the user played the game so far.
|
||||||
*/
|
*/
|
||||||
void setPlayTime(int hours, int minutes);
|
void setPlayTime(int hours, int minutes);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the 'play_time' key properly, based on the given value.
|
* Sets the time the game was played before the save state was created.
|
||||||
|
*
|
||||||
|
* @param msecs How many milliseconds the user played the game so far.
|
||||||
*/
|
*/
|
||||||
void setPlayTime(uint32 msecs);
|
void setPlayTime(uint32 msecs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries a human readable description of the time the game was played
|
||||||
|
* before the save state was created.
|
||||||
|
*
|
||||||
|
* This will return an empty string in case the value is not set.
|
||||||
|
*/
|
||||||
|
const Common::String &getPlayTime() const { return _playTime; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* The saveslot id, as it would be passed to the "-x" command line switch.
|
||||||
|
*/
|
||||||
|
int _slot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A human readable description of the save state.
|
||||||
|
*/
|
||||||
|
Common::String _description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the save state can be deleted.
|
||||||
|
*/
|
||||||
|
bool _isDeletable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the save state is write protected.
|
||||||
|
*/
|
||||||
|
bool _isWriteProtected;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Human readable description of the date the save state was created.
|
||||||
|
*/
|
||||||
|
Common::String _saveDate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Human readable description of the time the save state was created.
|
||||||
|
*/
|
||||||
|
Common::String _saveTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Human readable description of the time the game was played till the
|
||||||
|
* save state was created.
|
||||||
|
*/
|
||||||
|
Common::String _playTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The thumbnail of the save state.
|
||||||
|
*/
|
||||||
|
Common::SharedPtr<Graphics::Surface> _thumbnail;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** List of savestates. */
|
/** List of savestates. */
|
||||||
|
|
|
@ -730,6 +730,10 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
|
||||||
case 8: { // Dup
|
case 8: { // Dup
|
||||||
const char *rawString = 0;
|
const char *rawString = 0;
|
||||||
uint32 size = 0;
|
uint32 size = 0;
|
||||||
|
reg_t stringHandle;
|
||||||
|
// We allocate the new string first because if the StringTable needs to
|
||||||
|
// grow, our rawString pointer will be invalidated
|
||||||
|
SciString *dupString = s->_segMan->allocateString(&stringHandle);
|
||||||
|
|
||||||
if (argv[1].segment == s->_segMan->getStringSegmentId()) {
|
if (argv[1].segment == s->_segMan->getStringSegmentId()) {
|
||||||
SciString *string = s->_segMan->lookupString(argv[1]);
|
SciString *string = s->_segMan->lookupString(argv[1]);
|
||||||
|
@ -741,8 +745,6 @@ reg_t kString(EngineState *s, int argc, reg_t *argv) {
|
||||||
size = string.size() + 1;
|
size = string.size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t stringHandle;
|
|
||||||
SciString *dupString = s->_segMan->allocateString(&stringHandle);
|
|
||||||
dupString->setSize(size);
|
dupString->setSize(size);
|
||||||
|
|
||||||
for (uint32 i = 0; i < size; i++)
|
for (uint32 i = 0; i < size; i++)
|
||||||
|
|
|
@ -338,7 +338,7 @@ void GfxScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte
|
||||||
void GfxScreen::putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color) {
|
void GfxScreen::putKanjiChar(Graphics::FontSJIS *commonFont, int16 x, int16 y, uint16 chr, byte color) {
|
||||||
byte *displayPtr = _displayScreen + y * _displayWidth * 2 + x * 2;
|
byte *displayPtr = _displayScreen + y * _displayWidth * 2 + x * 2;
|
||||||
// we don't use outline, so color 0 is actually not used
|
// we don't use outline, so color 0 is actually not used
|
||||||
commonFont->drawChar(displayPtr, chr, _displayWidth, 1, color, 0);
|
commonFont->drawChar(displayPtr, chr, _displayWidth, 1, color, 0, -1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte GfxScreen::getVisual(int x, int y) {
|
byte GfxScreen::getVisual(int x, int y) {
|
||||||
|
|
|
@ -779,7 +779,7 @@ void CharsetRendererV3::printChar(int chr, bool ignoreCharsetMask) {
|
||||||
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->format.bytesPerPixel);
|
drawBits1(*vs, dst, charPtr, drawTop, origWidth, origHeight, vs->format.bytesPerPixel);
|
||||||
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
|
#ifndef DISABLE_TOWNS_DUAL_LAYER_MODE
|
||||||
else if (_vm->_cjkFont)
|
else if (_vm->_cjkFont)
|
||||||
_vm->_cjkFont->drawChar(vs, chr, _left, drawTop, _color, _shadowColor);
|
_vm->_cjkFont->drawChar(*vs, chr, _left, drawTop, _color, _shadowColor);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
|
dst = (byte *)_vm->_textSurface.getBasePtr(_left * _vm->_textSurfaceMultiplier, _top * _vm->_textSurfaceMultiplier);
|
||||||
|
|
|
@ -39,7 +39,6 @@ public:
|
||||||
virtual void send(MidiChannel *mc) = 0;
|
virtual void send(MidiChannel *mc) = 0;
|
||||||
virtual void copy_to(Instrument *dest) = 0;
|
virtual void copy_to(Instrument *dest) = 0;
|
||||||
virtual bool is_valid() = 0;
|
virtual bool is_valid() = 0;
|
||||||
virtual operator int() { return 255; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Instrument {
|
class Instrument {
|
||||||
|
|
|
@ -105,7 +105,9 @@ static const byte imxOtherTable[6][64] = {
|
||||||
|
|
||||||
void releaseImcTables() {
|
void releaseImcTables() {
|
||||||
free(_destImcTable);
|
free(_destImcTable);
|
||||||
|
_destImcTable = NULL;
|
||||||
free(_destImcTable2);
|
free(_destImcTable2);
|
||||||
|
_destImcTable2 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initializeImcTables() {
|
void initializeImcTables() {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue