diff options
author | David Corrales | 2007-05-26 20:23:24 +0000 |
---|---|---|
committer | David Corrales | 2007-05-26 20:23:24 +0000 |
commit | 3646c968c9578c2a94d65ebd5fb06ec835f8c51d (patch) | |
tree | 8b57b339ebb31a1d7a67f1678aa5dc5c7759070a | |
parent | d1f56d93f934150f4b579c2e90564e2bf035f113 (diff) | |
parent | ac45c5b33d834acbc9718f89be76e49d403a4d2c (diff) | |
download | scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.tar.gz scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.tar.bz2 scummvm-rg350-3646c968c9578c2a94d65ebd5fb06ec835f8c51d.zip |
Merged the fs branch with trunk. r26472:26948
svn-id: r26949
542 files changed, 38529 insertions, 17349 deletions
@@ -26,6 +26,7 @@ ScummVM Team AGI: Stuart George + Filippos Karapetis Pawel Kolodziejski Eugene Sandulenko David Symonds @@ -48,10 +49,14 @@ ScummVM Team Jonathan Gray Cinematique evo 1: + Vincent Hamm - original CinE engine author Pawel Kolodziejski Gregory Montoir Eugene Sandulenko + Cinematique evo 2: + Vincent Hamm + FOTAQ: David Eriksson Gregory Montoir @@ -72,8 +77,12 @@ ScummVM Team Lure: Paul Gilbert + Parallaction: + peres + SAGA: Torbjorn Andersson + Filippos Karapetis Andrew Kurushin Eugene Sandulenko @@ -144,7 +153,6 @@ ScummVM Team Tore Anderson - Former Debian GNU/Linux maintainer Ralph Brorsen - Help with GUI implementation Jamieson Christian - iMUSE, MIDI, all things musical - Vincent Hamm - Co-Founder, original CinE engine author Ruediger Hanke - Port: MorphOS Felix Jakschitsch - Zak256 reverse engineering Mutwin Kraus - Original MacOS porter @@ -226,6 +234,8 @@ Other contributions Andreas Karlsson - Initial port for EPOC/SymbianOS Claudio Matsuoka - Daily Linux builds Thomas Mayer - PSP port contributions + n0p - Windows CE port aspect ratio correction scaler + and right click input method Mikesch Nepomuk - MI1 VGA floppy patches Nicolas Noble - Config file and ALSA support Quietust - Sound support for Amiga SCUMM V2/V3 games, MM @@ -236,6 +246,7 @@ Other contributions support Andre Souza - SDL-based OpenGL renderer Tim Phillips - Initial MI1 CD music support + Robin Watts - ARM assembly routines for the Windows CE port And to all the contributors, users, and beta testers we've missed. Thanks! @@ -94,19 +94,36 @@ bundle: scummvm-static # location of additional libs for OS X usually /sw/ for fink or # /opt/local/ for darwinports OSXOPT=/sw + +# Static libaries, used for the scummvm-static target +OSX_STATIC_LIBS := `sdl-config --static-libs` + +ifdef USE_VORBIS +OSX_STATIC_LIBS += \ + $(OSXOPT)/lib/libvorbisfile.a \ + $(OSXOPT)/lib/libvorbis.a \ + $(OSXOPT)/lib/libogg.a +endif + +ifdef USE_FLAC +OSX_STATIC_LIBS += $(OSXOPT)/lib/libFLAC.a +endif + +ifdef USE_MAD +OSX_STATIC_LIBS += $(OSXOPT)/lib/libmad.a +endif + +ifdef USE_MPEG2 +OSX_STATIC_LIBS += $(OSXOPT)/lib/libmpeg2.a +endif + # Special target to create a static linked binary for Mac OS X. # We use -force_cpusubtype_ALL to ensure the binary runs on every # PowerPC machine. scummvm-static: $(OBJS) $(CXX) $(LDFLAGS) -force_cpusubtype_ALL -o scummvm-static $(OBJS) \ - `sdl-config --static-libs` \ -framework CoreMIDI \ - $(OSXOPT)/lib/libmad.a \ - $(OSXOPT)/lib/libvorbisfile.a \ - $(OSXOPT)/lib/libvorbis.a \ - $(OSXOPT)/lib/libogg.a \ - $(OSXOPT)/lib/libmpeg2.a \ - $(OSXOPT)/lib/libFLAC.a \ + $(OSX_STATIC_LIBS) \ -lSystemStubs \ -lz @@ -9,6 +9,9 @@ For a more comprehensive changelog for the latest experimental SVN code, see: - Added support for Simon the Sorcerer's Puzzle Pack. - Added support for Ween: The Prophecy. - Added support for Bargon Attack. + - Added Sierra AGI engine. + - Added support for Goblins 3. + - Added Parallaction engine. Currently only Nippon Safes Inc. is supported. General: - Added dialog which allows the user to select the GUI theme on runtime. @@ -29,9 +32,6 @@ For a more comprehensive changelog for the latest experimental SVN code, see: - Added support for DXA cutscenes. - Added "fast mode" (use Ctrl-f to toggle). - Cine: - - Improved support for international versions. - Queen: - Added support for Amiga versions. - Fixed some sound glitches. @@ -44,6 +44,7 @@ For a more comprehensive changelog for the latest experimental SVN code, see: in Zak McKracken and Maniac Mansion, by rewriting the walking code for these games. - Fixed several other issues. + - Added support for DXA movies playback in HE games. Simon: - Renamed Simon engine to AGOS. @@ -62,6 +63,10 @@ For a more comprehensive changelog for the latest experimental SVN code, see: WinCE Port: - Switched to using a GCC toolchain for building. + - Major update to the SDL lib. Better, faster, more compatible :-) + + PalmOS Port: + - Now using PalmOS Porting SDK which enables use of the C standard library 0.9.1 (2006-10-29) New Ports: @@ -878,6 +878,7 @@ other games. stretches the image to use 320x240 pixels instead, or a multiple thereof Alt-Enter - Toggles full screen/windowed + Alt-s - Make a screenshot (SDL backend only) SCUMM: Ctrl 0-9 and Alt 0-9 - Load and save game state @@ -886,7 +887,6 @@ other games. Ctrl-t - Switch between 'Speech only', 'Speech and Subtitles' and 'Subtitles only' Tilde (~) - Show/hide the debugging console - Ctrl-s - Shows memory consumption [ and ] - Music volume, down/up - and + - Text speed, slower/faster F5 - Displays a save/load box diff --git a/backends/fs/ds/ds-fs.cpp b/backends/fs/ds/ds-fs.cpp index 5243099fbe..572f796f76 100644 --- a/backends/fs/ds/ds-fs.cpp +++ b/backends/fs/ds/ds-fs.cpp @@ -19,7 +19,6 @@ #include "stdafx.h" #include "str.h" -#include "fs.h" #include "common/util.h" //#include <NDS/ARM9/console.h> //basic print funcionality #include "ds-fs.h" diff --git a/backends/fs/palmos/palmos-fs.cpp b/backends/fs/palmos/palmos-fs.cpp index 52fe741d26..af09d79a12 100644 --- a/backends/fs/palmos/palmos-fs.cpp +++ b/backends/fs/palmos/palmos-fs.cpp @@ -21,12 +21,12 @@ #if defined(PALMOS_MODE) +#include "PalmVersion.h" +#include "globals.h" + #include "common/stdafx.h" #include "backends/fs/abstract-fs.h" -#include <stdio.h> -#include <stdlib.h> - /** * Implementation of the ScummVM file system API based on PalmOS VFS API. * diff --git a/backends/fs/posix/posix-fs-factory.cpp b/backends/fs/posix/posix-fs-factory.cpp index bed3dc5f8f..2ec3c84ec4 100644 --- a/backends/fs/posix/posix-fs-factory.cpp +++ b/backends/fs/posix/posix-fs-factory.cpp @@ -1,8 +1,6 @@ #include "backends/fs/posix/posix-fs-factory.h" #include "backends/fs/posix/posix-fs.cpp" -DECLARE_SINGLETON(POSIXFilesystemFactory); - AbstractFilesystemNode *POSIXFilesystemFactory::makeRootFileNode() const { return new POSIXFilesystemNode(); } diff --git a/backends/midi/zodiac.cpp b/backends/midi/zodiac.cpp index e626db687e..fe6cf0f7e9 100644 --- a/backends/midi/zodiac.cpp +++ b/backends/midi/zodiac.cpp @@ -25,8 +25,7 @@ #ifndef DISABLE_TAPWAVE -#include "TwTraps.h" -#include "TwMidi.h" +#include <tapwave.h> class MidiDriver_Zodiac:public MidiDriver_MPU401 { @@ -110,12 +109,13 @@ void MidiDriver_Zodiac::send(uint32 b) { } void MidiDriver_Zodiac::sysEx(const byte *msg, uint16 length) { -FIXME: We may have to add the 0xF0 / 0xF7 frame here. -Or not -- maybe TwMidiSysEx doesn't expect it either. -But since I couldn't find any documentation on this API, -I'll leave it to the porter to decide that. -- Fingolfin + unsigned char buf[256]; + + buf[0] = 0xF0; + memcpy(buf + 1, msg, length); + buf[length + 1] = 0xF7; - TwMidiSysEx(_midiHandle, 0, (byte *)msg, length); + TwMidiSysEx(_midiHandle, 0, (byte *)buf, length + 2); } MidiDriver *MidiDriver_Zodiac_create() { diff --git a/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc b/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc Binary files differindex f7661a3121..856fc32edb 100644 --- a/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc +++ b/backends/platform/PalmOS/Rsc/Resource.Frk/Starter.rsrc diff --git a/backends/platform/PalmOS/Rsc/StarterRsc.h b/backends/platform/PalmOS/Rsc/StarterRsc.h index 58a1f79ab0..99836d4a77 100644 --- a/backends/platform/PalmOS/Rsc/StarterRsc.h +++ b/backends/platform/PalmOS/Rsc/StarterRsc.h @@ -3,7 +3,7 @@ // Header generated by Constructor for Palm OS (R) 1.9.1 // -// Generated at 17:51:34 on dimanche 14 janvier 2007 +// Generated at 13:30:37 on mardi 1 mai 2007 // // Generated for file: Starter.rsrc // @@ -200,7 +200,9 @@ #define EngineOkButton 1403 //(Left Origin = 4, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) #define EngineCancelButton 1420 //(Left Origin = 45, Top Origin = 139, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) #define EngineUnnamed1402Label 1402 //(Left Origin = 4, Top Origin = 16, Usable = 1, Font = Bold) -#define EngineListList 1401 //(Left Origin = 4, Top Origin = 30, Width = 148, Usable = 1, Font = Standard, Visible Items = 9) +#define EngineUnnamed1404Label 1404 //(Left Origin = 4, Top Origin = 88, Usable = 1, Font = Bold) +#define EngineListList 1401 //(Left Origin = 4, Top Origin = 30, Width = 148, Usable = 1, Font = Standard, Visible Items = 5) +#define EngineSupportedList 1405 //(Left Origin = 4, Top Origin = 102, Width = 148, Usable = 1, Font = Standard, Visible Items = 3) // Resource: tFRM 4000 #define InfoForm 4000 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) diff --git a/backends/platform/PalmOS/Src/base_event.cpp b/backends/platform/PalmOS/Src/base_event.cpp index 7da7cd5861..1f7d07f4ae 100644 --- a/backends/platform/PalmOS/Src/base_event.cpp +++ b/backends/platform/PalmOS/Src/base_event.cpp @@ -81,7 +81,7 @@ void OSystem_PalmBase::battery_handler() { } } -bool OSystem_PalmBase::pollEvent(Event &event) { +bool OSystem_PalmBase::pollEvent(Common::Event &event) { ::EventType ev; Boolean handled; UInt32 keyCurrentState; @@ -92,52 +92,60 @@ bool OSystem_PalmBase::pollEvent(Event &event) { sound_handler(); for(;;) { -#if defined(COMPILE_OS5) && defined(PALMOS_ARM) - SysEventGet(&ev, evtNoWait); -#else - EvtGetEvent(&ev, evtNoWait); -#endif - // check for hardkey repeat for mouse emulation - keyCurrentState = KeyCurrentState(); - // check_hard_keys(); + // if it was a key pressed, let the keyup event raise + if (_wasKey) { + // check for hardkey repeat for mouse emulation + keyCurrentState = KeyCurrentState(); - if (!(keyCurrentState & _keyMouseMask)) { - _lastKeyRepeat = 0; - } else { - if (getMillis() >= (_keyMouseRepeat + _keyMouseDelay)) { - _keyMouseRepeat = getMillis(); + if (!(keyCurrentState & _keyExtraMask)) { + _lastKeyRepeat = 0; + + } else if (getMillis() >= (_keyExtraRepeat + _keyExtraDelay)) { + _keyExtraRepeat = getMillis(); if (gVars->arrowKeys) { - event.kbd.keycode = 0; - - if (keyCurrentState & _keyMouse.bitUp) - event.kbd.keycode = 273; - else if (keyCurrentState & _keyMouse.bitDown) - event.kbd.keycode = 274; - else if (keyCurrentState & _keyMouse.bitLeft) - event.kbd.keycode = 276; - else if (keyCurrentState & _keyMouse.bitRight) - event.kbd.keycode = 275; - - if (event.kbd.keycode) { - event.type = Common::EVENT_KEYDOWN; - event.kbd.ascii = event.kbd.keycode; - event.kbd.flags = 0; - return true; +/* if HARD_KEY(Up, chrUpArrow) + else if HARD_KEY(Down, chrDownArrow) + else if HARD_KEY(Left, chrLeftArrow) + else if HARD_KEY(Right, chrRightArrow) +*/ + } else { + // button released ? + if (_keyExtraPressed) { + if (_keyExtraPressed & _keyExtra.bitActionA) { + if (!(keyCurrentState & _keyExtra.bitActionA)) { + _keyExtraPressed &= ~_keyExtra.bitActionA; + + event.type = Common::EVENT_LBUTTONUP; + event.mouse.x = _mouseCurState.x; + event.mouse.y = _mouseCurState.y; + return true; + } + } + + if (_keyExtraPressed & _keyExtra.bitActionB) { + if (!(keyCurrentState & _keyExtra.bitActionB)) { + _keyExtraPressed &= ~_keyExtra.bitActionB; + + event.type = Common::EVENT_RBUTTONUP; + event.mouse.x = _mouseCurState.x; + event.mouse.y = _mouseCurState.y; + return true; + } + } } - } else { Int8 sx = 0; Int8 sy = 0; - if (keyCurrentState & _keyMouse.bitUp) + if (keyCurrentState & _keyExtra.bitUp) sy = -1; - else if (keyCurrentState & _keyMouse.bitDown) + else if (keyCurrentState & _keyExtra.bitDown) sy = +1; - if (keyCurrentState & _keyMouse.bitLeft) + if (keyCurrentState & _keyExtra.bitLeft) sx = -1; - else if (keyCurrentState & _keyMouse.bitRight) + else if (keyCurrentState & _keyExtra.bitRight) sx = +1; if (sx || sy) { @@ -148,12 +156,42 @@ bool OSystem_PalmBase::pollEvent(Event &event) { warpMouse(x, y); return true; - } + } } } } - if (ev.eType == keyDownEvent) { +#if defined(COMPILE_OS5) && defined(PALMOS_ARM) + SysEventGet(&ev, evtNoWait); +#else + EvtGetEvent(&ev, evtNoWait); +#endif + + if (ev.eType == keyUpEvent) { + int k = 0; + switch (ev.data.keyUp.chr) { + + // arrow keys + case chrUpArrow: + k = 273; break; + case chrDownArrow: + k = 274; break; + case chrLeftArrow: + k = 275; break; + case chrRightArrow: + k = 276; break; + } + + if (k) { + event.type = Common::EVENT_KEYUP; + event.kbd.keycode = k; + event.kbd.ascii = k; + event.kbd.flags = 0; + return true; + } + + } else if (ev.eType == keyDownEvent) { + int k = 0; switch (ev.data.keyDown.chr) { // ESC key case vchrLaunch: @@ -180,6 +218,24 @@ bool OSystem_PalmBase::pollEvent(Event &event) { case vchrContrast: // do nothing return true; + + // arrow keys + case chrUpArrow: + k = 273; break; + case chrDownArrow: + k = 274; break; + case chrLeftArrow: + k = 275; break; + case chrRightArrow: + k = 276; break; + } + + if (k) { + event.type = Common::EVENT_KEYDOWN; + event.kbd.keycode = k; + event.kbd.ascii = k; + event.kbd.flags = 0; + return true; } } @@ -192,11 +248,13 @@ bool OSystem_PalmBase::pollEvent(Event &event) { ((ev.data.keyDown.chr == vchrAttnStateChanged) || (ev.data.keyDown.chr == vchrAttnUnsnooze))); + // graffiti strokes, auto-off, etc... if (!handled) if (SysHandleEvent(&ev)) continue; + switch(ev.eType) { case penMoveEvent: get_coordinates(&ev, x, y); @@ -222,7 +280,7 @@ bool OSystem_PalmBase::pollEvent(Event &event) { num += 9 - (3 - (3 * x / _screenWidth )) - (3 * (3 * y / _screenHeight)); - + event.type = Common::EVENT_KEYDOWN; event.kbd.keycode = num; event.kbd.ascii = num; @@ -252,7 +310,7 @@ bool OSystem_PalmBase::pollEvent(Event &event) { event.mouse.y = y; warpMouse(x, y); return true; - + case keyDownEvent: if (ev.data.keyDown.chr == vchrCommand && (ev.data.keyDown.modifiers & commandKeyMask)) { @@ -302,7 +360,7 @@ bool OSystem_PalmBase::pollEvent(Event &event) { } else if ((key == 'z' && mask == Common::KBD_CTRL) || (mask == Common::KBD_ALT && key == 'x')) { event.type = Common::EVENT_QUIT; return true; - + // num pad (indy fight mode) } else if (key == 'n' && mask == (Common::KBD_CTRL|Common::KBD_ALT) && !_overlayVisible) { _useNumPad = !_useNumPad; @@ -310,7 +368,7 @@ bool OSystem_PalmBase::pollEvent(Event &event) { displayMessageOnOSD(_useNumPad ? "Fight mode on." : "Fight mode off."); return false; } - + // other keys _wasKey = true; event.type = Common::EVENT_KEYDOWN; @@ -320,7 +378,7 @@ bool OSystem_PalmBase::pollEvent(Event &event) { return true; default: - if (_wasKey) { + if (_wasKey && ev.eType != keyHoldEvent) { event.type = Common::EVENT_KEYUP; _wasKey = false; return true; diff --git a/backends/platform/PalmOS/Src/base_mouse.cpp b/backends/platform/PalmOS/Src/base_mouse.cpp index 2f3d3f5476..99b89b7f8c 100644 --- a/backends/platform/PalmOS/Src/base_mouse.cpp +++ b/backends/platform/PalmOS/Src/base_mouse.cpp @@ -26,22 +26,53 @@ void OSystem_PalmBase::warpMouse(int x, int y) { if (x != _mouseCurState.x || y != _mouseCurState.y) { + x = x >= _screenWidth ? _screenWidth - 1 : x; + y = y >= _screenHeight ? _screenHeight - 1 : y; + _mouseCurState.x = x; _mouseCurState.y = y; - undraw_mouse(); } } bool OSystem_PalmBase::showMouse(bool visible) { - if (_mouseVisible == visible) - return visible; - bool last = _mouseVisible; _mouseVisible = visible; return last; } +void OSystem_PalmBase::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { + if (w == 0 || h == 0) + return; + + _mouseHotspotX = hotspotX; + _mouseHotspotY = hotspotY; + + _mouseKeyColor = keycolor; + + if (_mouseCurState.w != w || _mouseCurState.h != h) { + _mouseCurState.w = w; + _mouseCurState.h = h; + + if (_mouseDataP) + free(_mouseDataP); + + if (_mouseBackupP) + free(_mouseBackupP); + + _mouseDataP = (byte *)malloc(w * h); + _mouseBackupP = (byte *)malloc(w * h * 2); // if 16bit = *2 + } + + if (!_mouseBackupP) { + free(_mouseDataP); + _mouseDataP = NULL; + } + + if (_mouseDataP) + memcpy(_mouseDataP, buf, w * h); +} + void OSystem_PalmBase::simulate_mouse(Common::Event &event, Int8 iHoriz, Int8 iVert, Coord *xr, Coord *yr) { Int16 x = _mouseCurState.x; Int16 y = _mouseCurState.y; diff --git a/backends/platform/PalmOS/Src/be_base.cpp b/backends/platform/PalmOS/Src/be_base.cpp index 8776376ee5..705a2597fd 100644 --- a/backends/platform/PalmOS/Src/be_base.cpp +++ b/backends/platform/PalmOS/Src/be_base.cpp @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2001-2007 The ScummVM project + * Copyright (C) 2002-2007 Chris Apers - PalmOS Backend * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -64,16 +64,18 @@ OSystem_PalmBase::OSystem_PalmBase() { _mixerMgr = 0; _mouseDataP = NULL; + _mouseBackupP = NULL; _mouseVisible = false; _mouseDrawn = false; - MemSet(&_keyMouse, sizeof(_keyMouse), 0); + MemSet(&_keyExtra, sizeof(_keyExtra), 0); MemSet(&_mouseCurState, sizeof(_mouseCurState), 0); MemSet(&_mouseOldState, sizeof(_mouseOldState), 0); MemSet(&_timer, sizeof(TimerType), 0); MemSet(&_sound, sizeof(SoundType), 0); - _keyMouseRepeat = 0; - _keyMouseDelay = (gVars->arrowKeys) ? computeMsecs(125) : computeMsecs(25); + _keyExtraRepeat = 0; + _keyExtraPressed = 0; + _keyExtraDelay = (gVars->arrowKeys) ? computeMsecs(125) : computeMsecs(25); } static int timer_handler(int t) { @@ -86,13 +88,13 @@ void OSystem_PalmBase::initBackend() { if (gVars->autoSave != -1) ConfMan.setInt("autosave_period", gVars->autoSave); - _keyMouse.bitUp = keyBitPageUp; - _keyMouse.bitDown = keyBitPageDown; - _keyMouse.bitLeft = keyBitHard2; - _keyMouse.bitRight = keyBitHard3; + _keyExtra.bitUp = keyBitPageUp; + _keyExtra.bitDown = keyBitPageDown; + _keyExtra.bitLeft = keyBitHard2; + _keyExtra.bitRight = keyBitHard3; int_initBackend(); - _keyMouseMask = (_keyMouse.bitUp | _keyMouse.bitDown | _keyMouse.bitLeft | _keyMouse.bitRight); + _keyExtraMask = (_keyExtra.bitUp | _keyExtra.bitDown | _keyExtra.bitLeft | _keyExtra.bitRight | _keyExtra.bitActionA | _keyExtra.bitActionB); // Create the savefile manager, if none exists yet (we check for this to // allow subclasses to provide their own). @@ -143,7 +145,12 @@ void OSystem_PalmBase::quit() { int_quit(); clearSoundCallback(); unload_gfx_mode(); - + + if (_mouseDataP) { + MemPtrFree(_mouseBackupP); + MemPtrFree(_mouseDataP); + } + delete _saveMgr; delete _timerMgr; delete _mixerMgr; diff --git a/backends/platform/PalmOS/Src/be_base.h b/backends/platform/PalmOS/Src/be_base.h index cd4c38980e..65ed93d9a5 100644 --- a/backends/platform/PalmOS/Src/be_base.h +++ b/backends/platform/PalmOS/Src/be_base.h @@ -25,9 +25,13 @@ #ifndef BE_BASE_H #define BE_BASE_H +#include "PalmVersion.h" +#include "globals.h" + #include "common/stdafx.h" #include "common/scummsys.h" #include "common/system.h" +#include "common/events.h" namespace Audio { class Mixer; @@ -52,6 +56,12 @@ enum { kModifierCount }; +// Mouse button event +enum { + vchrMouseLeft = vchrHardKeyMax - 2, + vchrMouseRight = vchrHardKeyMax - 1 +}; + // OSD resource id #define kDrawKeyState 3000 #define kDrawNumPad 3010 @@ -94,7 +104,6 @@ private: virtual void draw_mouse() = 0; virtual void undraw_mouse() = 0; -// virtual bool check_hard_keys() = 0; virtual bool check_event(Common::Event &event, EventPtr ev) = 0; virtual void timer_handler(); @@ -107,12 +116,10 @@ private: virtual void clearSoundCallback() = 0; protected: + OSystem_PalmBase(); + virtual void draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color = 0); - enum { - MAX_MOUSE_W = 80, - MAX_MOUSE_H = 80 - }; struct MousePos { int16 x,y,w,h; }; @@ -145,13 +152,15 @@ protected: Boolean _overlayVisible; Boolean _redawOSD, _setPalette; - UInt32 _keyMouseMask, _keyMouseRepeat, _keyMouseDelay; + UInt32 _keyExtraMask, _keyExtraPressed, _keyExtraRepeat, _keyExtraDelay; struct { UInt32 bitUp; UInt32 bitDown; UInt32 bitLeft; UInt32 bitRight; - } _keyMouse; + UInt32 bitActionA; // left mouse button + UInt32 bitActionB; // right mouse button + } _keyExtra; bool _mouseVisible; bool _mouseDrawn; @@ -163,7 +172,7 @@ protected: byte *_mouseDataP, *_mouseBackupP; - eventsEnum _wasKey; + bool _wasKey; UInt8 _lastKeyModifier; UInt32 _lastKeyRepeat; Boolean _useNumPad, _showBatLow; @@ -172,7 +181,6 @@ protected: int _samplesPerSec; public: - OSystem_PalmBase(); void initBackend(); /* @@ -216,7 +224,7 @@ public: bool showMouse(bool visible); void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) = 0; + void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale); virtual void showOverlay() = 0; virtual void hideOverlay() = 0; diff --git a/backends/platform/PalmOS/Src/be_os5.cpp b/backends/platform/PalmOS/Src/be_os5.cpp index 74551607b7..d3e1d3578f 100644 --- a/backends/platform/PalmOS/Src/be_os5.cpp +++ b/backends/platform/PalmOS/Src/be_os5.cpp @@ -23,11 +23,7 @@ */ #include "be_os5.h" - -#ifndef __TWKEYS_H__ -#include <PalmNavigator.h> #include <HsKeyCommon.h> -#endif OSystem_PalmOS5::OSystem_PalmOS5() : OSystem_PalmBase() { _sound.active = false; @@ -78,18 +74,12 @@ void OSystem_PalmOS5::calc_rect(Boolean fullscreen) { } void OSystem_PalmOS5::int_initBackend() { - if (OPTIONS_TST(kOpt5WayNavigatorV1)) { - _keyMouse.bitUp = keyBitPageUp; - _keyMouse.bitDown = keyBitPageDown; - _keyMouse.bitLeft = keyBitNavLeft; - _keyMouse.bitRight = keyBitNavRight; - - } else if (OPTIONS_TST(kOpt5WayNavigatorV2)) { - _keyMouse.bitUp = keyBitRockerUp|keyBitPageUp; - _keyMouse.bitDown = keyBitRockerDown|keyBitPageDown; - _keyMouse.bitLeft = keyBitRockerLeft; - _keyMouse.bitRight = keyBitRockerRight; - } + _keyExtra.bitUp = keyBitRockerUp|keyBitPageUp; + _keyExtra.bitDown = keyBitRockerDown|keyBitPageDown; + _keyExtra.bitLeft = keyBitRockerLeft; + _keyExtra.bitRight = keyBitRockerRight; + _keyExtra.bitActionA = keyBitHard3; + _keyExtra.bitActionB = keyBitHard4; } bool OSystem_PalmOS5::hasFeature(Feature f) { diff --git a/backends/platform/PalmOS/Src/be_os5.h b/backends/platform/PalmOS/Src/be_os5.h index e6c4227e71..b4b68bc920 100644 --- a/backends/platform/PalmOS/Src/be_os5.h +++ b/backends/platform/PalmOS/Src/be_os5.h @@ -99,6 +99,9 @@ typedef struct { extern SoundExType _soundEx; class OSystem_PalmOS5 : public OSystem_PalmBase { +protected: + int16 _nativePal[256], _mousePal[256]; + private: uint16 _scaleTableX[512]; uint32 _scaleTableY[512]; @@ -108,7 +111,6 @@ private: OverlayColor *_overlayP; WinHandle _overlayH, _workScreenH; - int16 _nativePal[256], _mousePal[256]; int16 *_workScreenP; Boolean _isSwitchable, _wasRotated; @@ -124,7 +126,7 @@ private: void draw_mouse(); void undraw_mouse(); virtual bool check_event(Common::Event &event, EventPtr ev); - virtual void extras_palette(uint8 index, uint8 r, uint8 g, uint8 b); + void extras_palette(uint8 index, uint8 r, uint8 g, uint8 b); void calc_scale(); void render_landscapeAny(RectangleType &r, PointType &p); @@ -168,8 +170,7 @@ public: void clearScreen(); bool grabRawScreen(Graphics::Surface *surf); - void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale); - virtual void setCursorPalette(const byte *colors, uint start, uint num); + void setCursorPalette(const byte *colors, uint start, uint num); void disableCursorPalette(bool disable); void showOverlay(); @@ -179,7 +180,7 @@ public: virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); - + void setWindowCaption(const char *caption); }; diff --git a/backends/platform/PalmOS/Src/be_os5ex.cpp b/backends/platform/PalmOS/Src/be_os5ex.cpp index f6f95ac06e..c498568ab3 100644 --- a/backends/platform/PalmOS/Src/be_os5ex.cpp +++ b/backends/platform/PalmOS/Src/be_os5ex.cpp @@ -38,7 +38,7 @@ OSystem_PalmOS5Ex::OSystem_PalmOS5Ex() : OSystem_PalmOS5() { _timerEx.timer = &_timer; _timerEx.ticks = SysTicksPerSecond(); } -/* + static SYSTEM_CALLBACK void timer_handler(void *userDataP) { CALLBACK_PROLOGUE TimerExPtr _timerEx = (TimerExPtr)userDataP; @@ -73,7 +73,7 @@ void OSystem_PalmOS5Ex::setTimerCallback(TimerProc callback, int timer) { if (!_timer.active) _timerEx.timerID = 0; } -*/ + OSystem::MutexRef OSystem_PalmOS5Ex::createMutex() { UInt32 mutexID; Err e = KALMutexCreate(&mutexID, appFileCreator); @@ -95,9 +95,8 @@ void OSystem_PalmOS5Ex::deleteMutex(MutexRef mutex) { if (mutex) KALMutexDelete((UInt32)mutex); } -/* + void OSystem_PalmOS5Ex::int_quit() { if (_timerEx.timerID) KALTimerDelete(_timerEx.timerID); } -*/
\ No newline at end of file diff --git a/backends/platform/PalmOS/Src/be_os5ex.h b/backends/platform/PalmOS/Src/be_os5ex.h index fb4027ccce..7d8cf4b607 100644 --- a/backends/platform/PalmOS/Src/be_os5ex.h +++ b/backends/platform/PalmOS/Src/be_os5ex.h @@ -45,9 +45,9 @@ typedef struct { class OSystem_PalmOS5Ex : public OSystem_PalmOS5 { private: -// void timer_handler() {}; - void sound_handler() {}; -// void int_quit(); + void timer_handler() {} + void sound_handler() {} + void int_quit(); SndStreamVariableBufferCallback sound_callback(); @@ -55,7 +55,7 @@ public: OSystem_PalmOS5Ex(); static OSystem *create(); -// void setTimerCallback(TimerProc callback, int interval); + void setTimerCallback(TimerProc callback, int interval); MutexRef createMutex(); void lockMutex(MutexRef mutex); diff --git a/backends/platform/PalmOS/Src/be_zodiac.cpp b/backends/platform/PalmOS/Src/be_zodiac.cpp index ce4dfa6013..76e3ed8562 100644 --- a/backends/platform/PalmOS/Src/be_zodiac.cpp +++ b/backends/platform/PalmOS/Src/be_zodiac.cpp @@ -33,10 +33,13 @@ OSystem_PalmZodiac::OSystem_PalmZodiac() : OSystem_PalmOS5Ex() { } void OSystem_PalmZodiac::int_initBackend() { - _keyMouse.bitUp = keyBitRockerUp; - _keyMouse.bitDown = keyBitRockerDown; - _keyMouse.bitLeft = keyBitRockerLeft; - _keyMouse.bitRight = keyBitRockerRight; + _keyExtra.bitUp = keyBitRockerUp; + _keyExtra.bitDown = keyBitRockerDown; + _keyExtra.bitLeft = keyBitRockerLeft; + _keyExtra.bitRight = keyBitRockerRight; + +// _keyExtra.bitActionA = keyBitActionD; +// _keyExtra.bitActionB = keyBitActionB; } void OSystem_PalmZodiac::calc_rect(Boolean fullscreen) { diff --git a/backends/platform/PalmOS/Src/be_zodiac.h b/backends/platform/PalmOS/Src/be_zodiac.h index 1d28afa493..c93004c89a 100644 --- a/backends/platform/PalmOS/Src/be_zodiac.h +++ b/backends/platform/PalmOS/Src/be_zodiac.h @@ -36,7 +36,6 @@ private: TwGfxType *_gfxH; TwGfxSurfaceType *_palmScreenP, *_tmpScreenP; TwGfxSurfaceType *_overlayP; - UInt16 _nativePal[256], _mousePal[256]; Boolean _fullscreen; TwGfxPointType _srcPos; @@ -53,7 +52,6 @@ private: void load_gfx_mode(); void hotswap_gfx_mode(int mode); - void extras_palette(uint8 index, uint8 r, uint8 g, uint8 b); void calc_rect(Boolean fullscreen); bool check_event(Common::Event &event, EventPtr ev); void draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color = 0); @@ -69,8 +67,6 @@ public: void updateScreen(); - void setCursorPalette(const byte *colors, uint start, uint num); - void clearOverlay(); void grabOverlay(OverlayColor *buf, int pitch); void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); diff --git a/backends/platform/PalmOS/Src/cdaudio.h b/backends/platform/PalmOS/Src/cdaudio.h index 1c1d42e7e9..206f6087c5 100644 --- a/backends/platform/PalmOS/Src/cdaudio.h +++ b/backends/platform/PalmOS/Src/cdaudio.h @@ -54,8 +54,8 @@ public: virtual void setVolume(int volume) { _volumeLevel = volume; } virtual int getVolume() const { return _volumeLevel; } - virtual void upVolume(int value) {}; - virtual void downVolume(int value) {}; + virtual void upVolume(int value) {} + virtual void downVolume(int value) {} protected: int _volumeLevel; diff --git a/backends/platform/PalmOS/Src/extend.cpp b/backends/platform/PalmOS/Src/extend.cpp index f2b9bbcc0a..0d7f19d582 100644 --- a/backends/platform/PalmOS/Src/extend.cpp +++ b/backends/platform/PalmOS/Src/extend.cpp @@ -22,14 +22,15 @@ * */ +#include "PalmVersion.h" #include <stdlib.h> #include "globals.h" #include "modulesrsc.h" -const Char *SCUMMVM_SAVEPATH = "/PALM/Programs/ScummVM/Saved"; +const char *SCUMMVM_SAVEPATH = "/PALM/Programs/ScummVM/Saved"; -void PalmFatalError(const Char *err) { +void PalmFatalError(const char *err) { WinSetDrawWindow(WinGetDisplayWindow()); WinPalette(winPaletteSetToDefault,0,0,0); WinSetBackColor(0); diff --git a/backends/platform/PalmOS/Src/launcher/app.cpp b/backends/platform/PalmOS/Src/launcher/app.cpp index ea028e6b7f..3f57f77125 100644 --- a/backends/platform/PalmOS/Src/launcher/app.cpp +++ b/backends/platform/PalmOS/Src/launcher/app.cpp @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2001-2007 The ScummVM project + * Copyright (C) 2002-2007 Chris Apers - PalmOS Backend * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,6 +24,7 @@ #include <PalmOS.h> #include <SonyClie.h> +#include <SysGlue.h> #include "StarterRsc.h" #include "palmdefs.h" @@ -34,7 +35,6 @@ #include "mathlib.h" #include "formCards.h" #include "games.h" -#include "extend.h" #include "modules.h" #include "init_mathlib.h" @@ -172,6 +172,7 @@ static void AppStartCheckScreenSize() { OPTIONS_RST(kOptCollapsible); OPTIONS_RST(kOptModeWide); OPTIONS_RST(kOptModeLandscape); + OPTIONS_RST(kOptModeRotatable); // we are on a sony device if (OPTIONS_TST(kOptDeviceClie)) { @@ -186,6 +187,8 @@ static void AppStartCheckScreenSize() { OPTIONS_SET(kOptCollapsible); OPTIONS_SET(kOptModeWide); OPTIONS_SET((mode == PALM_LANDSCAPE) ? kOptModeLandscape : kOptNone); + // TODO: doesn't work with Sony + OPTIONS_SET(SysGlueTrapExists(pinSysSetOrientation) ? kOptModeRotatable :kOptNone); } } diff --git a/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp b/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp index ccb3d09f8a..15772c6aab 100644 --- a/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp +++ b/backends/platform/PalmOS/Src/launcher/forms/formCards.cpp @@ -364,6 +364,7 @@ void CardSlotCreateDirs() { VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Saved"); VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Audio"); VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Mods"); + VFSDirCreate(gPrefs->card.volRefNum, "/PALM/Programs/ScummVM/Themes"); } } diff --git a/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp b/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp index 9b4009294c..28ff9c6747 100644 --- a/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp +++ b/backends/platform/PalmOS/Src/launcher/forms/formMisc.cpp @@ -190,12 +190,14 @@ static void MiscFormInit() { TabAddContent(&frmP, tabP, "ScummVM", TabMiscScummVMForm); TabAddContent(&frmP, tabP, "More ...", TabMiscExtsForm); + if (OPTIONS_TST(kOptDeviceARM)) { + FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscPalmOSStdPaletteCheckbox)); + TabMoveUpObject(frmP, TabMiscPalmOSAdvancedCheckbox, 12); + } + if (!OPTIONS_TST(kOptDeviceARM) || OPTIONS_TST(kOptDeviceZodiac)) FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscPalmOSAdvancedCheckbox)); - if (OPTIONS_TST(kOptDeviceARM)) - FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscPalmOSStdPaletteCheckbox)); - if (!OPTIONS_TST(kOptGoLcdAPI)) { FrmRemoveObject(&frmP, FrmGetObjectIndex(frmP, TabMiscExtsGolcdCheckbox)); // move lightspeed diff --git a/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp b/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp new file mode 100755 index 0000000000..179723f18a --- /dev/null +++ b/backends/platform/PalmOS/Src/launcher/forms/formSelect.cpp @@ -0,0 +1,276 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2007 The ScummVM project + * Copyright (C) 2002-2007 Chris Apers - PalmOS Backend + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include <PalmOS.h> +#include "StarterRsc.h" +#include "formUtil.h" +#include "games.h" +#include "start.h" +#include "common/util.h" + +static Char **items = NULL; +Int16 selectedEngine = -1; + +// Supported games +static const char *engine_agos[] = { + "Demon in my Pocket", + "Elvira - Mistress of the Dark", + "Elvira II - The Jaws of Cerberus", + "Jumble", + "NoPatience", + "Simon the Sorcerer I", + "Simon the Sorcerer II", + "Swampy Adventures", + "The Feeble Files", + "Waxworks" +}; + +static const char *engine_sky[] = { + "Floppy, CD and Demo" +}; + +static const char *engine_sword1[] = { + "The Shadow of the Templars (PC/Mac)", + "The Shadow of the Templars (Demo)" +}; + +static const char *engine_sword2[] = { + "The Smoking Mirror", + "The Smoking Mirror (Demo)" +}; + +static const char *engine_cine[] = { + "Future Wars", + "Operation Stealth" +}; + +static const char *engine_queen[] = { + "Flight of the Amazon Queen" +}; + +static const char *engine_lure[] = { + "Lure of the Tempress" +}; + +static const char *engine_gob[] = { + "Bargon Attack", + "Gobliiins", + "Gobliins 2", + "Goblins Quest 3", + "The Bizarre Adventures of Woodruff and the Schnibble", + "Ween: The Prophecy", +}; + +static const char *engine_kyra[] = { + "The Legend of Kyrandia", + "The Legend of Kyrandia: The Hand of Fate", + "The Legend of Kyrandia: Malcolm's Revenge" +}; + +static const char *engine_parallaction[] = { + "Nippon Safes Inc." +}; + +static const char *engine_saga[] = { + "I Have No Mouth And I Must Scream", + "Inherit the earth" +}; + +static const char *engine_scumm[] = { + "Day of the Tentacle", + "Indiana Jones and the Fate of Atlantis", + "Indiana Jones and the Last Crusade", + "Loom", + "Maniac Mansion", + "Monkey Island 2: LeChuck's Revenge", + "Passport to Adventure", + "Sam & Max Hit the Road", + "The Secret of Monkey Island" + "Zak McKracken and the Alien Mindbenders" +}; + +static const char *engine_agi[] = { + "AGI Tetris", + "Caitlyn's Destiny", + "Donald Duck's Playground", + "Fanmade AGI game", + "Gold Rush!", + "King's Quest I: Quest for the Crown", + "King's Quest II: Romancing the Throne", + "King's Quest III: To Heir Is Human", + "King's Quest IV: The Perils of Rosella", + "Leisure Suit Larry in the Land of the Lounge Lizards", + "Mixed-Up Mother Goose", + "Manhunter 1: New York", + "Manhunter 2: San Francisco", + "Police Quest I: In Pursuit of the Death Angel", + "Serguei's Destiny 1", + "Serguei's Destiny 2", + "Space Quest 0: Replicated", + "Space Quest I: The Sarien Encounter", + "Space Quest II: Vohaul's Revenge", + "Space Quest X: The Lost Chapter", + "The Black Cauldron", + "Xmas Card" +}; + +static const char *engine_touche[] = { + "Touche: The Adventures of the Fifth Musketeer" +}; + +static const char *engine_cruise[] = { + "Cruise for a Corpse" +}; + +static const struct { + int size; + const char **listP; +} supported[] = { + { ARRAYSIZE(engine_agos), engine_agos }, + { ARRAYSIZE(engine_sky), engine_sky }, + { ARRAYSIZE(engine_sword1), engine_sword1 }, + { ARRAYSIZE(engine_sword2), engine_sword2 }, + { ARRAYSIZE(engine_cine), engine_cine }, + { ARRAYSIZE(engine_queen), engine_queen }, + { ARRAYSIZE(engine_lure), engine_lure }, + { ARRAYSIZE(engine_gob), engine_gob }, + { ARRAYSIZE(engine_kyra), engine_kyra }, + { ARRAYSIZE(engine_parallaction), engine_parallaction }, + { ARRAYSIZE(engine_saga), engine_saga }, + { ARRAYSIZE(engine_scumm), engine_scumm }, + { ARRAYSIZE(engine_agi), engine_agi }, + { ARRAYSIZE(engine_touche), engine_touche }, + { ARRAYSIZE(engine_cruise), engine_cruise } +}; + +static void SelectorSetList(Int16 sel) { + ListType *listP; + FormPtr frmP = FrmGetActiveForm(); + + Boolean toBeDrawn = (items != NULL); + if (items) + MemPtrFree(items); + + listP = (ListType *)FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EngineSupportedList)); + items = (Char **)MemPtrNew(supported[sel].size * sizeof(Char *)); + + for (int i = 0; i < supported[sel].size; i++) + items[i] = (Char *)supported[sel].listP[i]; + + LstSetListChoices (listP, items, supported[sel].size); + LstSetTopItem(listP, 0); + LstSetSelection(listP, -1); + + if (toBeDrawn) { + WinScreenLock(winLockCopy); + LstDrawList(listP); + WinScreenUnlock(); + } +} + +static void SelectorFormInit() { + ListType *listP; + FormPtr frmP = FrmGetActiveForm(); + + listP = (ListType *)FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EngineListList)); + itemsText = (Char **)MemPtrNew(ENGINE_COUNT * sizeof(Char *)); + + for (int i = 0; i < ENGINE_COUNT; i++) + itemsText[i] = (Char *)engines[i].nameP; + + LstSetListChoices (listP, itemsText, ENGINE_COUNT); + LstSetSelection(listP, 0); + + SelectorSetList(0); + + FrmDrawForm(frmP); +} + +static void SelectorFormFree(bool quit) { + items = NULL; + + if (!quit) { + ListType *listP = (ListType *)GetObjectPtr(EngineListList); + Int16 sel = LstGetSelection(listP); + + FrmReturnToMain(); + StartScummVM(sel); + + } else { + FrmReturnToMain(); + + if (bDirectMode) { + // force exit if nothing selected + EventType event; + event.eType = keyDownEvent; + event.data.keyDown.chr = vchrLaunch; + event.data.keyDown.modifiers = commandKeyMask; + EvtAddUniqueEventToQueue(&event, 0, true); + } + } +} + +Boolean SelectorFormHandleEvent(EventPtr eventP) { + FormPtr frmP = FrmGetActiveForm(); + Boolean handled = false; + + switch (eventP->eType) { + case frmOpenEvent: + SelectorFormInit(); + handled = true; + break; + + case frmCloseEvent: + SelectorFormFree(true); + handled = true; + break; + + case lstSelectEvent: + if (eventP->data.lstSelect.listID == EngineSupportedList) + LstSetSelection(eventP->data.lstSelect.pList, -1); + else + SelectorSetList(eventP->data.lstSelect.selection); + handled = true; + break; + + case ctlSelectEvent: + switch (eventP->data.ctlSelect.controlID) + { + case EngineOkButton: + SelectorFormFree(false); + break; + + case EngineCancelButton: + SelectorFormFree(true); + break; + } + handled = true; + break; + + default: + break; + } + + return handled; +} diff --git a/backends/platform/PalmOS/Src/launcher/forms/formUtil.h b/backends/platform/PalmOS/Src/launcher/forms/formUtil.h index 90cf1ff37a..e9b87bc49f 100644 --- a/backends/platform/PalmOS/Src/launcher/forms/formUtil.h +++ b/backends/platform/PalmOS/Src/launcher/forms/formUtil.h @@ -4,6 +4,8 @@ #define frmRedrawUpdateMS (frmRedrawUpdateCode + 1) #define frmRedrawUpdateMSImport (frmRedrawUpdateCode + 2) +#define NO_ENGINE -1 + // form list draw #define ITEM_TYPE_UNKNOWN 'U' #define ITEM_TYPE_CARD 'C' diff --git a/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp b/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp index 1709b4c7a2..bd3263350d 100644 --- a/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp +++ b/backends/platform/PalmOS/Src/launcher/forms/formmain.cpp @@ -299,8 +299,10 @@ Boolean MainFormHandleEvent(EventPtr eventP) case skinButtonGameStart: if (gPrefs->card.volRefNum == vfsInvalidVolRef) FrmCustomAlert(FrmWarnAlert,"Please select/insert a memory card.", 0, 0); + else if (GamGetSelected() != dmMaxRecordIndex) + StartScummVM(); else - bStartScumm = true; + FrmPopupForm(EngineForm); handled = true; break; diff --git a/backends/platform/PalmOS/Src/launcher/forms/forms.h b/backends/platform/PalmOS/Src/launcher/forms/forms.h index 0bdfd356c7..ca0089d8c1 100644 --- a/backends/platform/PalmOS/Src/launcher/forms/forms.h +++ b/backends/platform/PalmOS/Src/launcher/forms/forms.h @@ -18,5 +18,6 @@ HANDLER(CardSlot) HANDLER(Skins) HANDLER(Music) HANDLER(Info) +HANDLER(Selector) #endif diff --git a/backends/platform/PalmOS/Src/launcher/games.cpp b/backends/platform/PalmOS/Src/launcher/games.cpp index d0e162a4cc..c9fd0a661b 100644 --- a/backends/platform/PalmOS/Src/launcher/games.cpp +++ b/backends/platform/PalmOS/Src/launcher/games.cpp @@ -32,7 +32,6 @@ #include "games.h" #include "skin.h" -#include "extend.h" #include "StarterRsc.h" DmOpenRef gameDB = NULL; diff --git a/backends/platform/PalmOS/Src/launcher/games.h b/backends/platform/PalmOS/Src/launcher/games.h index c80c99eda3..235aca38de 100644 --- a/backends/platform/PalmOS/Src/launcher/games.h +++ b/backends/platform/PalmOS/Src/launcher/games.h @@ -170,6 +170,7 @@ enum { ENGINE_SCUMM, ENGINE_AGI, ENGINE_TOUCHE, + ENGINE_CRUISE, ENGINE_COUNT }; @@ -179,21 +180,21 @@ static const struct { } engines[] = { { "agos", "AGOS Engine" }, { "sky", "Beneath a Steel Sky" }, - { "sword1", "Broken Sword 1" }, - { "sword2", "Broken Sword 2" }, + { "sword1", "Broken Sword I" }, + { "sword2", "Broken Sword II" }, { "cine", "Delphine Cinematique v1.0" }, { "queen", "Flight of the Amazon Queen" }, { "lure", "Lure of the Tempress" }, - { "gob", "Gobliiins" }, + { "gob", "Gobliiins, Bargon Attack and more ..." }, { "kyra", "Kyrandia" }, { "parallaction", "Parallaction" }, { "saga", "SAGA Engine" }, { "scumm", "Scumm Games" }, { "agi", "Sierra AGI" }, { "touche", "Touche: The Adventures of the Fifth Musketeer" }, + { "cruise", "Cruise for a Corpse" }, }; - // protos Err GamOpenDatabase (); void GamImportDatabase (); diff --git a/backends/platform/PalmOS/Src/launcher/launch.cpp b/backends/platform/PalmOS/Src/launcher/launch.cpp index 7dd775d77d..8e5de05c8d 100644 --- a/backends/platform/PalmOS/Src/launcher/launch.cpp +++ b/backends/platform/PalmOS/Src/launcher/launch.cpp @@ -29,7 +29,6 @@ #include "games.h" #include "start.h" #include "rumble.h" -#include "extend.h" #include "globals.h" #include "features.h" #include "formUtil.h" @@ -188,54 +187,23 @@ onError: #undef CHECK_FILE #undef BUILD_FILE -Boolean StartScummVM() { +Boolean StartScummVM(Int16 engine) { Char **argvP; UInt8 lightspeed, argc = 0; UInt32 stackSize; Boolean toLauncher, direct, isARM; - UInt8 engine; Char num[6]; - UInt16 index = GamGetSelected(); - argvP = ArgsInit(); direct = false; // start command line (exec name) ArgsAdd(&argvP[argc], "-", NULL, &argc); + UInt16 index = GamGetSelected(); // no game selected if (index == dmMaxRecordIndex) { - ListPtr listP; - UInt16 whichButton; - - // init form - FormPtr frmP = FrmInitForm(EngineForm); - listP = (ListType *)FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EngineListList)); - itemsText = (Char **)MemPtrNew(ENGINE_COUNT * sizeof(Char *)); - - for (int i = 0; i < ENGINE_COUNT; i++) - itemsText[i] = (Char *)engines[i].nameP; - - LstSetListChoices (listP, itemsText, ENGINE_COUNT); - LstSetSelection(listP, 0); - - whichButton = FrmDoDialog(frmP); - engine = LstGetSelection(listP); - - FrmDeleteForm(frmP); - MemPtrFree(itemsText); - itemsText = NULL; - - if (whichButton == EngineCancelButton) { - if (bDirectMode) { - // and force exit if nothing selected - EventType event; - event.eType = keyDownEvent; - event.data.keyDown.chr = vchrLaunch; - event.data.keyDown.modifiers = commandKeyMask; - EvtAddUniqueEventToQueue(&event, 0, true); - } + if (engine == NO_ENGINE) { // free args ArgsFree(argvP); return false; @@ -244,6 +212,7 @@ Boolean StartScummVM() { // default values if (bDirectMode) gPrefs->card.volRefNum = parseCards(); // always use the first removable card available (?) + gVars->filter = true; gVars->palmVolume = 50; gVars->fmQuality = FM_QUALITY_INI; @@ -455,7 +424,11 @@ Boolean StartScummVM() { // gVars values // (gVars->HRrefNum defined in checkHRmode on Cli) +#ifndef _DEBUG_ENGINE gVars->VFS.volRefNum = (gPrefs->card.autoDetect ? vfsInvalidVolRef : gPrefs->card.volRefNum); +#else + gVars->VFS.volRefNum = gPrefs->card.volRefNum; +#endif gVars->vibrator = gPrefs->vibrator; gVars->stdPalette = gPrefs->stdPalette; gVars->VFS.cacheSize = (gPrefs->card.useCache ? gPrefs->card.cacheSize : 0); diff --git a/backends/platform/PalmOS/Src/launcher/start.cpp b/backends/platform/PalmOS/Src/launcher/start.cpp index 076c24d6c2..e68228cc77 100644 --- a/backends/platform/PalmOS/Src/launcher/start.cpp +++ b/backends/platform/PalmOS/Src/launcher/start.cpp @@ -43,7 +43,6 @@ GlobalsPreferencePtr gPrefs; GlobalsDataPtr gVars; Boolean bDirectMode = false; -Boolean bStartScumm = false; Boolean bLaunched = false; /*********************************************************************** @@ -200,6 +199,10 @@ static Boolean AppHandleEvent(EventPtr eventP) { FrmSetEventHandler(frmP, InfoFormHandleEvent); break; + case EngineForm: + FrmSetEventHandler(frmP, SelectorFormHandleEvent); + break; + default: // ErrFatalDisplay("Invalid Form Load Event"); break; @@ -231,9 +234,6 @@ static void AppEventLoop(void) { do { EvtGetEvent(&event, evtNoWait); - if(bStartScumm) - bStartScumm = StartScummVM(); - if (! SysHandleEvent(&event)) if (! MenuHandleEvent(0, &event, &error)) if (! AppHandleEvent(&event)) @@ -330,7 +330,7 @@ static UInt32 ScummVMPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) { FrmGotoForm(MainForm); }else { GamUnselect(); - bStartScumm = true; + FrmGotoForm(EngineForm); } AppEventLoop(); diff --git a/backends/platform/PalmOS/Src/launcher/start.h b/backends/platform/PalmOS/Src/launcher/start.h index f08d551763..acf9081a83 100644 --- a/backends/platform/PalmOS/Src/launcher/start.h +++ b/backends/platform/PalmOS/Src/launcher/start.h @@ -79,7 +79,6 @@ typedef struct { extern GlobalsPreferencePtr gPrefs; extern Boolean bDirectMode; -extern Boolean bStartScumm; extern Boolean bLaunched; #define appPrefID 0x00 @@ -92,7 +91,7 @@ extern Boolean bLaunched; Err AppStart(void); void AppStop(void); -Boolean StartScummVM(); +Boolean StartScummVM(Int16 engine = -1); void SavePrefs(); Err SendDatabase (UInt16 cardNo, LocalID dbID, Char *nameP, Char *descriptionP); #endif diff --git a/backends/platform/PalmOS/Src/missing/ext_stdio.c b/backends/platform/PalmOS/Src/missing/ext_stdio.c deleted file mode 100644 index f7d37a9140..0000000000 --- a/backends/platform/PalmOS/Src/missing/ext_stdio.c +++ /dev/null @@ -1,650 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <stdio.h> -#include <stdlib.h> -#include <PmPalmOSNVFS.h> - -#define CACHE_SIZE 1024 -enum { - MODE_BUFREAD = 1, - MODE_BUFWRITE, - MODE_BUFNONE -}; - -FILE gStdioOutput = {0,0,0,0,0,0}; -static void dummy(Boolean) {}; - -static LedProc gStdioLedProc = dummy; -static UInt16 gStdioVolRefNum = vfsInvalidVolRef; -static UInt32 gCacheSize = CACHE_SIZE; - -// TODO : implement "errno" - -void StdioInit(UInt16 volRefNum, const Char *output) { // DONE - gStdioVolRefNum = volRefNum; - gStdioOutput.mode = MODE_BUFWRITE; - - VFSFileDelete(gStdioVolRefNum, output); - VFSFileCreate(gStdioVolRefNum, output); - VFSFileOpen (gStdioVolRefNum, output,vfsModeWrite, &gStdioOutput.fileRef); -} - -void StdioSetLedProc(LedProc ledProc) { // DONE - if (ledProc) - gStdioLedProc = ledProc; - else - gStdioLedProc = dummy; -} - -void StdioSetCacheSize(UInt32 s) { // DONE - gCacheSize = s; -} - -void StdioRelease() { // DONE - // there is no cache on stdout/stderr - VFSFileClose(gStdioOutput.fileRef); -} - -UInt16 fclose(FILE *stream) { // DONE - UInt32 numBytesWritten; - Err e; - - if (stream->cacheSize) { - if (stream->bufSize > 0 && stream->mode == MODE_BUFWRITE) - VFSFileWrite(stream->fileRef, stream->bufSize, stream->cache, &numBytesWritten); - - MemPtrFree(stream->cache); - } - - e = VFSFileClose(stream->fileRef); - e = MemPtrFree(stream); - - return e; -} - -UInt16 feof(FILE *stream) { // DONE - Err e; - - if (stream->cacheSize) { - switch (stream->mode) { - case MODE_BUFWRITE: - return 0; // never set in this mode - case MODE_BUFREAD: - if (stream->bufSize > 0) - return 0; - break; - } - } - - e = VFSFileEOF(stream->fileRef); - return e; -} - -UInt16 ferror(FILE *stream) { - return (stream->err); -} - -Int16 fgetc(FILE *stream) { - UInt32 numBytesRead; - Char c; - - numBytesRead = fread(&c, 1, 1, stream); - return (int)(numBytesRead == 1 ? c : EOF); -} - -Char *fgets(Char *s, UInt32 n, FILE *stream) { - UInt32 numBytesRead; - - numBytesRead = fread(s, n, 1, stream); - if (numBytesRead) { - UInt32 reset = 0; - Char *endLine = StrChr(s, '\n'); - - if (endLine >= s) { - reset = (endLine - s); - s[reset] = 0; - reset = numBytesRead - (reset + 1); - fseek(stream, -reset, SEEK_CUR); - } - - return s; - } - - return NULL; -} - -FILE *fopen(const Char *filename, const Char *type) { // DONE - Err err; - UInt16 openMode; - Boolean cache = true; - FILE *fileP = (FILE *)MemPtrNew(sizeof(FILE)); - - if (!fileP) - return NULL; - - MemSet(fileP, sizeof(FILE), 0); - - if (StrCompare(type,"r")==0 || StrCompare(type,"rb")==0) { - fileP->mode = MODE_BUFREAD; - openMode = vfsModeRead; - - } else if (StrCompare(type,"w")==0 || StrCompare(type,"wb")==0) { - fileP->mode = MODE_BUFWRITE; - openMode = vfsModeCreate|vfsModeWrite; - - } else { - cache = false; - fileP->mode = MODE_BUFNONE; - openMode = vfsModeReadWrite; - } - - if (cache) { - fileP->cacheSize = gCacheSize; - if (gCacheSize) fileP->cache = (UInt8 *)malloc(gCacheSize); // was MemGluePtrNew - if (!fileP->cache) fileP->cacheSize = 0; - } - - if (openMode & vfsModeRead) { - // if read file : - // first try to load from the specfied card - err = VFSFileOpen (gStdioVolRefNum, filename, openMode, &fileP->fileRef); - //if err (not found ?) parse each avalaible card for the specified file - if (err) { - UInt16 volRefNum; - UInt32 volIterator = vfsIteratorStart|vfsIncludePrivateVolumes; - while (volIterator != vfsIteratorStop) { - err = VFSVolumeEnumerate(&volRefNum, &volIterator); - - if (!err) { - err = VFSFileOpen (volRefNum, filename, openMode, &fileP->fileRef); - if (!err) - return fileP; - } - } - } else { - return fileP; - } - } else { - // if write file : - // use only the specified card - err = VFSFileDelete(gStdioVolRefNum, filename); // delete it if exists - err = VFSFileCreate(gStdioVolRefNum, filename); - openMode = vfsModeWrite; - if (!err) { - err = VFSFileOpen (gStdioVolRefNum, filename, openMode, &fileP->fileRef); - if (!err) - return fileP; - } - } - - if (fileP->cacheSize) - MemPtrFree(fileP->cache); - - MemPtrFree(fileP); // prevent memory leak - return NULL; -} - -UInt32 fread(void *ptr, UInt32 size, UInt32 nitems, FILE *stream) { // DONE - Err e = errNone; - UInt32 numBytesRead, rsize = (size * nitems); - - // try to read on a write only stream ? - if (stream->mode == MODE_BUFWRITE || !rsize) - return 0; - - // cached ? - if (stream->cacheSize) { - // empty buffer ? fill it if required - if (stream->bufSize == 0 && rsize < stream->cacheSize) { - gStdioLedProc(true); - e = VFSFileRead(stream->fileRef, stream->cacheSize, stream->cache, &numBytesRead); - gStdioLedProc(false); - stream->bufSize = numBytesRead; - stream->bufPos = 0; - } - - // we have the data in the cache - if (stream->bufSize >= rsize) { - MemMove(ptr, (stream->cache + stream->bufPos), rsize); - stream->bufPos += rsize; - stream->bufSize -= rsize; - numBytesRead = rsize; - - // not enough but something ? - } else if (stream->bufSize > 0) { - UInt8 *next = (UInt8 *)ptr; - MemMove(ptr, (stream->cache + stream->bufPos), stream->bufSize); - rsize -= stream->bufSize; - gStdioLedProc(true); - e = VFSFileRead(stream->fileRef, rsize, (next + stream->bufSize), &numBytesRead); - gStdioLedProc(false); - numBytesRead += stream->bufSize; - stream->bufSize = 0; - stream->bufPos = 0; - - // nothing in the cache ? - } else { - gStdioLedProc(true); - e = VFSFileRead(stream->fileRef, rsize, ptr, &numBytesRead); - gStdioLedProc(false); - } - - // no ? direct read - } else { - gStdioLedProc(true); - e = VFSFileRead(stream->fileRef, rsize, ptr, &numBytesRead); - gStdioLedProc(false); - } - - if (e == errNone || e == vfsErrFileEOF) - return (UInt32)(numBytesRead / size); - - return 0; -} - -UInt32 fwrite(const void *ptr, UInt32 size, UInt32 nitems, FILE *stream) { // DONE - Err e = errNone; - UInt32 numBytesWritten = (size * nitems); - - // try to write on a read only stream ? - if (stream->mode == MODE_BUFREAD || !numBytesWritten) - return 0; - - // cached ? - if (stream->cacheSize) { - // can cache it ? - if ((stream->bufSize + numBytesWritten) <= stream->cacheSize) { - MemMove((stream->cache + stream->bufSize), ptr, numBytesWritten); - stream->bufSize += numBytesWritten; - - // not enough room ? write cached data and new data - } else { - gStdioLedProc(true); - e = VFSFileWrite(stream->fileRef, stream->bufSize, stream->cache, &numBytesWritten); - e = VFSFileWrite(stream->fileRef, (size * nitems), ptr, &numBytesWritten); - gStdioLedProc(false); - stream->bufSize = 0; - } - - // no ? direct write - } else { - gStdioLedProc(true); - e = VFSFileWrite(stream->fileRef, (size * nitems), ptr, &numBytesWritten); - gStdioLedProc(false); - } - - if ((e == errNone || e == vfsErrFileEOF)) { - return (UInt32)(numBytesWritten / size); - } - - return 0; -} - -Int16 fseek(FILE *stream, Int32 offset, Int32 whence) { // DONE - UInt32 numBytesWritten; - Err e; - - if (stream->cacheSize) { - switch (stream->mode) { - case MODE_BUFWRITE: - e = VFSFileWrite(stream->fileRef, stream->bufSize, stream->cache, &numBytesWritten); - stream->bufSize = 0; - break; - - case MODE_BUFREAD: - // reposition file postion if needed - if (whence == SEEK_CUR) - e = VFSFileSeek(stream->fileRef, vfsOriginCurrent, -stream->bufSize); - stream->bufSize = 0; - stream->bufPos = 0; - break; - } - } - - e = VFSFileSeek(stream->fileRef, whence, offset); - return (e ? -1 : 0); -} - -Int32 ftell(FILE *stream) { // DONE - Err e; - UInt32 filePos; - - e = VFSFileTell(stream->fileRef ,&filePos); - - if (stream->cacheSize) { - switch (stream->mode) { - case MODE_BUFWRITE: - filePos += stream->bufSize; - break; - - case MODE_BUFREAD: - filePos -= stream->bufSize; - break; - } - } - - if (e) return -1; // errno = ? - return filePos; -} - -Int32 fprintf(FILE *stream, const Char *formatStr, ...) { // DONE - UInt32 numBytesWritten; - Char buf[256]; - va_list va; - - if (!stream->fileRef) - return 0; - - va_start(va, formatStr); - vsprintf(buf, formatStr, va); - va_end(va); - - numBytesWritten = fwrite(buf, StrLen(buf), 1, stream); - return numBytesWritten; -} - -Int32 printf(const Char *format, ...) { // DONE - UInt32 numBytesWritten; - Char buf[256]; - va_list va; - - if (!stdout->fileRef) - return 0; - - va_start(va, format); - vsprintf(buf, format, va); - va_end(va); - - numBytesWritten = fwrite(buf, StrLen(buf), 1, stdout); - return numBytesWritten; -} - -/* needed with 68k mode only, already defined in ARM MSL */ -#ifdef PALMOS_68K - -Int32 sprintf(Char* s, const Char* formatStr, ...) { - Int16 count; - va_list va; - - va_start(va, formatStr); - count = vsprintf(s, formatStr, va); - va_end(va); - - return count; -} - -Int32 snprintf(Char* s, UInt32 len, const Char* formatStr, ...) { - // len is ignored - Int16 count; - va_list va; - - va_start(va, formatStr); - count = vsprintf(s, formatStr, va); - va_end(va); - - return count; -} - - -/* WARNING : vsprintf - * ------- - * This function can handle only %[+- ][.0][field length][sxXdoiucp] format strings - * compiler option : 4byte int mode only ! - * - * TODO : check http://www.ijs.si/software/snprintf/ for a portable implementation of vsnprintf - * This one make use of sprintf so need to check if it works with PalmOS. - */ - -static Char *StrIToBase(Char *s, Int32 i, UInt8 b) { - const Char *conv = "0123456789ABCDEF"; - Char o; - Int16 c, n = 0; - Int32 div, mod; - - do { - div = i / b; - mod = i % b; - - s[n++] = *(conv + mod); - i = div; - - } while (i >= b); - - if (i > 0) { - s[n + 0] = *(conv + i); - s[n + 1] = 0; - } else { - s[n + 0] = 0; - n--; - } - - for (c=0; c <= (n >> 1); c++) { - o = s[c]; - s[c] = s[n - c]; - s[n - c]= o; - } - - return s; -} - -static void StrProcC_(Char *ioStr, UInt16 maxLen) { - Char *found; - Int16 length; - - while (found = StrStr(ioStr, "`c`")) { - if (found[3] == 0) { // if next char is NULL - length = maxLen - (found - ioStr + 2); - MemMove(found, found + 4, length); - maxLen -= 2; - } - } -} - -static void StrProcXO(Char *ioStr, UInt16 maxLen, Char *tmp) { - Char *found, *last, mod, fill; - Int16 len, count, next; - Int32 val; - - while (found = StrChr(ioStr, '`')) { - last = StrChr(found + 1, '`'); - - if (!last) - return; - - *last = 0; - next = 0; - fill = *(found + 1); - mod = *(found + 2); - count = StrAToI(found + 3); - - len = maxLen - (last - ioStr); - MemMove(found, (last + 1), len); - - // x and X always 8char on palmos ... o set to 8char (not supported on palmos) - while ((found[next] == '0' || found[next] == ' ') && next < 8) // WARNING : reduce size only (TODO ?) - next++; - - // convert to base 8 - if (mod == 'o') { - StrNCopy(tmp, found + next, 8 - next); - tmp[8 - next] = 0; - val = StrAToI(tmp); - StrIToBase(tmp, val, 8); // now we have the same but in octal - next = 8 - StrLen(tmp); - MemMove(found + next, tmp, StrLen(tmp)); - } else { - // if val is 0, keep last 0 - if (next == 8) - next = 7; - } - - if ((8 - next) > count) - count = 8 - next; - - if (count == 0) - count = 1; - - len = maxLen - (found - ioStr) - (8 - count); - MemSet(found, next, fill); - MemMove(found, found + (8 - count), len); - - // ... and upper case - if (mod == 'x') { - while (count--) { - if (*found >='A' && *found <='F') - *found = (*found + 32); - found++; - } - } - } -} - -Int32 vsprintf(Char* s, const Char* formatStr, _Palm_va_list argParam) { - Char format[256], result[256], tmp[32]; - - Char *found, *mod, *num; - UInt32 next; - Boolean zero; - Int16 count, len; - - MemSet(format, sizeof(format), 'x'); - MemSet(result, sizeof(result), 'y'); - MemSet(tmp, sizeof(tmp), 'z'); - - StrCopy(format,formatStr); // copy actual formatStr to temp buffer - next = 0; // start of the string - - while (found = StrChr(format + next, '%')) { - mod = found + 1; - - if (*mod == '%') { // just a % ? - mod++; - - } else { - if (*mod == '+' || - *mod == '-' || - *mod == ' ' ) // skip - mod++; - - if (*mod == '0' || - *mod == '.' ) { - *mod++ = '0'; - zero = true; - } else { - zero = false; - } - - num = mod; - while ( *mod >= '0' && - *mod <= '9' ) // search format char - mod++; - - // get the numeric value - if (num < mod) { - StrNCopy(tmp, num, mod - num); - tmp[mod - num] = 0; - count = StrAToI(tmp); - } else { - count = 0; - } - - if (*mod == 'l') // already set to %...l(x) ? - mod++; - - // prepare new format -//#if !defined(PALMOS_ARM) - if (*mod == 'c') { - StrCopy(tmp, "`c`%c%c"); - - } else -//#endif - if (*mod == 'p') { - StrCopy(tmp, "%08lX"); // %x = %08X in palmos - - } else { - len = 0; - - switch (*mod) { - case 'x': - case 'X': - case 'o': - tmp[0] = '`'; - tmp[1] = (zero) ? '0' : ' '; - tmp[2] = *mod; - StrIToA(tmp + 3, count); - len += StrLen(tmp); - tmp[len++] = '`'; - tmp[len] = 0; - - if (*mod == 'o') { // set as base 10 num and convert later - *mod = 'd'; - count = 8; // force 8char - } - - break; - } - - StrNCopy(tmp + len, found, (num - found)); - len += (num - found); - - if (count) { - StrIToA(tmp + len, count); - len += StrLen(tmp + len); - } - - if (*mod == 'd' || - *mod == 'i' || - *mod == 'x' || - *mod == 'X' || - *mod == 'u' - ) { - tmp[len++] = 'l'; - } - - tmp[len + 0] = *mod; - tmp[len + 1] = 0; - } - - mod++; - MemMove(found + StrLen(tmp), mod, StrLen(mod) + 1); - StrNCopy(found, tmp, StrLen(tmp)); - mod = found + StrLen(tmp); - } - - next = (mod - format); - } - - // Copy result in a temp buffer to process last formats - StrVPrintF(result, format, argParam); -//#if !defined(PALMOS_ARM) - StrProcC_(result, 256); -//#endif - StrProcXO(result, 256, tmp); - StrCopy(s, result); - - return StrLen(s); -} - -#endif diff --git a/backends/platform/PalmOS/Src/missing/ext_stdlib.c b/backends/platform/PalmOS/Src/missing/ext_stdlib.c deleted file mode 100644 index 701e3bca69..0000000000 --- a/backends/platform/PalmOS/Src/missing/ext_stdlib.c +++ /dev/null @@ -1,139 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <stdlib.h> - -#ifdef STDLIB_TRACE_MEMORY -UInt32 __stdlib_trace_memory = 0; -#endif - -#define memNewChunkFlagAllowLarge 0x1000 -SysAppInfoPtr SysGetAppInfo(SysAppInfoPtr *uiAppPP, SysAppInfoPtr *actionCodeAppPP) SYS_TRAP(sysTrapSysGetAppInfo); - -#ifdef PALMOS68K -long strtol(const char *s, char **endptr, int base) { - // WARNING : only base = 10 supported - long val = StrAToI(s); - - if (endptr) { - Char str[maxStrIToALen]; - StrIToA(str, val); - - if (StrNCompare(s, str, StrLen(str)) == 0) - *endptr = (char *)s + StrLen(str); - } - - return val; -} -#endif - -MemPtr __malloc(UInt32 size) { - MemPtr newP = NULL; - - if (size <= 65000) { - newP = MemPtrNew(size); - } else { - SysAppInfoPtr appInfoP; - UInt16 ownerID; - UInt16 attr; - - ownerID = ((SysAppInfoPtr)SysGetAppInfo(&appInfoP, &appInfoP))->memOwnerID; - attr = ownerID|memNewChunkFlagAllowLarge|memNewChunkFlagNonMovable; - - newP = MemChunkNew(0, size, attr); - } - -#ifdef STDLIB_TRACE_MEMORY - __stdlib_trace_memory += size; -#endif - return newP; -} - -MemPtr calloc(UInt32 nelem, UInt32 elsize) { - MemPtr newP; - UInt32 size = (nelem * elsize); - - newP = malloc(size); // was MemGluePtrNew - - if (newP) - MemSet(newP,size,0); - -#ifdef STDLIB_TRACE_MEMORY - __stdlib_trace_memory += size; -#endif - return newP; -} - -Err free(MemPtr memP) { - if (memP) { -#ifdef STDLIB_TRACE_MEMORY - UInt32 sz = MemPtrSize(memP); - __stdlib_trace_memory -= sz; -#endif - return MemPtrFree(memP); - } - - return memErrInvalidParam; -} - -MemPtr realloc(MemPtr oldP, UInt32 size) { - MemPtr newP; - -#ifdef STDLIB_TRACE_MEMORY - UInt32 sz = MemPtrSize(oldP); - __stdlib_trace_memory -= sz; - __stdlib_trace_memory += size; -#endif - - if (oldP != NULL) - if (MemPtrResize(oldP, size) == 0) - return oldP; - - newP = malloc(size); // was MemPtrNew - - if (oldP!=NULL) { - MemMove(newP,oldP,MemPtrSize(oldP)); - MemPtrFree(oldP); - } - - return newP; -} - -ErrJumpBuf stdlib_errJumpBuf; -#define ERR_MAGIC 0xDADA - -void exit(Int16 status) { - EventType event; - event.eType = keyDownEvent; - - event.data.keyDown.chr = vchrLaunch; - event.data.keyDown.modifiers = commandKeyMask; -#ifdef PALMOS_ARM - SysEventAddUniqueToQueue(&event, 0, true); -#else - EvtAddUniqueEventToQueue(&event, 0, true); -#endif - - ErrLongJump(stdlib_errJumpBuf, status == 0 ? 0xDADA : status); -} diff --git a/backends/platform/PalmOS/Src/missing/ext_time.c b/backends/platform/PalmOS/Src/missing/ext_time.c deleted file mode 100644 index 5de64062b0..0000000000 --- a/backends/platform/PalmOS/Src/missing/ext_time.c +++ /dev/null @@ -1,85 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include <time.h> - -time_t time(time_t *tloc) { - // get ROM version - UInt32 romVersion; - Err e = FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); - - // since 1/1/1904 12AM. - UInt32 secs = TimGetSeconds(); - - // form 1/1/1904 12AM to 1/1/1970 12AM - DateTimeType Epoch = {0, 0, 0, 1, 1, 1970, 0}; - - secs -= TimDateTimeToSeconds(&Epoch); - - // DST really supported from OS v4.0 - if (romVersion >= sysMakeROMVersion(4,0,0,sysROMStageRelease,0)) - secs -= (PrefGetPreference(prefTimeZone) + PrefGetPreference(prefDaylightSavingAdjustment)) * 60; - else - secs -= (PrefGetPreference(prefMinutesWestOfGMT) - 720) * 60; - - if (tloc) - *tloc = secs; - - return (secs); -} - - -struct tm *localtime(const time_t *timer) { - static struct tm tmDate; - DateTimeType dt; - UInt32 secs = *timer; - - // get ROM version - UInt32 romVersion; - Err e = FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); - - // form 1/1/1904 12AM to 1/1/1970 12AM - DateTimeType Epoch = {0, 0, 0, 1, 1, 1970, 0}; - - // timer supposed to be based on Epoch - secs += TimDateTimeToSeconds(&Epoch); - - // DST really supported from OS v4.0 - if (romVersion >= sysMakeROMVersion(4,0,0,sysROMStageRelease,0)) - secs += (PrefGetPreference(prefTimeZone) + PrefGetPreference(prefDaylightSavingAdjustment)) * 60; - else - secs += (PrefGetPreference(prefMinutesWestOfGMT) - 720) * 60; // no sure about this one - - TimSecondsToDateTime (secs, &dt); - - tmDate.tm_sec = dt.second; - tmDate.tm_min = dt.minute; - tmDate.tm_hour = dt.hour; - tmDate.tm_mday = dt.day; - tmDate.tm_mon = dt.month - 1; - tmDate.tm_year = dt.year - 1900; - tmDate.tm_wday = dt.weekDay; - - return &tmDate; -} diff --git a/backends/platform/PalmOS/Src/missing/fcntl.h b/backends/platform/PalmOS/Src/missing/fcntl.h deleted file mode 100644 index 59daa2ae05..0000000000 --- a/backends/platform/PalmOS/Src/missing/fcntl.h +++ /dev/null @@ -1,42 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef FCNTL_H -#define FCNTL_H - -#define O_TEXT 0x0 /* 960827: Added this for Visual C++ compatibility. */ -#define O_RDWR 0x1 /* open the file in read/write mode */ /*- mm 980420 -*/ -#define O_RDONLY 0x2 /* open the file in read only mode */ /*- mm 980420 -*/ -#define O_WRONLY 0x4 /* open the file in write only mode */ /*- mm 980420 -*/ -#define O_APPEND 0x0100 /* open the file in append mode */ -#define O_CREAT 0x0200 /* create the file if it doesn't exist */ -#define O_EXCL 0x0400 /* if the file already exists don't create it again */ -#define O_TRUNC 0x0800 /* truncate the file after opening it */ -#define O_NRESOLVE 0x1000 /* Don't resolve any aliases */ -#define O_ALIAS 0x2000 /* Open alias file (if the file is an alias) */ -#define O_RSRC 0x4000 /* Open the resource fork */ -#define O_BINARY 0x8000 /* open the file in binary mode (default is text mode) */ -#define F_DUPFD 0x0 /* return a duplicate file descriptor */ - -#endif diff --git a/backends/platform/PalmOS/Src/missing/stdio.h b/backends/platform/PalmOS/Src/missing/stdio.h deleted file mode 100644 index 490da720a5..0000000000 --- a/backends/platform/PalmOS/Src/missing/stdio.h +++ /dev/null @@ -1,103 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef __STDIO_H__ -#define __STDIO_H__ - -#include "palmversion.h" -#include <stdarg.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (*LedProc)(Boolean show); -typedef UInt32 size_t; - -typedef struct { - FileRef fileRef; - UInt32 cacheSize, bufSize, bufPos; - UInt8 *cache; - UInt16 mode, err; -} FILE; - -#undef stdin -#undef stdout -#undef stderr - -#define stdin 0 -#define stdout (&gStdioOutput) -#define stderr (&gStdioOutput) - -#undef SEEK_SET -#undef SEEK_CUR -#undef SEEK_END - -#define SEEK_SET vfsOriginBeginning -#define SEEK_CUR vfsOriginCurrent -#define SEEK_END vfsOriginEnd - -extern FILE gStdioOutput; - -void StdioInit (UInt16 volRefNum, const Char *output); -void StdioSetLedProc (LedProc ledProc); -void StdioSetCacheSize (UInt32 s); -void StdioRelease (); - -/* missing functions in 68k MSL (some are defined in ARM) */ -#define clearerr(a) -#define fflush(a) -#define getc(a) fgetc(a) -#define vsnprintf(a,b,c,d) vsprintf(a,c,d) - -UInt16 fclose (FILE *stream); -UInt16 feof (FILE *stream); -UInt16 ferror (FILE *stream); -Char *fgets (Char *s, UInt32 n, FILE *stream); -Int16 fgetc (FILE *stream); -FILE *fopen (const Char *filename, const Char *type); -UInt32 fread (void *ptr, UInt32 size, UInt32 nitems, FILE *stream); -UInt32 fwrite (const void *ptr, UInt32 size, UInt32 nitems, FILE *stream); -Int16 fseek (FILE *stream, Int32 offset, Int32 whence); -Int32 ftell (FILE *stream); - -Int32 fprintf (FILE *stream, const Char *formatStr, ...); -Int32 printf (const Char* formatStr, ...); -Int32 sprintf (Char* s, const Char* formatStr, ...); -Int32 snprintf (Char* s, UInt32 len, const Char* formatStr, ...); -Int32 vsprintf (Char* s, const Char* formatStr, _Palm_va_list argParam); - -/* ARM MSL only */ -#ifdef PALMOS_ARM -#undef vsnprintf - -int vsnprintf (char *str, size_t size, const char *format, va_list ap); -int sscanf ( char * buffer, const char * format, ...); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/missing/stdlib.h b/backends/platform/PalmOS/Src/missing/stdlib.h deleted file mode 100644 index 95e65b3232..0000000000 --- a/backends/platform/PalmOS/Src/missing/stdlib.h +++ /dev/null @@ -1,93 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef STDLIB_H -#define STDLIB_H - -#include "palmversion.h" - -#ifdef PALMOS_68K -#include "MemGlue.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* malloc stuff */ -#ifdef STDLIB_TRACE_MEMORY -# define malloc __malloc - extern UInt32 __stdlib_trace_memory; -#else -# if defined(COMPILE_ZODIAC) -# define malloc MemPtrNew -# elif defined(COMPILE_OS5) && defined(PALMOS_ARM) -# define malloc __malloc -# else -# define malloc MemGluePtrNew -# endif -#endif - -/* custom exit (true exit !) */ -extern ErrJumpBuf stdlib_errJumpBuf; -#define DO_EXIT( code ) \ - if (ErrSetJump(stdlib_errJumpBuf) == 0) { code } - -/* mapped to system functions */ -#define atoi StrAToI -#define atol StrAToI -#define abs(a) ((a) < 0 ? -(a) : (a)) -#define qsort(a,b,c,d) SysQSort((a), (b), (c), (CmpFuncPtr)(&d), 0); -#define rand() SysRandom(0) -#define abort() -#define strtoul(a,b,c) ((unsigned long)strtol(a,b,c)) - -MemPtr __malloc (UInt32); -MemPtr calloc (UInt32 nelem, UInt32 elsize); -void exit (Int16 status); -Err free (MemPtr memP); -MemPtr realloc (MemPtr oldP, UInt32 size); -long strtol (const char *s, char **endptr, int base); - -/* already defined in MSL */ -void *bsearch (const void *key, const void *base, UInt32 nmemb, UInt32 size, int (*compar)(const void *, const void *)); - -/* ARM MSL only */ -#ifdef PALMOS_ARM -#undef qsort -#undef strtol -#undef strtoul - -typedef int (*_compare_function)(const void*, const void*); - -void qsort (void * table_base, UInt32 num_members, UInt32 member_size, _compare_function compare_members); -long int strtol (const char *nptr, char **endptr, int base); -unsigned long int strtoul (const char *nptr, char **endptr,int base); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/missing/string.h b/backends/platform/PalmOS/Src/missing/string.h deleted file mode 100644 index bb250dfe9b..0000000000 --- a/backends/platform/PalmOS/Src/missing/string.h +++ /dev/null @@ -1,66 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef PALM_STRING_H -#define PALM_STRING_H - -#include "palmversion.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* mapped to system functions */ -#define memcmp MemCmp -#define memcpy MemMove -#define memmove MemMove -#define memset(a,b,c) MemSet(a,c,b) -#define strcat StrCat -#define strncat StrNCat -#define strchr StrChr -#define strcmp StrCompare -#define strcpy StrCopy -#define strncpy StrNCopy -#define stricmp StrCaselessCompare -#define strnicmp StrNCaselessCompare -#define strlen StrLen -#define strncmp StrNCompare -#define strstr StrStr - -/* missing functions in 68k MSL */ -void *memchr (const void *s, int c, UInt32 n); -Char *strdup (const Char *strSource); - -/* already defined in MSL */ -Char *strtok (Char *str, const Char *sep); -Char *strrchr (const Char *s, int c); -Char *strpbrk (const Char *s1, const Char *s2); -UInt32 strspn (const Char *s1, const Char *s2); -UInt32 strcspn (const Char *s1, const Char *s2); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/missing/sys/stat.h b/backends/platform/PalmOS/Src/missing/sys/stat.h deleted file mode 100644 index da84fa5f6b..0000000000 --- a/backends/platform/PalmOS/Src/missing/sys/stat.h +++ /dev/null @@ -1 +0,0 @@ -/* nothing */ diff --git a/backends/platform/PalmOS/Src/native/oscalls.cpp b/backends/platform/PalmOS/Src/native/oscalls.cpp index 4520d81c20..403eec40ab 100644 --- a/backends/platform/PalmOS/Src/native/oscalls.cpp +++ b/backends/platform/PalmOS/Src/native/oscalls.cpp @@ -29,19 +29,33 @@ GlobalsType global; PACE_CLASS_WRAPPER(Err) - StatShow_68k(void) { + __68k_StatShow(void) { PACE_PIN_EXEC_NP(pinStatShow, Err) } PACE_CLASS_WRAPPER(Err) - StatHide_68k(void) { + __68k_StatHide(void) { PACE_PIN_EXEC_NP(pinStatHide, Err) } PACE_CLASS_WRAPPER(Err) - PINSetInputAreaState_68k(UInt16 state) { + __68k_PINSetInputAreaState(UInt16 state) { PACE_PARAMS_INIT() PACE_PARAMS_ADD16(state) PACE_PARAMS_END() PACE_PIN_EXEC(pinPINSetInputAreaState, Err) } + +PACE_CLASS_WRAPPER(Err) + __68k_SysSetOrientation(UInt16 orientation) { + PACE_PARAMS_INIT() + PACE_PARAMS_ADD16(orientation) + PACE_PARAMS_END() + PACE_PIN_EXEC(pinSysSetOrientation, Err) +} + +PACE_CLASS_WRAPPER(UInt16) + __68k_SysGetOrientation(void) { + PACE_PIN_EXEC_NP(pinSysGetOrientation, UInt16) +} + diff --git a/backends/platform/PalmOS/Src/native/oscalls.h b/backends/platform/PalmOS/Src/native/oscalls.h index ae8f989337..0fb030b64a 100644 --- a/backends/platform/PalmOS/Src/native/oscalls.h +++ b/backends/platform/PalmOS/Src/native/oscalls.h @@ -29,9 +29,17 @@ extern "C" { #endif -Err StatShow_68k(); -Err StatHide_68k(); -Err PINSetInputAreaState_68k(UInt16 state); +#ifdef PALMOS_ARM +# define __68K(a) __68k_##a +#else +# define __68K(a) a +#endif + +Err __68k_StatShow(); +Err __68k_StatHide(); +Err __68k_PINSetInputAreaState(UInt16 state); +Err __68k_SysSetOrientation(UInt16 orientation); +UInt16 __68k_SysGetOrientation(void); #ifdef __cplusplus } diff --git a/backends/platform/PalmOS/Src/native/pnoARM.c b/backends/platform/PalmOS/Src/native/pnoARM.c index e072abca4d..e80e651462 100644 --- a/backends/platform/PalmOS/Src/native/pnoARM.c +++ b/backends/platform/PalmOS/Src/native/pnoARM.c @@ -56,29 +56,4 @@ unsigned long PNO_Main(const void *emulStateP, void *userData68KP, Call68KFuncTy return PilotMain(sysAppLaunchCmdNormalLaunch, userData68KP, 0); } - // - // The following functions provide malloc/free support to Metrowerks - // Standard Library (MSL). This feature requires the MSL library be - // built with _MSL_OS_DIRECT_MALLOC enabled. - // -void* -__sys_alloc(UInt32 size) -{ - void * ptr = malloc(size); - ErrFatalDisplayIf(ptr == NULL, "out of memory"); - return ptr; -} - -void -__sys_free(void* ptr) -{ - (void) MemPtrFree(ptr); -} - -UInt32 -__sys_pointer_size(void* ptr) -{ - return (UInt32) MemPtrSize(ptr); -} - #endif diff --git a/backends/platform/PalmOS/Src/native/zodiacARM.cpp b/backends/platform/PalmOS/Src/native/zodiacARM.cpp index 6bea511258..d98ed9bed9 100644 --- a/backends/platform/PalmOS/Src/native/zodiacARM.cpp +++ b/backends/platform/PalmOS/Src/native/zodiacARM.cpp @@ -22,12 +22,10 @@ * */ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> +#include "PalmVersion.h" +#include <MSL_PalmOS.h> #include "globals.h" -#include "extend.h" #include "args.h" #include "palmdefs.h" @@ -49,6 +47,7 @@ GlobalsDataPtr gVars = &g_vars; UInt32 g_stackSize; extern "C" void __destroy_global_chain(void); +extern void DrawStatus(Boolean show); static void palm_main(int argc, char **argvP) { #ifdef COMPILE_OS5 @@ -88,12 +87,11 @@ static void Go() { MemMove(gVars, tmp, sizeof(GlobalsDataType)); // init STDIO - StdioSetCacheSize(0); - StdioInit(gVars->VFS.volRefNum, "/PALM/Programs/ScummVM/scumm.log"); + stdio_set_cache(0); + stdio_init(gVars->VFS.volRefNum, "/PALM/Programs/ScummVM/scumm.log"); if (gVars->indicator.showLED) - StdioSetLedProc(DrawStatus); - StdioSetCacheSize(gVars->VFS.cacheSize); - gUnistdCWD = SCUMMVM_SAVEPATH; + stdio_set_led(DrawStatus); + stdio_set_cache(gVars->VFS.cacheSize); // get args FtrGet(appFileCreator, ftrArgsData, (UInt32 *)&argvP); @@ -108,7 +106,7 @@ static void Go() { // release if (HWR_INIT(INIT_VIBRATOR)) RumbleRelease(); - StdioRelease(); + stdio_release(); #ifdef DEBUG_ARM AdnDebugNativeUnregister(); diff --git a/backends/platform/PalmOS/Src/native/zodiacStartup.cpp b/backends/platform/PalmOS/Src/native/zodiacStartup.cpp index 9a898bacb0..5e018286b7 100644 --- a/backends/platform/PalmOS/Src/native/zodiacStartup.cpp +++ b/backends/platform/PalmOS/Src/native/zodiacStartup.cpp @@ -101,31 +101,6 @@ static void relocate(void) } /* - * The following functions provide malloc/free support to Metrowerks - * Standard Library (MSL). This feature requires the MSL library be - * built with _MSL_OS_DIRECT_MALLOC enabled. - */ -void* -__sys_alloc(size_t size) -{ - void * ptr = MemPtrNew(size); - ErrFatalDisplayIf(ptr == NULL, "out of memory"); - return ptr; -} - -void -__sys_free(void* ptr) -{ - (void) MemPtrFree(ptr); -} - -size_t -__sys_pointer_size(void* ptr) -{ - return (size_t) MemPtrSize(ptr); -} - -/* * This is the real entrypoint for Tapwave Native Application. It * depends on various CodeWarrior 9.2 compiler/linker/runtime features. */ diff --git a/backends/platform/PalmOS/Src/os5_event.cpp b/backends/platform/PalmOS/Src/os5_event.cpp index 8af2a717a7..85a3b49426 100644 --- a/backends/platform/PalmOS/Src/os5_event.cpp +++ b/backends/platform/PalmOS/Src/os5_event.cpp @@ -37,19 +37,12 @@ void OSystem_PalmOS5::get_coordinates(EventPtr ev, Coord &x, Coord &y) { } } -bool OSystem_PalmOS5::check_event(Event &event, EventPtr ev) { +bool OSystem_PalmOS5::check_event(Common::Event &event, EventPtr ev) { if (ev->eType == keyUpEvent) { - switch (ev->data.keyDown.chr) { + switch (ev->data.keyUp.chr) { case vchrHard3: - event.type = Common::EVENT_LBUTTONUP; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; - return true; - case vchrHard4: - event.type = Common::EVENT_RBUTTONUP; - event.mouse.x = _mouseCurState.x; - event.mouse.y = _mouseCurState.y; + // will be handled by hard keys return true; } @@ -59,23 +52,24 @@ bool OSystem_PalmOS5::check_event(Event &event, EventPtr ev) { // hot swap gfx // case 0x1B04: case vchrHard1: - printf("swap\n"); if (OPTIONS_TST(kOptCollapsible)) hotswap_gfx_mode(_mode == GFX_WIDE ? GFX_NORMAL: GFX_WIDE); return false; // not a key // case 0x1B05: case vchrHard2: - setFeatureState(kFeatureAspectRatioCorrection, 0); - return false; // not a key + setFeatureState(kFeatureAspectRatioCorrection, 0); + return false; // not a key case vchrHard3: - event.type = Common::EVENT_RBUTTONDOWN; + _keyExtraPressed |= _keyExtra.bitActionA; + event.type = Common::EVENT_LBUTTONDOWN; event.mouse.x = _mouseCurState.x; event.mouse.y = _mouseCurState.y; return true; case vchrHard4: + _keyExtraPressed |= _keyExtra.bitActionB; event.type = Common::EVENT_RBUTTONDOWN; event.mouse.x = _mouseCurState.x; event.mouse.y = _mouseCurState.y; diff --git a/backends/platform/PalmOS/Src/os5_gfx.cpp b/backends/platform/PalmOS/Src/os5_gfx.cpp index 295c753604..c68e5ea8c7 100644 --- a/backends/platform/PalmOS/Src/os5_gfx.cpp +++ b/backends/platform/PalmOS/Src/os5_gfx.cpp @@ -28,11 +28,6 @@ #include <PenInputMgr.h> #include <palmOneResources.h> -#ifdef PALMOS_ARM -#include <System/WIP.h> -#include <Libraries/AIA/palmOneStatusBarMgrARM.h> -#endif - #include "oscalls.h" void OSystem_PalmOS5::int_initSize(uint w, uint h) { @@ -63,8 +58,6 @@ void OSystem_PalmOS5::load_gfx_mode() { _ratio.width = (gVars->screenFullHeight * _screenWidth / _screenHeight); _ratio.height = (gVars->screenFullWidth * _screenHeight / _screenWidth); - _mouseBackupP = (byte *)MemPtrNew(MAX_MOUSE_W * MAX_MOUSE_H * 2); // *2 if 16bit - _mouseDataP = (byte *)MemPtrNew(MAX_MOUSE_W * MAX_MOUSE_H); _offScreenP = (byte *)malloc(_screenWidth * _screenHeight); MemSet(_offScreenP, _screenWidth * _screenHeight, 0); @@ -75,6 +68,11 @@ void OSystem_PalmOS5::load_gfx_mode() { WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); clearScreen(); + if (OPTIONS_TST(kOptModeRotatable)) { + _sysOldOrientation = __68K(SysGetOrientation()); + __68K(SysSetOrientation(sysOrientationLandscape)); + } + gVars->indicator.on = RGBToColor(0,255,0); gVars->indicator.off = RGBToColor(0,0,0); @@ -97,13 +95,6 @@ void OSystem_PalmOS5::hotswap_gfx_mode(int mode) { if (_mode != GFX_NORMAL && !_isSwitchable) return; -#ifdef PALMOS_ARM - UInt32 device; - Boolean isT3 = false; - if (!FtrGet(sysFileCSystem, sysFtrNumOEMDeviceID, &device)) - isT3 = (device == kPalmOneDeviceIDTungstenT3); -#endif - if (_workScreenH) WinDeleteWindow(_workScreenH, false); _workScreenH = NULL; @@ -117,17 +108,9 @@ void OSystem_PalmOS5::hotswap_gfx_mode(int mode) { _stretched = (_screenWidth > gVars->screenWidth); if (OPTIONS_TST(kOptCollapsible)) { -#ifdef PALMOS_ARM - if (isT3) { - //AiaSetInputAreaState(aiaInputAreaShow); - StatShow_68k(); - PINSetInputAreaState_68k(pinInputAreaOpen); - } else -#endif - { - StatShow(); - PINSetInputAreaState(pinInputAreaOpen); - } + //AiaSetInputAreaState(aiaInputAreaShow); // For T3 ?? + __68K(StatShow()); + __68K(PINSetInputAreaState(pinInputAreaOpen)); } if (_stretched) { @@ -143,18 +126,10 @@ void OSystem_PalmOS5::hotswap_gfx_mode(int mode) { _stretched = true; if (OPTIONS_TST(kOptCollapsible)) { -#ifdef PALMOS_ARM // T3 DIA library is 68k base, there is no possible native call - if (isT3) { - //AiaSetInputAreaState(aiaInputAreaFullScreen); - PINSetInputAreaState_68k(pinInputAreaClosed); - StatHide_68k(); - } else -#endif - { - PINSetInputAreaState(pinInputAreaClosed); - StatHide(); - } + //AiaSetInputAreaState(aiaInputAreaFullScreen); + __68K(PINSetInputAreaState(pinInputAreaClosed)); + __68K(StatHide()); } calc_rect(true); @@ -182,8 +157,7 @@ void OSystem_PalmOS5::unload_gfx_mode() { return; _gfxLoaded = false; - MemPtrFree(_mouseBackupP); - MemPtrFree(_mouseDataP); + // mouse data freed in quit() free(_offScreenP); if (_workScreenH) @@ -198,6 +172,9 @@ void OSystem_PalmOS5::unload_gfx_mode() { WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); clearScreen(); + if (OPTIONS_TST(kOptModeRotatable)) + __68K(SysSetOrientation(_sysOldOrientation)); + WinSetCoordinateSystem(_sysOldCoord); } diff --git a/backends/platform/PalmOS/Src/os5_mouse.cpp b/backends/platform/PalmOS/Src/os5_mouse.cpp index 20e725694c..a0b372bfad 100644 --- a/backends/platform/PalmOS/Src/os5_mouse.cpp +++ b/backends/platform/PalmOS/Src/os5_mouse.cpp @@ -37,130 +37,86 @@ void OSystem_PalmOS5::disableCursorPalette(bool disable) { _cursorPaletteDisabled = disable; } -void OSystem_PalmOS5::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { - if (w == 0 || h == 0) - return; - -FIXME: The restriction on MAX_MOUSE_H / MAX_MOUSE_W is obsolete; -in particular, BS2 might use bigger cursors these days. -See also bug #1609058. 1607180 -Hence this code now might overwrite memory unchecked; at the -very least an assert should be inserted to cause a controlled -crash, but of course it would be better to remove the restriction -on "small" cursors. - - - _mouseCurState.w = w; - _mouseCurState.h = h; - - _mouseHotspotX = hotspotX; - _mouseHotspotY = hotspotY; - - _mouseKeyColor = keycolor; - - // copy new cursor - byte *dst = _mouseDataP; - memset(dst, MAX_MOUSE_W * MAX_MOUSE_H, keycolor); - while (h--) { - memcpy(dst, buf, w); - dst += MAX_MOUSE_W; - buf += w; - } -} - +// TODO: this code is almost the same as Zodiac version. void OSystem_PalmOS5::draw_mouse() { - if (_mouseDrawn || !_mouseVisible) + if (!_mouseDataP || _mouseDrawn || !_mouseVisible) return; - - byte *src = _mouseDataP; // Image representing the mouse - byte color; - int width; - - _mouseCurState.y = _mouseCurState.y >= _screenHeight ? _screenHeight - 1 : _mouseCurState.y; + + byte *src = _mouseDataP; int x = _mouseCurState.x - _mouseHotspotX; int y = _mouseCurState.y - _mouseHotspotY; int w = _mouseCurState.w; int h = _mouseCurState.h; - int draw_x = x; - int draw_y = y; - // clip the mouse rect - if (x < 0) { - w += x; - src -= x; - x = 0; - } if (y < 0) { + src -= y * w; h += y; - src -= y * MAX_MOUSE_W; y = 0; } - if (w > _screenWidth - x) - w = _screenWidth - x; + if (x < 0) { + src -= x; + w += x; + x = 0; + } + if (h > _screenHeight - y) h = _screenHeight - y; + if (w > _screenWidth - x) + w = _screenWidth - x; - // Quick check to see if anything has to be drawn at all if (w <= 0 || h <= 0) return; - // Store the bounding box so that undraw mouse can restore the area the - // mouse currently covers to its original content. + // store the bounding box so that undraw mouse can restore the area the + // mouse currently covers to its original content _mouseOldState.x = x; _mouseOldState.y = y; _mouseOldState.w = w; _mouseOldState.h = h; - // Quick check to see if anything has to be drawn at all - if (w <= 0 || h <= 0) - return; - - // Store the bounding box so that undraw mouse can restore the area the - // mouse currently covers to its original content. - _mouseOldState.x = x; - _mouseOldState.y = y; - _mouseOldState.w = w; - _mouseOldState.h = h; + byte color; + int ww; - // Backup the covered area draw the mouse cursor if (_overlayVisible) { - int16 *bak = (int16 *)_mouseBackupP; // Surface used to backup the area obscured by the mouse - int16 *dst = _overlayP + y * _screenWidth + x; + int16 *bak = (int16 *)_mouseBackupP; int16 *pal = _cursorPaletteDisabled ? _nativePal : _mousePal; + int16 *dst = _overlayP + y * _screenWidth + x; do { - width = w; + ww = w; do { *bak++ = *dst; color = *src++; - if (color != _mouseKeyColor) // transparent, don't draw + + // transparent, don't draw + if (color != _mouseKeyColor) *dst = pal[color]; dst++; - } while (--width); + } while (--ww); - src += MAX_MOUSE_W - w; - bak += MAX_MOUSE_W - w; + src += _mouseCurState.w - w; dst += _screenWidth - w; } while (--h); } else { - byte *bak = _mouseBackupP; // Surface used to backup the area obscured by the mouse - byte *dst =_offScreenP + y * _screenWidth + x; // Surface we are drawing into + byte *bak = _mouseBackupP; + byte *dst =_offScreenP + y * _screenWidth + x; do { - width = w; + ww = w; do { *bak++ = *dst; color = *src++; - if (color != _mouseKeyColor) // transparent, don't draw + + // transparent, don't draw + if (color != _mouseKeyColor) *dst = color; dst++; - } while (--width); + } while (--ww); - src += MAX_MOUSE_W - w; - bak += MAX_MOUSE_W - w; + src += _mouseCurState.w - w; dst += _screenWidth - w; } while (--h); } @@ -173,27 +129,28 @@ void OSystem_PalmOS5::undraw_mouse() { return; int h = _mouseOldState.h; - // No need to do clipping here, since draw_mouse() did that already + + // no need to do clipping here, since draw_mouse() did that already if (_overlayVisible) { - int16 *bak = (int16 *)_mouseBackupP; int16 *dst = _overlayP + _mouseOldState.y * _screenWidth + _mouseOldState.x; + int16 *bak = (int16 *)_mouseBackupP; do { - memcpy(dst, bak, _mouseOldState.w * 2); - bak += MAX_MOUSE_W; + MemMove(dst, bak, _mouseOldState.w * 2); dst += _screenWidth; + bak += _mouseOldState.w; } while (--h); } else { - byte *dst, *bak = _mouseBackupP; - dst = _offScreenP + _mouseOldState.y * _screenWidth + _mouseOldState.x; + byte *dst = _offScreenP + _mouseOldState.y * _screenWidth + _mouseOldState.x; + byte *bak = _mouseBackupP; do { - memcpy(dst, bak, _mouseOldState.w); - bak += MAX_MOUSE_W; + MemMove(dst, bak, _mouseOldState.w); dst += _screenWidth; + bak += _mouseOldState.w; } while (--h); } _mouseDrawn = false; -} +}
\ No newline at end of file diff --git a/backends/platform/PalmOS/Src/os5_overlay.cpp b/backends/platform/PalmOS/Src/os5_overlay.cpp index 93c6123cef..0eee6d167b 100644 --- a/backends/platform/PalmOS/Src/os5_overlay.cpp +++ b/backends/platform/PalmOS/Src/os5_overlay.cpp @@ -31,7 +31,7 @@ void OSystem_PalmOS5::showOverlay() { undraw_mouse(); _overlayVisible = true; - clearOverlay(); + clearOverlay(); } void OSystem_PalmOS5::hideOverlay() { diff --git a/backends/platform/PalmOS/Src/os5_sound.cpp b/backends/platform/PalmOS/Src/os5_sound.cpp index 4bdded13e7..7af173036f 100644 --- a/backends/platform/PalmOS/Src/os5_sound.cpp +++ b/backends/platform/PalmOS/Src/os5_sound.cpp @@ -134,7 +134,7 @@ void OSystem_PalmOS5::clearSoundCallback() { } if (_soundEx.dataP) - free(_soundEx.dataP); + MemPtrFree(_soundEx.dataP); } _sound.active = false; diff --git a/backends/platform/PalmOS/Src/palmversion.h b/backends/platform/PalmOS/Src/palmversion.h deleted file mode 100644 index d4362ddd61..0000000000 --- a/backends/platform/PalmOS/Src/palmversion.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PALMVERSION_H -#define PALMVERSION_H - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(COMPILE_ZODIAC) -# include <tapwave.h> -#else -# include <PalmOS.h> -# include <VFSMgr.h> -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/backends/platform/PalmOS/Src/prefixes/compile.h b/backends/platform/PalmOS/Src/prefixes/compile.h index f54a56d2ca..f8c5ca1cbf 100644 --- a/backends/platform/PalmOS/Src/prefixes/compile.h +++ b/backends/platform/PalmOS/Src/prefixes/compile.h @@ -43,6 +43,7 @@ #define DISABLE_AGI #define DISABLE_TOUCHE #define DISABLE_PARALLACTION +#define DISABLE_CRUISE // ScummVM #define DISABLE_HQ_SCALERS @@ -50,23 +51,24 @@ //#define CT_NO_TRANSPARENCY //#define REDUCE_MEMORY_USAGE -// PalmOS -//#define STDLIB_TRACE_MEMORY -//#define _DEBUG - -#define PALMOS_MODE -//#define COMPILE_ZODIAC -#define COMPILE_OS5 +#include "compile_base.h" //#define DISABLE_ADLIB //#define DISABLE_LIGHTSPEED #ifdef COMPILE_ZODIAC -# define DISABLE_SONY +# undef DISABLE_FANCY_THEMES +# define USE_ZLIB +// set an external ZLIB since save/load implementation +// doesn't support built-in zodiac version which is 1.1.4 +// (seen inflateInit2 which err on "MAX_WBITS + 32") +# define USE_ZLIB_EXTERNAL +# define DISABLE_SONY #endif #ifdef COMPILE_OS5 -# define DISABLE_TAPWAVE +# define DISABLE_TAPWAVE +# define USE_ZLIB #endif #endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_agi.h b/backends/platform/PalmOS/Src/prefixes/native_agi.h index 496cf7c85b..790f108efa 100644 --- a/backends/platform/PalmOS/Src/prefixes/native_agi.h +++ b/backends/platform/PalmOS/Src/prefixes/native_agi.h @@ -4,4 +4,8 @@ #include "native_common.h" #undef DISABLE_AGI +#undef USE_MAD +#undef USE_VORBIS +#undef USE_TREMOR + #endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_cine.h b/backends/platform/PalmOS/Src/prefixes/native_cine.h index 212a5544d0..bacdfa2047 100644 --- a/backends/platform/PalmOS/Src/prefixes/native_cine.h +++ b/backends/platform/PalmOS/Src/prefixes/native_cine.h @@ -3,5 +3,10 @@ #include "native_common.h" #undef DISABLE_CINE +#define _DEBUG + +#undef USE_MAD +#undef USE_VORBIS +#undef USE_TREMOR #endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_common.h b/backends/platform/PalmOS/Src/prefixes/native_common.h index c04f5e1538..af4db70932 100644 --- a/backends/platform/PalmOS/Src/prefixes/native_common.h +++ b/backends/platform/PalmOS/Src/prefixes/native_common.h @@ -2,8 +2,6 @@ #define ZNATIVE_COMMON_H #include "compile.h" -#include "palmmad.h" -#include "palmtremor.h" #define __TWNEW_H__ @@ -12,7 +10,7 @@ #define USE_MAD #define USE_TREMOR -//#define USE_VORBIS +#define USE_VORBIS //#define USE_MPEG2 // enable assert diff --git a/backends/platform/PalmOS/Src/prefixes/native_cruise.h b/backends/platform/PalmOS/Src/prefixes/native_cruise.h new file mode 100755 index 0000000000..9bc0cdac13 --- /dev/null +++ b/backends/platform/PalmOS/Src/prefixes/native_cruise.h @@ -0,0 +1,11 @@ +#ifndef PREFIX_H +#define PREFIX_H + +#include "native_common.h" +#undef DISABLE_CRUISE + +#undef USE_MAD +#undef USE_VORBIS +#undef USE_TREMOR + +#endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_lure.h b/backends/platform/PalmOS/Src/prefixes/native_lure.h index 1d9005045c..b017c46fe6 100644 --- a/backends/platform/PalmOS/Src/prefixes/native_lure.h +++ b/backends/platform/PalmOS/Src/prefixes/native_lure.h @@ -4,4 +4,8 @@ #include "native_common.h" #undef DISABLE_LURE +#undef USE_MAD +#undef USE_VORBIS +#undef USE_TREMOR + #endif diff --git a/backends/platform/PalmOS/Src/prefixes/native_parallaction.h b/backends/platform/PalmOS/Src/prefixes/native_parallaction.h new file mode 100755 index 0000000000..545cdd36fd --- /dev/null +++ b/backends/platform/PalmOS/Src/prefixes/native_parallaction.h @@ -0,0 +1,11 @@ +#ifndef PREFIX_H +#define PREFIX_H + +#include "native_common.h" +#undef DISABLE_PARALLACTION + +#undef USE_MAD +#undef USE_VORBIS +#undef USE_TREMOR + +#endif diff --git a/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h b/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h index 6c7d749539..8473214746 100644 --- a/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h +++ b/backends/platform/PalmOS/Src/prefixes/prefix_frontend.h @@ -3,6 +3,7 @@ #define PALMOS_68K #define PALMOS_MODE + //#define _DEBUG_ENGINE #endif diff --git a/backends/platform/PalmOS/Src/stuffs.h b/backends/platform/PalmOS/Src/stuffs.h index b6f5a3f38b..25bf17c8c6 100644 --- a/backends/platform/PalmOS/Src/stuffs.h +++ b/backends/platform/PalmOS/Src/stuffs.h @@ -19,6 +19,7 @@ enum { kOptSonyPa1LibAPI = 1 << 0x0D, kOptGoLcdAPI = 1 << 0x0E, kOptLightspeedAPI = 1 << 0x0F, + kOptModeRotatable = 1 << 0x10, kOptDeviceProcX86 = 1 << 0x1F // DEBUG only }; diff --git a/backends/platform/PalmOS/Src/zodiac_gfx.cpp b/backends/platform/PalmOS/Src/zodiac_gfx.cpp index d14f745657..c84a6af056 100644 --- a/backends/platform/PalmOS/Src/zodiac_gfx.cpp +++ b/backends/platform/PalmOS/Src/zodiac_gfx.cpp @@ -56,11 +56,9 @@ void OSystem_PalmZodiac::load_gfx_mode() { _ratio.adjustAspect = ConfMan.getBool("aspect_ratio") ? kRatioHeight : kRatioNone; // precalc ratio (WIDE mode) - _ratio.width = ((float)_screenWidth / _screenHeight * gVars->screenFullHeight); - _ratio.height = ((float)_screenHeight / _screenWidth * gVars->screenFullWidth); + _ratio.width = (gVars->screenFullHeight * _screenWidth / _screenHeight); + _ratio.height = (gVars->screenFullWidth * _screenHeight / _screenWidth); - _mouseBackupP = (byte *)MemPtrNew(MAX_MOUSE_W * MAX_MOUSE_H * 2); // *2 if 16bit - _mouseDataP = (byte *)MemPtrNew(MAX_MOUSE_W * MAX_MOUSE_H); _offScreenP = (byte *)MemPtrNew(_screenWidth * _screenHeight); MemSet(_offScreenP, _screenWidth * _screenHeight, 0); @@ -98,7 +96,7 @@ void OSystem_PalmZodiac::load_gfx_mode() { _srcBmp.rowBytes = _screenWidth; _srcBmp.pixelFormat = twGfxPixelFormat8bpp; _srcBmp.data = _offScreenP; - _srcBmp.palette = _nativePal; + _srcBmp.palette = (UInt16 *)_nativePal; _srcRect.x = 0; _srcRect.y = 0; @@ -192,8 +190,6 @@ void OSystem_PalmZodiac::unload_gfx_mode() { WinScreenMode(winScreenModeSet, NULL, NULL, &depth, NULL); clearScreen(); - MemPtrFree(_mouseBackupP); - MemPtrFree(_mouseDataP); MemPtrFree(_offScreenP); SysSetOrientation(_sysOldOrientation); @@ -217,7 +213,8 @@ void OSystem_PalmZodiac::updateScreen() { Err e; // draw the mouse pointer - draw_mouse(); + draw_mouse(); + // update the screen if (_overlayVisible) { if (_stretched) { @@ -247,6 +244,7 @@ void OSystem_PalmZodiac::updateScreen() { dst.y += _new_shake_pos; } e = TwGfxDrawBitmap(_tmpScreenP, &pos, &_srcBmp); + e = TwGfxWaitForVBlank(_gfxH); e = TwGfxStretchBlt2(_palmScreenP, &dst, _tmpScreenP, &_srcRect, twGfxStretchFast| (gVars->filter ? twGfxStretchSmooth : 0)); } else { @@ -264,13 +262,11 @@ void OSystem_PalmZodiac::updateScreen() { e = TwGfxDrawBitmap(_palmScreenP, &pos, &_srcBmp); } } + + // undraw the mouse undraw_mouse(); } -void OSystem_PalmZodiac::extras_palette(uint8 index, uint8 r, uint8 g, uint8 b) { - _nativePal[index] = TwGfxMakeDisplayRGB(r, g, b); -} - void OSystem_PalmZodiac::draw_osd(UInt16 id, Int32 x, Int32 y, Boolean show, UInt8 color) { if (_mode != GFX_NORMAL) return; diff --git a/backends/platform/PalmOS/Src/zodiac_mouse.cpp b/backends/platform/PalmOS/Src/zodiac_mouse.cpp index bd68be1ae7..52e2261e44 100644 --- a/backends/platform/PalmOS/Src/zodiac_mouse.cpp +++ b/backends/platform/PalmOS/Src/zodiac_mouse.cpp @@ -24,100 +24,90 @@ #include "be_zodiac.h" -void OSystem_PalmZodiac::setCursorPalette(const byte *colors, uint start, uint num) { - for(uint i = 0; i < num; i++) { - _mousePal[i + start] = TwGfxMakeDisplayRGB(colors[0], colors[1], colors[2]); - colors += 4; - } - _cursorPaletteDisabled = false; -} - void OSystem_PalmZodiac::draw_mouse() { - if (_mouseDrawn || !_mouseVisible) + if (!_mouseDataP || _mouseDrawn || !_mouseVisible) return; - - byte *src = _mouseDataP; // Image representing the mouse - byte color; - int width; - - _mouseCurState.y = _mouseCurState.y >= _screenHeight ? _screenHeight - 1 : _mouseCurState.y; + + byte *src = _mouseDataP; int x = _mouseCurState.x - _mouseHotspotX; int y = _mouseCurState.y - _mouseHotspotY; int w = _mouseCurState.w; int h = _mouseCurState.h; - int draw_x = x; - int draw_y = y; - // clip the mouse rect - if (x < 0) { - w += x; - src -= x; - x = 0; - } if (y < 0) { + src -= y * w; h += y; - src -= y * MAX_MOUSE_W; y = 0; } - if (w > _screenWidth - x) - w = _screenWidth - x; + if (x < 0) { + src -= x; + w += x; + x = 0; + } + if (h > _screenHeight - y) h = _screenHeight - y; + if (w > _screenWidth - x) + w = _screenWidth - x; - // Quick check to see if anything has to be drawn at all if (w <= 0 || h <= 0) return; - // Store the bounding box so that undraw mouse can restore the area the - // mouse currently covers to its original content. + // store the bounding box so that undraw mouse can restore the area the + // mouse currently covers to its original content _mouseOldState.x = x; _mouseOldState.y = y; _mouseOldState.w = w; _mouseOldState.h = h; - // Backup the covered area draw the mouse cursor + byte color; + int ww; + if (_overlayVisible) { - uint16 *bak = (uint16 *)_mouseBackupP; // Surface used to backup the area obscured by the mouse - uint16 *dst, *pal = _cursorPaletteDisabled ? _nativePal : _mousePal; + int16 *bak = (int16 *)_mouseBackupP; + int16 *pal = _cursorPaletteDisabled ? _nativePal : _mousePal; + int16 *dst; TwGfxLockSurface(_overlayP, (void **)&dst); dst += y * _screenWidth + x; do { - width = w; + ww = w; do { *bak++ = *dst; color = *src++; - if (color != _mouseKeyColor) // transparent, don't draw + + // transparent, don't draw + if (color != _mouseKeyColor) *dst = pal[color]; dst++; - } while (--width); + } while (--ww); - src += MAX_MOUSE_W - w; - bak += MAX_MOUSE_W - w; + src += _mouseCurState.w - w; dst += _screenWidth - w; } while (--h); TwGfxUnlockSurface(_overlayP, true); } else { - byte *bak = _mouseBackupP; // Surface used to backup the area obscured by the mouse - byte *dst =_offScreenP + y * _screenWidth + x; // Surface we are drawing into + byte *bak = _mouseBackupP; + byte *dst =_offScreenP + y * _screenWidth + x; do { - width = w; + ww = w; do { *bak++ = *dst; color = *src++; - if (color != _mouseKeyColor) // transparent, don't draw + + // transparent, don't draw + if (color != _mouseKeyColor) *dst = color; dst++; - } while (--width); + } while (--ww); - src += MAX_MOUSE_W - w; - bak += MAX_MOUSE_W - w; + src += _mouseCurState.w - w; dst += _screenWidth - w; } while (--h); } @@ -130,30 +120,31 @@ void OSystem_PalmZodiac::undraw_mouse() { return; int h = _mouseOldState.h; - // No need to do clipping here, since draw_mouse() did that already + + // no need to do clipping here, since draw_mouse() did that already if (_overlayVisible) { - uint16 *bak = (uint16 *)_mouseBackupP; uint16 *dst; + uint16 *bak = (uint16 *)_mouseBackupP; TwGfxLockSurface(_overlayP, (void **)&dst); dst += _mouseOldState.y * _screenWidth + _mouseOldState.x; do { - memcpy(dst, bak, _mouseOldState.w * 2); - bak += MAX_MOUSE_W; + MemMove(dst, bak, _mouseOldState.w * 2); dst += _screenWidth; + bak += _mouseOldState.w; } while (--h); TwGfxUnlockSurface(_overlayP, true); } else { - byte *dst, *bak = _mouseBackupP; - dst = _offScreenP + _mouseOldState.y * _screenWidth + _mouseOldState.x; - + byte *dst = _offScreenP + _mouseOldState.y * _screenWidth + _mouseOldState.x; + byte *bak = _mouseBackupP; + do { - memcpy(dst, bak, _mouseOldState.w); - bak += MAX_MOUSE_W; + MemMove(dst, bak, _mouseOldState.w); dst += _screenWidth; + bak += _mouseOldState.w; } while (--h); } diff --git a/backends/platform/PalmOS/Src/zodiac_overlay.cpp b/backends/platform/PalmOS/Src/zodiac_overlay.cpp index d1b2f7a558..09385c110a 100644 --- a/backends/platform/PalmOS/Src/zodiac_overlay.cpp +++ b/backends/platform/PalmOS/Src/zodiac_overlay.cpp @@ -34,7 +34,7 @@ void OSystem_PalmZodiac::clearOverlay() { TwGfxBitmapType bmp = { sizeof(TwGfxBitmapType), _screenWidth, _screenHeight, _screenWidth, twGfxPixelFormat8bpp, - (void *)_offScreenP, _nativePal + (void *)_offScreenP, (UInt16 *)_nativePal }; e = TwGfxDrawBitmap(_overlayP, &pos, &bmp); } diff --git a/backends/platform/PalmOS/scummvm.mcp b/backends/platform/PalmOS/scummvm.mcp Binary files differindex 286eec33bb..5dca766c86 100644 --- a/backends/platform/PalmOS/scummvm.mcp +++ b/backends/platform/PalmOS/scummvm.mcp diff --git a/backends/platform/dc/portdefs.h b/backends/platform/dc/portdefs.h index cedfd5c0fe..08bc900e6e 100644 --- a/backends/platform/dc/portdefs.h +++ b/backends/platform/dc/portdefs.h @@ -37,3 +37,6 @@ #ifdef Timer #undef Timer #endif +/* newlib ctype.h defines _X for hex digit flag. + This conflicts with the use of _X as a variable name. */ +#undef _X diff --git a/backends/platform/ds/arm9/source/blitters.cpp b/backends/platform/ds/arm9/source/blitters.cpp index 7d1e0e4402..ec33a5aab4 100644 --- a/backends/platform/ds/arm9/source/blitters.cpp +++ b/backends/platform/ds/arm9/source/blitters.cpp @@ -19,8 +19,11 @@ */ #include "stdafx.h" +#include "blitters.h" #define CHARSET_MASK_TRANSPARENCY 253 +//#define PERFECT_5_TO_4_RESCALING + namespace DS { void asmDrawStripToScreen(int height, int width, byte const* text, byte const* src, byte* dst, @@ -149,6 +152,7 @@ void ComputeDivBy5TableIFN() } } +#ifdef PERFECT_5_TO_4_RESCALING static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4, u16* dest) { @@ -223,6 +227,44 @@ static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3 ((u32*)dest)[0] = d10; ((u32*)dest)[1] = d32; } +#else +static inline void RescaleBlock_5x1555_To_4x1555( u16 s0, u16 s1, u16 s2, u16 s3, u16 s4, + u16* dest) +{ + u32 ar0bs0 = s0 & 0x7C1F; + u32 ar0bs1 = s1 & 0x7C1F; + u32 ar0bs2 = s2 & 0x7C1F; + u32 ar0bs3 = s3 & 0x7C1F; + u32 ar0bs4 = s4 & 0x7C1F; + + u32 gs0 = s0 & 0x03E0; + u32 gs1 = s1 & 0x03E0; + u32 gs2 = s2 & 0x03E0; + u32 gs3 = s3 & 0x03E0; + u32 gs4 = s4 & 0x03E0; + + u32 ar0bd0 = (3*ar0bs0 + ar0bs1) >> 2; + u32 ar0bd1 = ( ar0bs1 + ar0bs2) >> 1; + u32 ar0bd2 = ( ar0bs2 + ar0bs3) >> 1; + u32 ar0bd3 = ( ar0bs3 + 3*ar0bs4) >> 2; + + u32 gd0 = (3*gs0 + gs1) >> 2; + u32 gd1 = ( gs1 + gs2) >> 1; + u32 gd2 = ( gs2 + gs3) >> 1; + u32 gd3 = ( gs3 + 3*gs4) >> 2; + + u32 d0 = (ar0bd0 & 0xFC1F) | (gd0 & 0x03E0); + u32 d1 = (ar0bd1 & 0xFC1F) | (gd1 & 0x03E0); + u32 d2 = (ar0bd2 & 0xFC1F) | (gd2 & 0x03E0); + u32 d3 = (ar0bd3 & 0xFC1F) | (gd3 & 0x03E0); + + u32 d10 = 0x80008000 | (d1 << 16) | d0; + u32 d32 = 0x80008000 | (d3 << 16) | d2; + + ((u32*)dest)[0] = d10; + ((u32*)dest)[1] = d32; +} +#endif static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3, u32 s4, u16* dest) @@ -262,6 +304,7 @@ static inline void RescaleBlock_5x8888_To_4x1555( u32 s0, u32 s1, u32 s2, u32 s3 } // Can't work in place +#ifdef PERFECT_5_TO_4_RESCALING static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const u8* src, const u32* palette) { ComputeDivBy5TableIFN(); @@ -277,6 +320,21 @@ static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const RescaleBlock_5x8888_To_4x1555(s0, s1, s2, s3, s4, dest+4*i); } } +#else +static inline void Rescale_320xPAL8Scanline_To_256x1555Scanline(u16* dest, const u8* src, const u16* palette) +{ + for(size_t i=0; i<64; ++i) + { + u16 s0 = palette[src[5*i+0]]; + u16 s1 = palette[src[5*i+1]]; + u16 s2 = palette[src[5*i+2]]; + u16 s3 = palette[src[5*i+3]]; + u16 s4 = palette[src[5*i+4]]; + + RescaleBlock_5x1555_To_4x1555(s0, s1, s2, s3, s4, dest+4*i); + } +} +#endif // Can work in place, because it's a contraction @@ -296,6 +354,7 @@ static inline void Rescale_320x1555Scanline_To_256x1555Scanline(u16* dest, const } } +#ifdef PERFECT_5_TO_4_RESCALING void Rescale_320x256xPAL8_To_256x256x1555(u16* dest, const u8* src, const u16* palette, int destStride, int srcStride) { u32 fastRam[768]; @@ -316,6 +375,19 @@ void Rescale_320x256xPAL8_To_256x256x1555(u16* dest, const u8* src, const u16* p Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam); } } +#else +void Rescale_320x256xPAL8_To_256x256x1555(u16* dest, const u8* src, const u16* palette, int destStride, int srcStride) +{ + u16 fastRam[256]; + for(size_t i=0; i<128; ++i) + ((u32*)fastRam)[i] = ((const u32*)palette)[i]; + + for(size_t i=0; i<200; ++i) + { + Rescale_320xPAL8Scanline_To_256x1555Scanline(dest + i*destStride, src + i *srcStride, fastRam); + } +} +#endif void Rescale_320x256x1555_To_256x256x1555(u16* dest, const u16* src, int destStride, int srcStride) { diff --git a/backends/platform/ds/arm9/source/fat/disc_io.c b/backends/platform/ds/arm9/source/fat/disc_io.c index 3cb70f510b..c706cf8b3e 100644 --- a/backends/platform/ds/arm9/source/fat/disc_io.c +++ b/backends/platform/ds/arm9/source/fat/disc_io.c @@ -358,7 +358,7 @@ void disc_getDldiId(char* id) { bool disc_setDsSlotInterface (void) { #ifdef ARM9 - REG_EXEMEMCNT &= ~(1<<11); + REG_EXMEMCNT &= ~(1<<11); #endif #ifdef ARM7 REG_EXEMEMCNT |= (1<<11); diff --git a/backends/platform/ds/arm9/source/fat/io_dldi.h b/backends/platform/ds/arm9/source/fat/io_dldi.h index 053de3a94c..86c3407374 100644 --- a/backends/platform/ds/arm9/source/fat/io_dldi.h +++ b/backends/platform/ds/arm9/source/fat/io_dldi.h @@ -30,7 +30,7 @@ extern u8 _dldi_driver_name; static inline LPIO_INTERFACE DLDI_GetInterface(void) { #ifdef NDS // NDM: I'm really not sure about this change ARM9 - ARM7 - REG_EXEMEMCNT &= ~(ARM7_OWNS_ROM | ARM7_OWNS_CARD); + REG_EXMEMCNT &= ~(ARM7_OWNS_ROM | ARM7_OWNS_CARD); #endif // defined NDS return &_io_dldi; } diff --git a/backends/platform/gp2x/build/scummvm.gpe b/backends/platform/gp2x/build/scummvm.gpe new file mode 100644 index 0000000000..1e69c149b9 --- /dev/null +++ b/backends/platform/gp2x/build/scummvm.gpe @@ -0,0 +1,14 @@ +#!/bin/bash + +# Remount SD with forced Sync, does this really work? +mount -o sync,remount /dev/mmcsd/disc0/part1 /mnt/sd/ + +# Run ScummVM, important this bit. +./scummvm.gp2x + +# Sync the SD card to check that everything is written. +sync + +# Return to the GPH menu screen +cd /usr/gp2x +exec /usr/gp2x/gp2xmenu diff --git a/backends/platform/gp32/startup.c b/backends/platform/gp32/startup.c index b12cf3f077..6f74241e09 100644 --- a/backends/platform/gp32/startup.c +++ b/backends/platform/gp32/startup.c @@ -87,7 +87,7 @@ int main (int arg_len, char * arg_v) GpKernelStart (); GpAppExit (); - while (1) {}; + while (1) {} } void InitializeFont (void) diff --git a/backends/platform/maemo/maemo-sdl.h b/backends/platform/maemo/maemo-sdl.h index e342ead5f9..e497c2597d 100644 --- a/backends/platform/maemo/maemo-sdl.h +++ b/backends/platform/maemo/maemo-sdl.h @@ -33,7 +33,7 @@ class OSystem_MAEMO : public OSystem_SDL { public: - OSystem_MAEMO() {}; + OSystem_MAEMO() {} void loadGFXMode(); }; diff --git a/backends/platform/null/null.cpp b/backends/platform/null/null.cpp index c13e8e56ff..cfccdb0531 100644 --- a/backends/platform/null/null.cpp +++ b/backends/platform/null/null.cpp @@ -21,8 +21,8 @@ */ #include "common/stdafx.h" -#include "common/scummsys.h" #include "common/system.h" +#include "base/main.h" #if defined(USE_NULL_DRIVER) @@ -51,13 +51,16 @@ public: virtual const GraphicsMode *getSupportedGraphicsModes() const; virtual int getDefaultGraphicsMode() const; bool setGraphicsMode(const char *name); + virtual bool setGraphicsMode(int mode); virtual int getGraphicsMode() const; virtual void initSize(uint width, uint height); virtual int16 getHeight(); virtual int16 getWidth(); virtual void setPalette(const byte *colors, uint start, uint num); + virtual void grabPalette(byte *colors, uint start, uint num); virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h); virtual void updateScreen(); + virtual bool grabRawScreen(Graphics::Surface *surf); virtual void setShakePos(int shakeOffset); virtual void showOverlay(); @@ -74,7 +77,7 @@ public: virtual bool showMouse(bool visible); virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1); virtual bool pollEvent(Common::Event &event); virtual uint32 getMillis(); @@ -85,15 +88,11 @@ public: virtual void unlockMutex(MutexRef mutex); virtual void deleteMutex(MutexRef mutex); + typedef void (*SoundProc)(void *param, byte *buf, int len); + virtual bool setSoundCallback(SoundProc proc, void *param); + virtual void clearSoundCallback(); virtual int getOutputSampleRate() const; - virtual bool openCD(int drive); - virtual bool pollCD(); - - virtual void playCD(int track, int num_loops, int start_frame, int duration); - virtual void stopCD(); - virtual void updateCD(); - virtual void quit(); virtual void setWindowCaption(const char *caption); @@ -107,16 +106,6 @@ static const OSystem::GraphicsMode s_supportedGraphicsModes[] = { {0, 0, 0} }; -int main(int argc, char *argv[]) { - g_system = OSystem_NULL_create(); - assert(g_system); - - // Invoke the actual ScummVM main entry point: - int res = scummvm_main(argc, argv); - g_system->quit(); // TODO: Consider removing / replacing this! - return res; -} - OSystem_NULL::OSystem_NULL() { _savefile = 0; _mixer = 0; @@ -161,6 +150,10 @@ int OSystem_NULL::getDefaultGraphicsMode() const { return -1; } +bool OSystem_NULL::setGraphicsMode(const char *mode) { + return true; +} + bool OSystem_NULL::setGraphicsMode(int mode) { return true; } @@ -183,28 +176,36 @@ int16 OSystem_NULL::getWidth() { void OSystem_NULL::setPalette(const byte *colors, uint start, uint num) { } +void OSystem_NULL::grabPalette(byte *colors, uint start, uint num) { + +} + void OSystem_NULL::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) { } void OSystem_NULL::updateScreen() { } +bool OSystem_NULL::grabRawScreen(Graphics::Surface *surf) { + return false; +} + void OSystem_NULL::setShakePos(int shakeOffset) { } -void OSystem_NULL::showOverlay () { +void OSystem_NULL::showOverlay() { } -void OSystem_NULL::hideOverlay () { +void OSystem_NULL::hideOverlay() { } -void OSystem_NULL::clearOverlay () { +void OSystem_NULL::clearOverlay() { } -void OSystem_NULL::grabOverlay (OverlayColor *buf, int pitch) { +void OSystem_NULL::grabOverlay(OverlayColor *buf, int pitch) { } -void OSystem_NULL::copyRectToOverlay (const OverlayColor *buf, int pitch, int x, int y, int w, int h) { +void OSystem_NULL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { } int16 OSystem_NULL::getOverlayHeight() { @@ -229,7 +230,7 @@ bool OSystem_NULL::showMouse(bool visible) { void OSystem_NULL::warpMouse(int x, int y) { } -void OSystem_NULL::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor) { +void OSystem_NULL::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor, int cursorTargetScale) { } bool OSystem_NULL::pollEvent(Common::Event &event) { @@ -273,17 +274,17 @@ void OSystem_NULL::quit() { void OSystem_NULL::setWindowCaption(const char *caption) { } -Common::SaveFileManager *DefaulOSystem::getSavefileManager() { +Common::SaveFileManager *OSystem_NULL::getSavefileManager() { assert(_savefile); return _savefile; } -Audio::Mixer *DefaulOSystem::getMixer() { +Audio::Mixer *OSystem_NULL::getMixer() { assert(_mixer); return _mixer; } -Common::TimerManager *DefaulOSystem::getTimerManager() { +Common::TimerManager *OSystem_NULL::getTimerManager() { assert(_timer); return _timer; } @@ -291,6 +292,17 @@ Common::TimerManager *DefaulOSystem::getTimerManager() { OSystem *OSystem_NULL_create() { return new OSystem_NULL(); } + +int main(int argc, char *argv[]) { + g_system = OSystem_NULL_create(); + assert(g_system); + + // Invoke the actual ScummVM main entry point: + int res = scummvm_main(argc, argv); + g_system->quit(); // TODO: Consider removing / replacing this! + return res; +} + #else /* USE_NULL_DRIVER */ OSystem *OSystem_NULL_create() { diff --git a/backends/platform/ps2/savefile.cpp b/backends/platform/ps2/savefile.cpp index 71073bd23f..9c7d446d83 100644 --- a/backends/platform/ps2/savefile.cpp +++ b/backends/platform/ps2/savefile.cpp @@ -205,9 +205,9 @@ public: AutoSaveFile(Ps2SaveFileManager *saveMan, const char *filename); ~AutoSaveFile(void); virtual uint32 write(const void *ptr, uint32 size); - virtual void flush(void) { }; + virtual void flush(void) {} virtual bool ioFailed(void) { return false; }; - virtual void clearIOFailed(void) {}; + virtual void clearIOFailed(void) {} private: Ps2SaveFileManager *_saveMan; char _fileName[256]; diff --git a/backends/platform/psp/osys_psp.cpp b/backends/platform/psp/osys_psp.cpp index 8d01d0cf6e..772fc0807a 100644 --- a/backends/platform/psp/osys_psp.cpp +++ b/backends/platform/psp/osys_psp.cpp @@ -63,7 +63,7 @@ static int timer_handler(int t) { const OSystem::GraphicsMode OSystem_PSP::s_supportedGraphicsModes[] = { { "320x200 (centered)", "320x200 16-bit centered", CENTERED_320X200 }, - { "353x272 (best-fit, centered)", "353x272 16-bit centered", CENTERED_435X272 }, + { "435x272 (best-fit, centered)", "435x272 16-bit centered", CENTERED_435X272 }, { "480x272 (full screen)", "480x272 16-bit stretched", STRETCHED_480X272 }, { "362x272 (4:3, centered)", "362x272 16-bit centered", CENTERED_362X272 }, {0, 0, 0} diff --git a/backends/platform/psp/osys_psp_gu.cpp b/backends/platform/psp/osys_psp_gu.cpp index 0a8cd71dda..8baa4e021b 100644 --- a/backends/platform/psp/osys_psp_gu.cpp +++ b/backends/platform/psp/osys_psp_gu.cpp @@ -115,6 +115,8 @@ OSystem_PSP_GU::OSystem_PSP_GU() { _graphicMode = STRETCHED_480X272; _keySelected = 1; _keyboardMode = 0; + _mouseX = PSP_SCREEN_WIDTH >> 1; + _mouseY = PSP_SCREEN_HEIGHT >> 1; } OSystem_PSP_GU::~OSystem_PSP_GU() { @@ -267,8 +269,6 @@ void OSystem_PSP_GU::copyRectToScreen(const byte *buf, int pitch, int x, int y, } void OSystem_PSP_GU::updateScreen() { - float scale; - sceGuStart(0,list); sceGuClearColor(0xff000000); @@ -381,9 +381,14 @@ void OSystem_PSP_GU::updateScreen() { break; case CENTERED_435X272: { - scale = 435.0f / _screenWidth; - vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scale; vertices[0].y = mY * scale; vertices[0].z = 0; - vertices[1].x = vertices[0].x + _mouseWidth * scale; vertices[1].y = vertices[0].y + _mouseHeight * scale; vertices[0].z = 0; + float scalex, scaley; + + scalex = 435.0f / _screenWidth; + scaley = 272.0f / _screenHeight; + + vertices[0].x = (PSP_SCREEN_WIDTH - 435) / 2 + mX * scalex; vertices[0].y = mY * scaley; vertices[0].z = 0; + vertices[1].x = vertices[0].x + _mouseWidth * scalex; vertices[1].y = vertices[0].y + _mouseHeight * scaley; vertices[0].z = 0; + } break; case CENTERED_362X272: diff --git a/backends/platform/sdl/sdl-common.h b/backends/platform/sdl/sdl-common.h index 58ebb72bd1..7703a1a511 100644 --- a/backends/platform/sdl/sdl-common.h +++ b/backends/platform/sdl/sdl-common.h @@ -117,7 +117,7 @@ public: void disableCursorPalette(bool disable) { _cursorPaletteDisabled = disable; blitCursor(); - }; + } // Shaking is used in SCUMM. Set current shake position. void setShakePos(int shake_pos); diff --git a/backends/platform/symbian/AdaptAllMMPs.pl b/backends/platform/symbian/AdaptAllMMPs.pl index 1b8e8d126c..a692017d05 100644 --- a/backends/platform/symbian/AdaptAllMMPs.pl +++ b/backends/platform/symbian/AdaptAllMMPs.pl @@ -20,6 +20,7 @@ chdir("../../../"); "mmp/scummvm_agi.mmp", "mmp/scummvm_touche.mmp", "mmp/scummvm_parallaction.mmp", + "mmp/scummvm_cruise.mmp", "S60/ScummVM_S60.mmp", "S60v3/ScummVM_S60v3.mmp", "S80/ScummVM_S80.mmp", @@ -63,14 +64,16 @@ my @excludes_snd = ( "tables.cpp", "freeverb.cpp" ); -my @excludes_gui = ( + +my @excludes_graphics = ( +"iff.cpp" ); #arseModule(mmpStr, dirStr, ifdefArray, [exclusionsArray]) ParseModule("_base", "base", \@section_empty); # now in ./TRG/ScummVM_TRG.mmp, these never change anyways... ParseModule("_base", "common", \@section_empty); -ParseModule("_base", "gui", \@section_empty, \@excludes_gui); -ParseModule("_base", "graphics", \@section_empty); +ParseModule("_base", "gui", \@section_empty); +ParseModule("_base", "graphics", \@section_empty, \@excludes_graphics); ParseModule("_base", "sound", \@section_empty, \@excludes_snd); chdir("engines/"); @@ -80,7 +83,6 @@ ParseModule("_agos", "agos", \@section_empty); ParseModule("_sky", "sky", \@section_empty); ParseModule("_gob", "gob", \@section_empty); ParseModule("_saga", "saga", \@section_empty); - ParseModule("_kyra", "kyra", \@section_empty); ParseModule("_sword1", "sword1", \@section_empty); ParseModule("_sword2", "sword2", \@section_empty); @@ -89,6 +91,7 @@ ParseModule("_cine", "cine", \@section_empty); ParseModule("_agi", "agi", \@section_empty); ParseModule("_touche", "touche", \@section_empty); ParseModule("_parallaction","parallaction",\@section_empty); +ParseModule("_cruise", "cruise", \@section_empty); print " ======================================================================================= Done. Enjoy :P diff --git a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl index a276b80223..bd2a3cf0dc 100644 --- a/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl +++ b/backends/platform/symbian/BuildPackageUpload_LocalSettings.pl @@ -5,12 +5,13 @@ $DefaultTopMacros = " MACRO USE_ZLIB // LIB:zlib.lib MACRO USE_MAD // LIB:libmad.lib - //MACRO USE_TREMOR // LIB:libtremor.lib + MACRO USE_TREMOR // LIB:libtremor.lib "; $DefaultBottomMacros = " MACRO DISABLE_SWORD1 // LIB:scummvm_sword1.lib MACRO DISABLE_SWORD2 // LIB:scummvm_sword2.lib + MACRO DISABLE_PARALLACTION // LIB:scummvm_parallaction.lib "; ## @@ -125,7 +126,7 @@ if (1) # all regular combo's //MACRO DISABLE_TOUCHE // LIB:scummvm_touche.lib //MACRO DISABLE_CINE // LIB:scummvm_cine.lib //MACRO DISABLE_LURE // LIB:scummvm_lure.lib - + //MACRO DISABLE_CRUISE // LIB:scummvm_cruise.lib $DefaultBottomMacros"; # now one for each ready-for-release engine diff --git a/backends/platform/symbian/S60/ScummVM_S60.mmp.in b/backends/platform/symbian/S60/ScummVM_S60.mmp.in index d65aa88423..cf91b4b14e 100644 --- a/backends/platform/symbian/S60/ScummVM_S60.mmp.in +++ b/backends/platform/symbian/S60/ScummVM_S60.mmp.in @@ -94,6 +94,9 @@ SOURCE gui\Key.cpp SOURCE gui\KeysDialog.cpp SOURCE gui\Actions.cpp +// Special for graphics +source graphics\iff.cpp + // *** Dynamic Libraries LIBRARY cone.lib eikcore.lib diff --git a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in index c680db130f..eebd4764f5 100644 --- a/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in +++ b/backends/platform/symbian/S60v3/ScummVM_S60v3.mmp.in @@ -114,6 +114,9 @@ SOURCE gui\Key.cpp SOURCE gui\KeysDialog.cpp SOURCE gui\Actions.cpp +// Special for graphics +source graphics\iff.cpp + // *** Dynamic Libraries LIBRARY cone.lib eikcore.lib LIBRARY euser.lib apparc.lib fbscli.lib diff --git a/backends/platform/symbian/S80/ScummVM_S80.mmp.in b/backends/platform/symbian/S80/ScummVM_S80.mmp.in index 8825662575..4bcb64060b 100644 --- a/backends/platform/symbian/S80/ScummVM_S80.mmp.in +++ b/backends/platform/symbian/S80/ScummVM_S80.mmp.in @@ -92,6 +92,9 @@ SOURCE gui\Key.cpp SOURCE gui\KeysDialog.cpp SOURCE gui\Actions.cpp +// Special for graphics +source graphics\iff.cpp + // *** Dynamic Libraries LIBRARY cone.lib eikcore.lib diff --git a/backends/platform/symbian/S90/Scummvm_S90.mmp.in b/backends/platform/symbian/S90/Scummvm_S90.mmp.in index fecbfe4b82..e55acc63b1 100644 --- a/backends/platform/symbian/S90/Scummvm_S90.mmp.in +++ b/backends/platform/symbian/S90/Scummvm_S90.mmp.in @@ -92,6 +92,9 @@ SOURCE gui\Key.cpp SOURCE gui\KeysDialog.cpp SOURCE gui\Actions.cpp +// Special for graphics +source graphics\iff.cpp + // *** Dynamic Libraries LIBRARY cone.lib eikcore.lib diff --git a/backends/platform/symbian/UIQ2/ScummVM_UIQ2.mmp.in b/backends/platform/symbian/UIQ2/ScummVM_UIQ2.mmp.in index 62c3eb3aa2..c3ebae01d7 100644 --- a/backends/platform/symbian/UIQ2/ScummVM_UIQ2.mmp.in +++ b/backends/platform/symbian/UIQ2/ScummVM_UIQ2.mmp.in @@ -91,6 +91,9 @@ SOURCE gui\Key.cpp SOURCE gui\KeysDialog.cpp SOURCE gui\Actions.cpp +// Special for graphics +source graphics\iff.cpp + // *** Dynamic Libraries LIBRARY cone.lib eikcore.lib diff --git a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in index 7fe7798080..8620237b3a 100644 --- a/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in +++ b/backends/platform/symbian/UIQ3/ScummVM_UIQ3.mmp.in @@ -115,6 +115,9 @@ SOURCE gui\Key.cpp SOURCE gui\KeysDialog.cpp SOURCE gui\Actions.cpp +// Special for graphics +source graphics\iff.cpp + // *** Dynamic Libraries LIBRARY cone.lib eikcore.lib diff --git a/backends/platform/symbian/mmp/scummvm_base.mmp.in b/backends/platform/symbian/mmp/scummvm_base.mmp.in index fb62b4943e..a1f3f1b261 100644 --- a/backends/platform/symbian/mmp/scummvm_base.mmp.in +++ b/backends/platform/symbian/mmp/scummvm_base.mmp.in @@ -56,6 +56,8 @@ OPTION GCC -Wno-multichar -Wno-reorder // don't optimize for ARM, platform way //MACRO DISABLE_CINE // LIB:scummvm_cine.lib //MACRO DISABLE_AGI // LIB:scummvm_agi.lib //MACRO DISABLE_PARALLACTION // LIB:scummvm_parallaction.lib + //MACRO DISABLE_CRUISE // LIB:scummvm_cruise.lib + //STOP_AUTO_MACROS_MASTER// diff --git a/backends/platform/symbian/mmp/scummvm_cruise.mmp.in b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in new file mode 100644 index 0000000000..05092777b0 --- /dev/null +++ b/backends/platform/symbian/mmp/scummvm_cruise.mmp.in @@ -0,0 +1,54 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2003-2005 Andreas 'Sprawl' Karlsson - Original EPOC port, ESDL + * Copyright (C) 2003-2005 Lars 'AnotherGuest' Persson - Original EPOC port, Audio System + * Copyright (C) 2005 Jurgen 'SumthinWicked' Braam - EPOC/CVS maintainer + * Copyright (C) 2005-2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// +// EPOC MMP makefile project for ScummVM +// + +// *** Definitions + +TARGET scummvm_cruise.lib +TARGETTYPE lib +OPTION MSVC /QIfist /Ob1 /Oy /GF // /QIfist disables use of __ftol2 to avoid linker probs with MS libc: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore/html/vcrefQIfistSuppress_ftol.asp +OPTION GCC -Wno-multichar -Wno-reorder // don't optimize for ARM, platform way too sensitive for that :( just turn off some common warnings + +//START_AUTO_MACROS_SLAVE// + + // empty base file, will be updated by Perl build scripts + +//STOP_AUTO_MACROS_SLAVE// + +// *** SOURCE files + +SOURCEPATH ..\..\..\..\engines\cruise + +//START_AUTO_OBJECTS_CRUISE_// + + // empty base file, will be updated by Perl build scripts + +//STOP_AUTO_OBJECTS_CRUISE_// + +// *** Include paths + +USERINCLUDE ..\..\..\..\engines +USERINCLUDE ..\..\..\.. ..\..\..\..\common ..\..\..\..\gui ..\..\..\..\sound ..\src +SYSTEMINCLUDE \epoc32\include \epoc32\include\libc ..\src diff --git a/backends/platform/wince/CEActionsPocket.cpp b/backends/platform/wince/CEActionsPocket.cpp index 73d8dfe334..6cddf62695 100644 --- a/backends/platform/wince/CEActionsPocket.cpp +++ b/backends/platform/wince/CEActionsPocket.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -24,13 +24,9 @@ #include "common/stdafx.h" #include "CEActionsPocket.h" #include "EventsBuffer.h" - #include "gui/message.h" - #include "scumm/scumm.h" - #include "common/config-manager.h" - #include "gui/KeysDialog.h" #ifdef _WIN32_WCE @@ -42,20 +38,20 @@ const String pocketActionNames[] = { "Save", "Quit", "Skip", - "Hide", - "Keyboard", - "Sound", + "Hide Toolbar", + "Show Keyboard", + "Sound on/off", "Right click", - "Cursor", + "Show/Hide Cursor", "Free look", "Zoom up", "Zoom down", "FT Cheat", "Bind Keys", - "Up", - "Down", - "Left", - "Right", + "Cursor Up", + "Cursor Down", + "Cursor Left", + "Cursor Right", "Left Click", }; @@ -100,11 +96,11 @@ GUI::Actions() _action_enabled[POCKET_ACTION_DOWN] = true; _action_enabled[POCKET_ACTION_LEFT] = true; _action_enabled[POCKET_ACTION_RIGHT] = true; - _action_mapping[POCKET_ACTION_LEFTCLICK] = VK_RETURN; - _action_mapping[POCKET_ACTION_UP] = 0x111; - _action_mapping[POCKET_ACTION_DOWN] = 0x112; - _action_mapping[POCKET_ACTION_LEFT] = 0x114; - _action_mapping[POCKET_ACTION_RIGHT] = 0x113; + _action_mapping[POCKET_ACTION_LEFTCLICK] = SDLK_RETURN; + _action_mapping[POCKET_ACTION_UP] = SDLK_UP; + _action_mapping[POCKET_ACTION_DOWN] = SDLK_DOWN; + _action_mapping[POCKET_ACTION_LEFT] = SDLK_LEFT; + _action_mapping[POCKET_ACTION_RIGHT] = SDLK_RIGHT; } void CEActionsPocket::initInstanceMain(OSystem *mainSystem) { @@ -184,7 +180,7 @@ void CEActionsPocket::initInstanceGame() { // Freelook _action_enabled[POCKET_ACTION_FREELOOK] = true; // Zoom - if (is_sword1 || is_sword2 || is_comi) { + if (is_sword1 || is_sword2 || is_comi || is_touche) { _zoom_needed = true; _action_enabled[POCKET_ACTION_ZOOM_UP] = true; _action_enabled[POCKET_ACTION_ZOOM_DOWN] = true; @@ -244,9 +240,9 @@ bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) { case POCKET_ACTION_CURSOR: _CESystem->swap_mouse_visibility(); return true; - case POCKET_ACTION_FREELOOK: - _CESystem->swap_freeLook(); - return true; + case POCKET_ACTION_FREELOOK: + _CESystem->swap_freeLook(); + return true; case POCKET_ACTION_ZOOM_UP: _CESystem->swap_zoom_up(); return true; @@ -270,7 +266,7 @@ bool CEActionsPocket::perform(GUI::ActionType action, bool pushed) { return true; case POCKET_ACTION_QUIT: { - GUI::MessageDialog alert("Do you want to quit ?", "Yes", "No"); + GUI::MessageDialog alert(" Are you sure you want to quit ? ", "Yes", "No"); if (alert.runModal() == GUI::kMessageOK) _mainSystem->quit(); return true; @@ -309,4 +305,3 @@ bool CEActionsPocket::needsZoomMapping() { else return (_action_mapping[POCKET_ACTION_ZOOM_UP] == 0 || _action_mapping[POCKET_ACTION_ZOOM_DOWN] == 0); } - diff --git a/backends/platform/wince/CEActionsPocket.h b/backends/platform/wince/CEActionsPocket.h index f3d8f482cb..d20829f3f6 100644 --- a/backends/platform/wince/CEActionsPocket.h +++ b/backends/platform/wince/CEActionsPocket.h @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,37 +26,34 @@ #include "common/stdafx.h" #include "common/scummsys.h" #include "common/system.h" - - #include "wince-sdl.h" #include "gui/Key.h" - #include "gui/Actions.h" -#define POCKET_ACTION_VERSION 4 +#define POCKET_ACTION_VERSION 5 enum pocketActionType { - POCKET_ACTION_PAUSE = 0, - POCKET_ACTION_SAVE, - POCKET_ACTION_QUIT, - POCKET_ACTION_SKIP, - POCKET_ACTION_HIDE, - POCKET_ACTION_KEYBOARD, - POCKET_ACTION_SOUND, - POCKET_ACTION_RIGHTCLICK, - POCKET_ACTION_CURSOR, - POCKET_ACTION_FREELOOK, - POCKET_ACTION_ZOOM_UP, - POCKET_ACTION_ZOOM_DOWN, - POCKET_ACTION_FT_CHEAT, - POCKET_ACTION_BINDKEYS, - POCKET_ACTION_UP, - POCKET_ACTION_DOWN, - POCKET_ACTION_LEFT, - POCKET_ACTION_RIGHT, - POCKET_ACTION_LEFTCLICK, - - POCKET_ACTION_LAST + POCKET_ACTION_PAUSE = 0, + POCKET_ACTION_SAVE, + POCKET_ACTION_QUIT, + POCKET_ACTION_SKIP, + POCKET_ACTION_HIDE, + POCKET_ACTION_KEYBOARD, + POCKET_ACTION_SOUND, + POCKET_ACTION_RIGHTCLICK, + POCKET_ACTION_CURSOR, + POCKET_ACTION_FREELOOK, + POCKET_ACTION_ZOOM_UP, + POCKET_ACTION_ZOOM_DOWN, + POCKET_ACTION_FT_CHEAT, + POCKET_ACTION_BINDKEYS, + POCKET_ACTION_UP, + POCKET_ACTION_DOWN, + POCKET_ACTION_LEFT, + POCKET_ACTION_RIGHT, + POCKET_ACTION_LEFTCLICK, + + POCKET_ACTION_LAST }; class CEActionsPocket : public GUI::Actions { diff --git a/backends/platform/wince/CEActionsSmartphone.cpp b/backends/platform/wince/CEActionsSmartphone.cpp index 8d9b18b46c..1d53b01dc4 100644 --- a/backends/platform/wince/CEActionsSmartphone.cpp +++ b/backends/platform/wince/CEActionsSmartphone.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,25 +20,15 @@ * */ -//#define SIMU_SMARTPHONE 1 - -//#ifdef WIN32_PLATFORM_WFSP - #include "common/stdafx.h" #include "CEActionsSmartphone.h" #include "EventsBuffer.h" - #include "gui/message.h" - #include "scumm/scumm.h" - #include "common/config-manager.h" - #include "gui/KeysDialog.h" -#ifdef _WIN32_WCE #define KEY_ALL_SKIP 3457 -#endif const String smartphoneActionNames[] = { "Up", @@ -53,14 +43,11 @@ const String smartphoneActionNames[] = { "FT Cheat", "Bind Keys", "Keyboard", - "Rotate" + "Rotate", + "Quit" }; -#ifdef SIMU_SMARTPHONE -const int ACTIONS_SMARTPHONE_DEFAULT[] = { 0x111, 0x112, 0x114, 0x113, 0x11a, 0x11b, VK_LWIN, VK_ESCAPE, VK_F8, 0, VK_RETURN, 0, 0 }; -#else -const int ACTIONS_SMARTPHONE_DEFAULT[] = { '4', '6', '8', '2', 0x11a, 0x11b, '0', VK_ESCAPE, '9', 0, VK_RETURN, 0, 0 }; -#endif +const int ACTIONS_SMARTPHONE_DEFAULT[] = { SDLK_UP, SDLK_DOWN, SDLK_LEFT, SDLK_RIGHT, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_ESCAPE, SDLK_9, SDLK_8, SDLK_F4, SDLK_RETURN, SDLK_5, SDLK_0 }; void CEActionsSmartphone::init() { _instance = new CEActionsSmartphone(); @@ -98,22 +85,18 @@ void CEActionsSmartphone::initInstanceMain(OSystem *mainSystem) { _CESystem = static_cast<OSystem_WINCE3*>(mainSystem); GUI_Actions::initInstanceMain(mainSystem); - // Mouse Up + + // These actions are always on _action_enabled[SMARTPHONE_ACTION_UP] = true; - // Mouse Down _action_enabled[SMARTPHONE_ACTION_DOWN] = true; - // Mouse Left _action_enabled[SMARTPHONE_ACTION_LEFT] = true; - // Mouse Right _action_enabled[SMARTPHONE_ACTION_RIGHT] = true; - // Left Click _action_enabled[SMARTPHONE_ACTION_LEFTCLICK] = true; - // Right Click _action_enabled[SMARTPHONE_ACTION_RIGHTCLICK] = true; - // Show virtual keyboard _action_enabled[SMARTPHONE_ACTION_KEYBOARD] = true; - // Rotate display _action_enabled[SMARTPHONE_ACTION_ROTATE] = true; + _action_enabled[SMARTPHONE_ACTION_QUIT] = true; + _action_enabled[SMARTPHONE_ACTION_BINDKEYS] = true; } void CEActionsSmartphone::initInstanceGame() { @@ -239,9 +222,14 @@ bool CEActionsSmartphone::perform(GUI::ActionType action, bool pushed) { case SMARTPHONE_ACTION_ROTATE: _CESystem->smartphone_rotate_display(); return true; + case SMARTPHONE_ACTION_QUIT: + { + GUI::MessageDialog alert(" Are you sure you want to quit ? ", "Yes", "No"); + if (alert.runModal() == GUI::kMessageOK) + _mainSystem->quit(); + return true; + } } return false; } - -//#endif diff --git a/backends/platform/wince/CEActionsSmartphone.h b/backends/platform/wince/CEActionsSmartphone.h index b100680d9d..3ba57f1239 100644 --- a/backends/platform/wince/CEActionsSmartphone.h +++ b/backends/platform/wince/CEActionsSmartphone.h @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,36 +23,32 @@ #ifndef CEACTIONSSMARTPHONE #define CEACTIONSSMARTPHONE -//#ifdef WIN32_PLATFORM_WFSP - #include "common/stdafx.h" #include "common/scummsys.h" #include "common/system.h" - - #include "wince-sdl.h" #include "gui/Key.h" - #include "gui/Actions.h" -#define SMARTPHONE_ACTION_VERSION 4 +#define SMARTPHONE_ACTION_VERSION 5 enum smartphoneActionType { - SMARTPHONE_ACTION_UP = 0, - SMARTPHONE_ACTION_DOWN, - SMARTPHONE_ACTION_LEFT, - SMARTPHONE_ACTION_RIGHT, - SMARTPHONE_ACTION_LEFTCLICK, - SMARTPHONE_ACTION_RIGHTCLICK, - SMARTPHONE_ACTION_SAVE, - SMARTPHONE_ACTION_SKIP, - SMARTPHONE_ACTION_ZONE, - SMARTPHONE_ACTION_FT_CHEAT, - SMARTPHONE_ACTION_BINDKEYS, - SMARTPHONE_ACTION_KEYBOARD, - SMARTPHONE_ACTION_ROTATE, - - SMARTPHONE_ACTION_LAST + SMARTPHONE_ACTION_UP = 0, + SMARTPHONE_ACTION_DOWN, + SMARTPHONE_ACTION_LEFT, + SMARTPHONE_ACTION_RIGHT, + SMARTPHONE_ACTION_LEFTCLICK, + SMARTPHONE_ACTION_RIGHTCLICK, + SMARTPHONE_ACTION_SAVE, + SMARTPHONE_ACTION_SKIP, + SMARTPHONE_ACTION_ZONE, + SMARTPHONE_ACTION_FT_CHEAT, + SMARTPHONE_ACTION_BINDKEYS, + SMARTPHONE_ACTION_KEYBOARD, + SMARTPHONE_ACTION_ROTATE, + SMARTPHONE_ACTION_QUIT, + + SMARTPHONE_ACTION_LAST }; @@ -78,5 +74,3 @@ class CEActionsSmartphone : public GUI::Actions { }; #endif - -//#endif diff --git a/backends/platform/wince/CEDevice.cpp b/backends/platform/wince/CEDevice.cpp index 495ba1b274..5a60c76bfe 100644 --- a/backends/platform/wince/CEDevice.cpp +++ b/backends/platform/wince/CEDevice.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,9 +20,6 @@ * */ -//#define SIMU_SMARTPHONE 1 -//#define SIMU_SMARTPHONE_2005 1 - #include "common/stdafx.h" #include "CEDevice.h" @@ -30,52 +27,63 @@ #include "wince-sdl.h" -#define KEY_CALENDAR 0xc1 -#define KEY_CONTACTS 0xc2 -#define KEY_INBOX 0xc3 -#define KEY_TASK 0xc4 - -//#ifdef WIN32_PLATFORM_WFSP -const char* SMARTPHONE_KEYS_NAME[] = { - "1", "2", "3","4", "5", "6", "7", "8", "9", "*", "0", "#", - "Home", "Back", "Up", "Down", "Left", "Right", "Action", "Hang up", "Call", - "Soft 1", "Soft 2", "Power", "Volume Up" ,"Volume Down", "Record", "None", - 0 -}; - -// Old mapping from the previous (non SDL) version. To be forgotten. -/* -const int SMARTPHONE_KEYS_MAPPING[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', VK_F8, '0', VK_F9, - VK_LWIN, VK_ESCAPE, VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_RETURN, VK_F4, VK_F3, - VK_F1, VK_F2, VK_F18, VK_F6, VK_F7, VK_F10, 0xff, 0 -}; -*/ - -// FIXME : Home and Record are not mapped -const int SMARTPHONE_KEYS_MAPPING[] = { - '1', '2', '3', '4', '5', '6', '7', '8', '9', VK_F9, '0', VK_F10, - 0xFF, VK_ESCAPE, 0x113, 0x114, 0x111, 0x112, VK_RETURN, 0x11D, 0x11C, - 0x11A, 0x11B, 0x11D, 0x11F, 0x120, 0xFF, 0 -}; - static void (WINAPI* _SHIdleTimerReset)(void) = NULL; static HANDLE (WINAPI* _SetPowerRequirement)(PVOID,int,ULONG,PVOID,ULONG) = NULL; static DWORD (WINAPI* _ReleasePowerRequirement)(HANDLE) = NULL; static HANDLE _hPowerManagement = NULL; static DWORD _lastTime = 0; +static DWORD REG_bat = 0, REG_ac = 0, REG_disp = 0, bat_timeout = 0; #ifdef __GNUC__ extern "C" void WINAPI SystemIdleTimerReset(void); -#define SPI_GETPLATFORMTYPE 257 +#define SPI_GETPLATFORMTYPE 257 +#define SPI_SETBATTERYIDLETIMEOUT 251 +#define SPI_GETBATTERYIDLETIMEOUT 252 #endif - #define TIMER_TRIGGER 9000 -//#endif +DWORD CEDevice::reg_access(TCHAR *key, TCHAR *val, DWORD data) { + HKEY regkey; + DWORD tmpval, cbdata; + + if (RegOpenKeyEx(HKEY_CURRENT_USER, key, 0, 0, ®key) != ERROR_SUCCESS) + return data; + + cbdata = sizeof(DWORD); + if (RegQueryValueEx(regkey, val, NULL, NULL, (LPBYTE) &tmpval, &cbdata) != ERROR_SUCCESS) + { + RegCloseKey(regkey); + return data; + } + + cbdata = sizeof(DWORD); + if (RegSetValueEx(regkey, val, 0, REG_DWORD, (LPBYTE) &data, cbdata) != ERROR_SUCCESS) + { + RegCloseKey(regkey); + return data; + } + + RegCloseKey(regkey); + return tmpval; +} + +void CEDevice::backlight_xchg() { + HANDLE h; + + REG_bat = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("BatteryTimeout"), REG_bat); + REG_ac = reg_access(TEXT("ControlPanel\\BackLight"), TEXT("ACTimeout"), REG_ac); + REG_disp = reg_access(TEXT("ControlPanel\\Power"), TEXT("Display"), REG_disp); + + h = CreateEvent(NULL, FALSE, FALSE, TEXT("BackLightChangeEvent")); + if (h) + { + SetEvent(h); + CloseHandle(h); + } +} -// Power management code borrowed from MoDaCo & Betaplayer. Thanks ! void CEDevice::init() { + // 2003+ power management code borrowed from MoDaCo & Betaplayer. Thanks ! HINSTANCE dll = LoadLibrary(TEXT("aygshell.dll")); if (dll) { *(FARPROC*)&_SHIdleTimerReset = GetProcAddress(dll, MAKEINTRESOURCE(2006)); @@ -89,12 +97,20 @@ void CEDevice::init() { if (_SetPowerRequirement) _hPowerManagement = _SetPowerRequirement((PVOID) TEXT("BKL1:"), 0, 1, (PVOID) NULL, 0); _lastTime = GetTickCount(); + + // older devices + REG_bat = REG_ac = REG_disp = 2 * 60 * 60 * 1000; // 2hrs should do it + backlight_xchg(); + SystemParametersInfo(SPI_GETBATTERYIDLETIMEOUT, 0, (void *) &bat_timeout, 0); + SystemParametersInfo(SPI_SETBATTERYIDLETIMEOUT, 60 * 60 * 2, NULL, SPIF_SENDCHANGE); } void CEDevice::end() { - if (_ReleasePowerRequirement && _hPowerManagement) { + if (_ReleasePowerRequirement && _hPowerManagement) _ReleasePowerRequirement(_hPowerManagement); - } + + backlight_xchg(); + SystemParametersInfo(SPI_SETBATTERYIDLETIMEOUT, bat_timeout, NULL, SPIF_SENDCHANGE); } void CEDevice::wakeUp() { @@ -107,97 +123,97 @@ void CEDevice::wakeUp() { } } +bool CEDevice::hasSquareQVGAResolution() { + return (OSystem_WINCE3::getScreenWidth() == 240 && OSystem_WINCE3::getScreenHeight() == 240); +} + bool CEDevice::hasPocketPCResolution() { -#ifdef SIMU_SMARTPHONE -#ifndef SIMU_SMARTPHONE_2005 - return false; -#else - return true; -#endif -#else if (OSystem_WINCE3::isOzone() && hasWideResolution()) return true; - return (OSystem_WINCE3::getScreenWidth() < 320 && OSystem_WINCE3::getScreenWidth() >= 240); -#endif + return (OSystem_WINCE3::getScreenWidth() <= 320 && OSystem_WINCE3::getScreenWidth() >= 240); } bool CEDevice::hasDesktopResolution() { -#ifdef SIMU_SMARTPHONE - return false; -#else if (OSystem_WINCE3::isOzone() && hasWideResolution()) return true; - return (OSystem_WINCE3::getScreenWidth() >= 320); -#endif + return (OSystem_WINCE3::getScreenWidth() > 320); } bool CEDevice::hasWideResolution() { -#ifdef SIMU_SMARTPHONE - return false; -#else return (OSystem_WINCE3::getScreenWidth() >= 640 || OSystem_WINCE3::getScreenHeight() >= 640); -#endif } bool CEDevice::hasSmartphoneResolution() { -#ifdef SIMU_SMARTPHONE -#ifndef SIMU_SMARTPHONE_2005 - return true; -#else - return false; -#endif -#else return (OSystem_WINCE3::getScreenWidth() < 240); -#endif } bool CEDevice::isSmartphone() { -#ifdef SIMU_SMARTPHONE - return true; -#else TCHAR platformType[100]; BOOL result = SystemParametersInfo(SPI_GETPLATFORMTYPE, sizeof(platformType), platformType, 0); if (!result && GetLastError() == ERROR_ACCESS_DENIED) return true; return (_wcsnicmp(platformType, TEXT("SmartPhone"), 10) == 0); -#endif } Common::String CEDevice::getKeyName(unsigned int keyCode) { - char key_name[10]; - - if (!keyCode) - return "No key"; - - if (keyCode == KEY_CALENDAR) - return "Button Calendar"; - if (keyCode == KEY_CONTACTS) - return "Button Contacts"; - if (keyCode == KEY_INBOX) - return "Button Inbox"; - if (keyCode == KEY_TASK) - return "Button Tasks"; - if (keyCode == SDLK_F1) - return "F1 (hard 1)"; - if (keyCode == SDLK_F2) - return "F2 (hard 2)"; - if (keyCode == SDLK_F3) - return "F3 (hard 3)"; - if (keyCode == SDLK_F4) - return "F4 (hard 4)"; - -//#ifdef WIN32_PLATFORM_WFSP - if (hasSmartphoneResolution()) { - int i = 0; - while (SMARTPHONE_KEYS_MAPPING[i]) { - if (keyCode == SMARTPHONE_KEYS_MAPPING[i]) - return SMARTPHONE_KEYS_NAME[i]; - i++; - } + switch (keyCode) { + case SDLK_F1: + return "Softkey A"; + case SDLK_F2: + return "Softkey B"; + case SDLK_F3: + return "Talk"; + case SDLK_F4: + return "End"; + case SDLK_APP1: + return "Application 1"; + case SDLK_APP2: + return "Application 2"; + case SDLK_APP3: + return "Application 3"; + case SDLK_APP4: + return "Application 4"; + case SDLK_APP5: + return "Application 5"; + case SDLK_APP6: + return "Application 6"; + case SDLK_LSUPER: + return "Home"; + case SDLK_ESCAPE: + return "Back"; + case SDLK_UP: + return "Up"; + case SDLK_DOWN: + return "Down"; + case SDLK_LEFT: + return "Left"; + case SDLK_RIGHT: + return "Right"; + case SDLK_RETURN: + return "Action"; + case SDLK_F10: + return "Record"; + case SDLK_F6: + return "Volume Up"; + case SDLK_F7: + return "Volume Down"; + case SDLK_F17: + return "Flip"; + case SDLK_F18: + return "Power"; + case SDLK_F16: + return "Speaker"; + case SDLK_F8: + return "Star"; + case SDLK_F9: + return "Pound"; + case SDLK_F11: + return "Symbol"; + case SDLK_F19: + return "Red Key"; + case 0: + return "None"; + default: + return SDL_GetKeyName((SDLKey)keyCode); } -//#endif - - sprintf(key_name, "Key %.4x", keyCode); - return key_name; } - diff --git a/backends/platform/wince/CEDevice.h b/backends/platform/wince/CEDevice.h index 1165377caa..4dd86f1619 100644 --- a/backends/platform/wince/CEDevice.h +++ b/backends/platform/wince/CEDevice.h @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -28,19 +28,22 @@ #include "common/system.h" #include "common/str.h" -//#include <gx.h> - class CEDevice { public: static void init(); static void end(); static void wakeUp(); static bool hasPocketPCResolution(); + static bool hasSquareQVGAResolution(); static bool hasDesktopResolution(); static bool hasWideResolution(); static bool hasSmartphoneResolution(); static bool isSmartphone(); static Common::String getKeyName(unsigned int keyCode); + + private: + static DWORD reg_access(TCHAR *key, TCHAR *val, DWORD data); + static void backlight_xchg(); }; #endif diff --git a/backends/platform/wince/CEKeysDialog.cpp b/backends/platform/wince/CEKeysDialog.cpp deleted file mode 100644 index 249f1f6fcd..0000000000 --- a/backends/platform/wince/CEKeysDialog.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "CEKeysDialog.h" -#include "CEDevice.h" -#include "gui/Actions.h" - -using GUI::ListWidget; -using GUI::kListNumberingZero; -using GUI::WIDGET_CLEARBG; -using GUI::kListSelectionChangedCmd; -using GUI::kCloseCmd; -using GUI::StaticTextWidget; -using GUI::kTextAlignCenter; -using GUI::CommandSender; -using GUI::Actions; - -enum { - kMapCmd = 'map ', - kOKCmd = 'ok ' -}; - - -CEKeysDialog::CEKeysDialog(const Common::String &title) - : GUI::Dialog(30, 20, 260, 160) { - addButton(this, 160, 20, "Map", kMapCmd, 'M'); // Map - addButton(this, 160, 40, "OK", kOKCmd, 'O'); // OK - addButton(this, 160, 60, "Cancel", kCloseCmd, 'C'); // Cancel - - _actionTitle = new StaticTextWidget(this, 10, 120, 240, 16, title, kTextAlignCenter); - _keyMapping = new StaticTextWidget(this, 10, 140, 240, 16, "", kTextAlignCenter); - - _actionTitle->setFlags(WIDGET_CLEARBG); - _keyMapping->setFlags(WIDGET_CLEARBG); - - _actionsList = new ListWidget(this, "Actions List"); - _actionsList->setNumberingMode(kListNumberingZero); - - // Get actions names - Common::StringList l; - - for (int i = 0; i < GUI_Actions::Instance()->size(); i++) - l.push_back(GUI_Actions::Instance()->actionName((GUI::ActionType)i)); - - _actionsList->setList(l); - - _actionSelected = -1; - GUI_Actions::Instance()->beginMapping(false); -} - -void CEKeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { - switch(cmd) { - - case kListSelectionChangedCmd: - if (_actionsList->getSelected() >= 0) { - char selection[100]; - - sprintf(selection, "Associated key : %s", CEDevice::getKeyName(GUI_Actions::Instance()->getMapping((GUI::ActionType)(_actionsList->getSelected()))).c_str()); - _keyMapping->setLabel(selection); - _keyMapping->draw(); - } - break; - case kMapCmd: - if (_actionsList->getSelected() < 0) { - _actionTitle->setLabel("Please select an action"); - } - else { - char selection[100]; - - _actionSelected = _actionsList->getSelected(); - sprintf(selection, "Associated key : %s", CEDevice::getKeyName(GUI_Actions::Instance()->getMapping((GUI::ActionType)_actionSelected)).c_str()); - _actionTitle->setLabel("Press the key to associate"); - _keyMapping->setLabel(selection); - _keyMapping->draw(); - GUI_Actions::Instance()->beginMapping(true); - _actionsList->setEnabled(false); - } - _actionTitle->draw(); - break; - case kOKCmd: - GUI_Actions::Instance()->saveMapping(); - close(); - break; - case kCloseCmd: - GUI_Actions::Instance()->loadMapping(); - close(); - break; - } -} - -void CEKeysDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { - if (modifiers == 0xff && GUI_Actions::Instance()->mappingActive()) { - // GAPI key was selected - char selection[100]; - - GUI_Actions::Instance()->setMapping((GUI::ActionType)_actionSelected, ascii); - - sprintf(selection, "Associated key : %s", CEDevice::getKeyName(GUI_Actions::Instance()->getMapping((GUI::ActionType)_actionSelected)).c_str()); - _actionTitle->setLabel("Choose an action to map"); - _keyMapping->setLabel(selection); - _keyMapping->draw(); - _actionSelected = -1; - _actionsList->setEnabled(true); - GUI_Actions::Instance()->beginMapping(false); - } -} diff --git a/backends/platform/wince/CEScaler.cpp b/backends/platform/wince/CEScaler.cpp index dac46b801a..85151dafe5 100644 --- a/backends/platform/wince/CEScaler.cpp +++ b/backends/platform/wince/CEScaler.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -89,42 +89,39 @@ void PocketPCLandscapeAspect(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr unsigned int p2; uint16 * inbuf; uint16 * outbuf; - inbuf=(uint16 *)srcPtr; - outbuf=(uint16 *)dstPtr; + inbuf = (uint16 *)srcPtr; + outbuf = (uint16 *)dstPtr; uint16 srcPitch16 = (uint16)(srcPitch / sizeof(uint16)); uint16 dstPitch16 = (uint16)(dstPitch / sizeof(uint16)); - for (i=0; i<((height)/6); i++) { - for (j=0; j<width; j++) { - p1=*((uint16*)inbuf+j); - inbuf+=srcPitch16; - *((uint16*)outbuf+j)=p1; - outbuf+=dstPitch16; - p2=*((uint16*)inbuf+j); - inbuf+=srcPitch16; - *((uint16*)outbuf+j)=MAKEPIXEL(P20(RB(p1))+P80(RB(p2)),P20(G(p1))+P80(G(p2))); - outbuf+=dstPitch16; - p1=p2; - p2=*((uint16*)inbuf+j); - inbuf+=srcPitch16; - *((uint16*)outbuf+j)=MAKEPIXEL(P40(RB(p1))+P60(RB(p2)),P40(G(p1))+P60(G(p2))); - outbuf+=dstPitch16; - p1=p2; - p2=*((uint16*)inbuf+j); - inbuf+=srcPitch16; - *((uint16*)outbuf+j)=MAKEPIXEL(P60(RB(p1))+P40(RB(p2)),P60(G(p1))+P40(G(p2))); - outbuf+=dstPitch16; - p1=p2; - p2=*((uint16*)inbuf+j); - *((uint16*)outbuf+j)=MAKEPIXEL(P80(RB(p1))+P20(RB(p2)),P80(G(p1))+P20(G(p2))); - outbuf+=dstPitch16; - *((uint16*)outbuf+j)=p2; - inbuf=inbuf-srcPitch16*4; - outbuf=outbuf-dstPitch16*5; + for (i = 0; i < height/5; i++) { + for (j=0; j < width; j++) { + p1 = *((uint16*)inbuf+j); inbuf += srcPitch16; + *((uint16*)outbuf+j) = p1; outbuf += dstPitch16; + + p2 = *((uint16*)inbuf+j); inbuf += srcPitch16; + *((uint16*)outbuf+j) = MAKEPIXEL(P20(RB(p1))+P80(RB(p2)),P20(G(p1))+P80(G(p2))); outbuf += dstPitch16; + + p1 = p2; + p2 = *((uint16*)inbuf+j); inbuf += srcPitch16; + *((uint16*)outbuf+j) = MAKEPIXEL(P40(RB(p1))+P60(RB(p2)),P40(G(p1))+P60(G(p2))); outbuf += dstPitch16; + + p1 = p2; + p2 = *((uint16*)inbuf+j); inbuf += srcPitch16; + *((uint16*)outbuf+j) = MAKEPIXEL(P60(RB(p1))+P40(RB(p2)),P60(G(p1))+P40(G(p2))); outbuf += dstPitch16; + + p1 = p2; + p2 = *((uint16*)inbuf+j); + *((uint16*)outbuf+j) = MAKEPIXEL(P80(RB(p1))+P20(RB(p2)),P80(G(p1))+P20(G(p2))); outbuf += dstPitch16; + + *((uint16*)outbuf+j) = p2; + + inbuf = inbuf - srcPitch16*4; + outbuf = outbuf - dstPitch16*5; } - inbuf=inbuf+srcPitch16*5; - outbuf=outbuf+dstPitch16*6; + inbuf = inbuf + srcPitch16*5; + outbuf = outbuf + dstPitch16*6; } } @@ -190,7 +187,6 @@ void PocketPCHalfZoom(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint3 } } -//#ifdef WIN32_PLATFORM_WFSP void SmartphoneLandscape(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, uint32 dstPitch, int width, int height) { uint8 *work; int i; @@ -221,5 +217,3 @@ void SmartphoneLandscape(const uint8 *srcPtr, uint32 srcPitch, uint8 *dstPtr, ui } } } -//#endif - diff --git a/backends/platform/wince/CEgui/ItemAction.cpp b/backends/platform/wince/CEgui/ItemAction.cpp index 9bc9db65bb..7010d85ec0 100644 --- a/backends/platform/wince/CEgui/ItemAction.cpp +++ b/backends/platform/wince/CEgui/ItemAction.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -39,7 +39,8 @@ namespace CEGUI { bool ItemAction::action(int x, int y, bool pushed) { if (checkInside(x, y) && _visible && pushed) { - GUI::Actions::Instance()->perform(_action); + GUI::Actions::Instance()->perform(_action, true); + GUI::Actions::Instance()->perform(_action, false); return true; } else diff --git a/backends/platform/wince/Makefile b/backends/platform/wince/Makefile index 1d08073b1d..44c4b597cf 100644 --- a/backends/platform/wince/Makefile +++ b/backends/platform/wince/Makefile @@ -3,6 +3,7 @@ # $URL$ # $Id$ +wince_gcc_root = /cygdrive/e/wince-gcc-root/ srcdir = ../../.. VPATH = $(srcdir) @@ -10,7 +11,7 @@ VPATH = $(srcdir) #DISABLE_SKY = 1 #DISABLE_QUEEN = 1 #DISABLE_GOB = 1 -#DISABLE_LURE = 1 +DISABLE_LURE = 1 #DISABLE_CINE = 1 #DISABLE_SAGA = 1 #DISABLE_KYRA = 1 @@ -20,8 +21,9 @@ VPATH = $(srcdir) #DISABLE_SWORD2 = 1 #DISABLE_TOUCHE = 1 DISABLE_PARALLACTION = 1 +DISABLE_CRUISE = 1 -DISABLE_HQ_SCALERS = 1 +#DISABLE_HQ_SCALERS = 1 CXX = arm-wince-pe-g++ LD = arm-wince-pe-g++ @@ -41,20 +43,20 @@ DEFINES += -D__stdcall= -Dcdecl= -D__cdecl__= -D__cdecl= -Wno-multichar #DEFINES += -DDEBUG -DUSE_WINDBG -g DEFINES += -O2 -INCLUDES := -I$(srcdir) -I. -I$(srcdir)/engines -Imissing/gcc -Ilibs/include -Ilibs/include/sdl -ICEgui -ICEkeys -I/cygdrive/e/wince-gcc-root/include +INCLUDES := -I$(srcdir) -I. -I$(srcdir)/engines -Imissing/gcc -Ilibs/include -Ilibs/include/sdl -ICEgui -ICEkeys -I$(wince_gcc_root)/include CFLAGS := CXXFLAGS := $(CFLAGS) -LDFLAGS := -Llibs/lib -L/cygdrive/e/wince-gcc-root/lib +LDFLAGS := -Llibs/lib -L$(wince_gcc_root)/lib LIBS := -lSDL -lzlib -lmad -lmpeg2 -ltremorce --entry WinMainCRTStartup TARGET = scummvm.exe OBJS := MODULE_DIRS += . -OBJS += CEActionsPocket.o CEDevice.o CEKeysDialog.o CEScaler.o \ +OBJS += CEActionsPocket.o CEDevice.o CEScaler.o \ CEActionsSmartphone.o CELauncherDialog.o wince-sdl.o OBJS += CEgui/GUIElement.o CEgui/Panel.o CEgui/SDL_ImageResource.o \ CEgui/ItemAction.o CEgui/PanelItem.o CEgui/Toolbar.o \ diff --git a/backends/platform/wince/wince-sdl.cpp b/backends/platform/wince/wince-sdl.cpp index f567b64b36..48eca8164e 100644 --- a/backends/platform/wince/wince-sdl.cpp +++ b/backends/platform/wince/wince-sdl.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,6 +20,8 @@ * */ +// NOTE: formatted for tabstop=4 + #include "common/stdafx.h" #include "backends/platform/wince/wince-sdl.h" @@ -83,10 +85,11 @@ using namespace CEGUI; #define NAME_ITEM_ORIENTATION "Orientation" #define NAME_ITEM_BINDKEYS "Bindkeys" -// Given to the true main, needed for backend adaptation - -static FILE *stdout_file; -static FILE *stderr_file; +// stdin/err redirection +#define STDOUT_FNAME "\\scummvm_stdout.txt" +#define STDERR_FNAME "\\scummvm_stderr.txt" +static FILE *stdout_file = NULL, *stderr_file = NULL; +static char stdout_fname[MAX_PATH], stderr_fname[MAX_PATH]; // Static member inits typedef void (*SoundProc)(void *param, byte *buf, int len); @@ -124,8 +127,6 @@ static const OSystem::GraphicsMode s_supportedGraphicsModesHigh[] = { {0, 0, 0} }; -#define STDOUT_FNAME "\\scummvm_stdout.txt" -#define STDERR_FNAME "\\scummvm_stderr.txt" // ******************************************************************************************** @@ -134,6 +135,13 @@ bool isSmartphone() { return _hasSmartphoneResolution; } +const TCHAR *ASCIItoUnicode(const char *str) { + static TCHAR ustr[MAX_PATH]; // size good enough + + MultiByteToWideChar(CP_ACP, 0, str, strlen(str) + 1, ustr, sizeof(ustr) / sizeof(TCHAR)); + return ustr; +} + // MAIN #ifndef __GNUC__ int handleException(EXCEPTION_POINTERS *exceptionPointers) { @@ -153,7 +161,7 @@ OSystem *OSystem_WINCE3_create() { } int SDL_main(int argc, char **argv) { - + FILE *newfp = NULL; #ifdef __GNUC__ // Due to incomplete crt0.o implementation, we go through the constructor function // list provided by the linker and init all of them @@ -170,32 +178,35 @@ int SDL_main(int argc, char **argv) { CEDevice::init(); OSystem_WINCE3::initScreenInfos(); - /* Avoid print problems - this file will be put in RAM anyway */ + /* Redirect standard input and standard output */ + strcpy(stdout_fname, getcwd(NULL, MAX_PATH)); + strcpy(stderr_fname, getcwd(NULL, MAX_PATH)); + strcat(stdout_fname, STDOUT_FNAME); + strcat(stderr_fname, STDERR_FNAME); #ifndef __GNUC__ - stdout_file = fopen(STDOUT_FNAME, "w"); - stderr_file = fopen(STDERR_FNAME, "w"); + stdout_file = fopen(stdout_fname, "w"); + stderr_file = fopen(stderr_fname, "w"); #else - /* Redirect standard input and standard output */ - FILE *newfp = _wfreopen(TEXT(STDOUT_FNAME), TEXT("w"), stdout); + stdout_file = newfp = _wfreopen(ASCIItoUnicode(stdout_fname), TEXT("w"), stdout); if (newfp == NULL) { #if !defined(stdout) - stdout = fopen(STDOUT_FNAME, "w"); + stdout = fopen(stdout_fname, "w"); stdout_file = stdout; #else - newfp = fopen(STDOUT_FNAME, "w"); + newfp = fopen(stdout_fname, "w"); if (newfp) { *stdout = *newfp; stdout_file = stdout; } #endif } - newfp = _wfreopen(TEXT(STDERR_FNAME), TEXT("w"), stderr); + stderr_file = newfp = _wfreopen(ASCIItoUnicode(stderr_fname), TEXT("w"), stderr); if (newfp == NULL) { #if !defined(stderr) - stderr = fopen(STDERR_FNAME, "w"); + stderr = fopen(stderr_fname, "w"); stderr_file = stderr; #else - newfp = fopen(STDERR_FNAME, "w"); + newfp = fopen(stderr_fname, "w"); if (newfp) { *stderr = *newfp; stderr_file = stderr; @@ -214,7 +225,6 @@ int SDL_main(int argc, char **argv) { // Invoke the actual ScummVM main entry point: res = scummvm_main(argc, argv); - //res = scummvm_main(0, NULL); g_system->quit(); // TODO: Consider removing / replacing this! #if !defined(DEBUG) && !defined(__GNUC__) } @@ -258,7 +268,10 @@ void OSystem_WINCE3::initBackend() // Initialize global key mapping GUI::Actions::init(); GUI_Actions::Instance()->initInstanceMain(this); - GUI_Actions::Instance()->loadMapping(); + if (!GUI_Actions::Instance()->loadMapping()) { // error during loading means not present/wrong version + warning("Setting default action mappings."); + GUI_Actions::Instance()->saveMapping(); // write defaults + } loadDeviceConfiguration(); @@ -306,7 +319,7 @@ OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(), _panelVisible(true), _panelStateForced(false), _forceHideMouse(false), _freeLook(false), _forcePanelInvisible(false), _toolbarHighDrawn(false), _zoomUp(false), _zoomDown(false), _scalersChanged(false), _monkeyKeyboard(false), _lastKeyPressed(0), _tapTime(0), - _saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false), + _saveToolbarState(false), _saveActiveToolbar(NAME_MAIN_PANEL), _rbutton(false), _hasfocus(true), _usesEmulatedMouse(false), _mouseBackupOld(NULL), _mouseBackupToolbar(NULL), _mouseBackupDim(0) { _isSmartphone = CEDevice::isSmartphone(); @@ -320,10 +333,13 @@ OSystem_WINCE3::OSystem_WINCE3() : OSystem_SDL(), create_toolbar(); _mixer = 0; + _screen = NULL; } void OSystem_WINCE3::swap_panel_visibility() { //if (!_forcePanelInvisible && !_panelStateForced) { + if (_zoomDown || _zoomUp) return; + if (_panelVisible) { if (_toolbarHandler.activeName() == NAME_PANEL_KEYBOARD) _panelVisible = !_panelVisible; @@ -335,6 +351,7 @@ void OSystem_WINCE3::swap_panel_visibility() { _panelVisible = !_panelVisible; } _toolbarHandler.setVisible(_panelVisible); + _toolbarHighDrawn = false; if (_screenHeight > 240) addDirtyRect(0, 400, 640, 80); @@ -376,7 +393,10 @@ void OSystem_WINCE3::swap_smartphone_keyboard() { _toolbarHandler.setActive(NAME_PANEL_KEYBOARD); _panelVisible = !_panelVisible; _toolbarHandler.setVisible(_panelVisible); - addDirtyRect(0, 0, 320, 40); + if (_screenHeight > 240) + addDirtyRect(0, 0, 640, 80); + else + addDirtyRect(0, 0, 320, 40); internUpdateScreen(); } @@ -417,6 +437,7 @@ void OSystem_WINCE3::swap_zoom_up() { _scaleFactorYd = 2; _scalerProc = PocketPCHalf; _zoomUp = false; + _zoomDown = false; } else { @@ -430,9 +451,8 @@ void OSystem_WINCE3::swap_zoom_up() { _scaleFactorYd = 1; _scalerProc = PocketPCHalfZoom; } - else - _zoomDown = false; - + + _zoomDown = false; _zoomUp = true; } // redraw whole screen @@ -448,6 +468,7 @@ void OSystem_WINCE3::swap_zoom_down() { _scaleFactorYd = 2; _scalerProc = PocketPCHalf; _zoomDown = false; + _zoomUp = false; } else { @@ -461,9 +482,8 @@ void OSystem_WINCE3::swap_zoom_down() { _scaleFactorYd = 1; _scalerProc = PocketPCHalfZoom; } - else - _zoomUp = false; + _zoomUp = false; _zoomDown = true; } // redraw whole screen @@ -641,7 +661,7 @@ bool OSystem_WINCE3::setSoundCallback(SoundProc proc, void *param) { return false; } else - warning("Sound opened OK, mixing at %d Hz", _sampleRate); + debug(1, "Sound opened OK, mixing at %d Hz", _sampleRate); SDL_PauseAudio(0); return true; } @@ -851,18 +871,16 @@ void OSystem_WINCE3::update_game_settings() { panel->add(NAME_ITEM_BINDKEYS, new ItemAction(ITEM_BINDKEYS, POCKET_ACTION_BINDKEYS)); // portrait/landscape - screen dependent // FIXME : will still display the portrait/landscape icon when using a scaler (but will be disabled) - if (_screenWidth <= 320 && (isOzone() || !CEDevice::hasDesktopResolution())) { - if (ConfMan.hasKey("landscape")) - if (ConfMan.get("landscape")[0] > 57) { - _newOrientation = _orientationLandscape = ConfMan.getBool("landscape"); - //ConfMan.removeKey("landscape", ""); - ConfMan.setInt("landscape", _orientationLandscape); - } else - _newOrientation = _orientationLandscape = ConfMan.getInt("landscape"); - else - _newOrientation = _orientationLandscape = 0; - panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2)); - } + if (ConfMan.hasKey("landscape")) + if (ConfMan.get("landscape")[0] > 57) { + _newOrientation = _orientationLandscape = ConfMan.getBool("landscape"); + //ConfMan.removeKey("landscape", ""); + ConfMan.setInt("landscape", _orientationLandscape); + } else + _newOrientation = _orientationLandscape = ConfMan.getInt("landscape"); + else + _newOrientation = _orientationLandscape = 0; + panel->add(NAME_ITEM_ORIENTATION, new ItemSwitch(ITEM_VIEW_LANDSCAPE, ITEM_VIEW_PORTRAIT, &_newOrientation, 2)); _toolbarHandler.add(NAME_MAIN_PANEL, *panel); _toolbarHandler.setActive(NAME_MAIN_PANEL); _toolbarHandler.setVisible(true); @@ -920,6 +938,9 @@ void OSystem_WINCE3::initSize(uint w, uint h) { if (w == 320 && h == 200 && !_hasSmartphoneResolution) h = 240; // use the extra 40 pixels height for the toolbar + if (h == 400) // touche engine fixup + h += 80; + if (!_hasSmartphoneResolution) if (h == 240) _toolbarHandler.setOffset(200); @@ -961,15 +982,15 @@ bool OSystem_WINCE3::update_scalers() { _adjustAspectRatio = false; if (CEDevice::hasPocketPCResolution()) { - if (!_orientationLandscape && (_screenWidth == 320 || !_screenWidth)) { + if ( (!_orientationLandscape && (_screenWidth == 320 || !_screenWidth)) + || CEDevice::hasSquareQVGAResolution() ) { _scaleFactorXm = 3; _scaleFactorXd = 4; _scaleFactorYm = 1; _scaleFactorYd = 1; _scalerProc = PocketPCPortrait; _modeFlags = 0; - } - if ( _orientationLandscape && (_screenWidth == 320 || !_screenWidth)) { + } else if ( _orientationLandscape && (_screenWidth == 320 || !_screenWidth)) { Common::String gameid(ConfMan.get("gameid")); // consider removing this check and start honoring the _adjustAspectRatio flag if (!_panelVisible && !_hasSmartphoneResolution && !_overlayVisible && !(strncmp(gameid.c_str(), "zak", 3) == 0)) { _scaleFactorXm = 1; @@ -987,16 +1008,14 @@ bool OSystem_WINCE3::update_scalers() { _scalerProc = Normal1x; _modeFlags = 0; } - } - if (_screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) { + } else if (_screenWidth == 640 && !(isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) { _scaleFactorXm = 1; _scaleFactorXd = 2; _scaleFactorYm = 1; _scaleFactorYd = 2; _scalerProc = PocketPCHalf; _modeFlags = 0; - } - if (_screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) { + } else if (_screenWidth == 640 && (isOzone() && (getScreenWidth() >= 640 || getScreenHeight() >= 640))) { _scaleFactorXm = 1; _scaleFactorXd = 1; _scaleFactorYm = 1; @@ -1007,6 +1026,7 @@ bool OSystem_WINCE3::update_scalers() { return true; } + if (CEDevice::hasSmartphoneResolution()) { if (_screenWidth > 320) error("Game resolution not supported on Smartphone"); @@ -1174,49 +1194,44 @@ void OSystem_WINCE3::loadGFXMode() { // Create the surface that contains the 8 bit game data _screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0); if (_screen == NULL) - error("_screen failed"); + error("_screen failed (%s)", SDL_GetError()); // Create the surface that contains the scaled graphics in 16 bit mode - // Always use full screen mode to have a "clean screen" - displayWidth = _screenWidth * _scaleFactorXm / _scaleFactorXd; - displayHeight = _screenHeight * _scaleFactorYm / _scaleFactorYd; - if (_screenHeight == 400) // touche engine fixup - displayHeight += 80 * _scaleFactorYm / _scaleFactorYd; + if (!_adjustAspectRatio) { + displayWidth = _screenWidth * _scaleFactorXm / _scaleFactorXd; + displayHeight = _screenHeight * _scaleFactorYm / _scaleFactorYd; + } else { + displayWidth = _screenWidth; + displayHeight = _screenHeight; + } - // FIXME - if (displayWidth <= GetSystemMetrics(SM_CXSCREEN)) { // no rotation - displayWidth = GetSystemMetrics(SM_CXSCREEN); - displayHeight = GetSystemMetrics(SM_CYSCREEN); - } else if (displayHeight > GetSystemMetrics(SM_CXSCREEN)) // rotating, clip height - displayHeight = GetSystemMetrics(SM_CXSCREEN); - - if (_orientationLandscape == 2) flags |= SDL_FLIPVIDEO; + switch (_orientationLandscape) { + case 1: + flags |= SDL_LANDSCVIDEO; + break; + case 2: + flags |= SDL_INVLNDVIDEO; + break; + default: + flags |= SDL_PORTRTVIDEO; + } _hwscreen = SDL_SetVideoMode(displayWidth, displayHeight, 16, flags); if (_hwscreen == NULL) { - // DON'T use error(), as this tries to bring up the debug - // console, which WON'T WORK now that _hwscreen is hosed. - - // FIXME: We should be able to continue the game without - // shutting down or bringing up the debug console, but at - // this point we've already screwed up all our member vars. - // We need to find a way to call SDL_VideoModeOK *before* - // that happens and revert to all the old settings if we - // can't pull off the switch to the new settings. - // - // Fingolfin says: the "easy" way to do that is not to modify - // the member vars before we are sure everything is fine. Think - // of "transactions, commit, rollback" style... we use local vars - // in place of the member vars, do everything etc. etc.. In case - // of a failure, rollback is trivial. Only if everything worked fine - // do we "commit" the changed values to the member vars. - warning("SDL_SetVideoMode says we can't switch to that mode"); + warning("SDL_SetVideoMode says we can't switch to that mode (%s)", SDL_GetError()); quit(); } - // Create the surface used for the graphics in 16 bit before scaling, and also the overlay + // see what orientation sdl finally accepted + if (_hwscreen->flags & SDL_PORTRTVIDEO) + _orientationLandscape = _newOrientation = 0; + else if (_hwscreen->flags & SDL_LANDSCVIDEO) + _orientationLandscape = _newOrientation = 1; + else + _orientationLandscape = _newOrientation = 2; + // Create the surface used for the graphics in 16 bit before scaling, and also the overlay // Distinguish 555 and 565 mode if (_hwscreen->format->Rmask == 0x7C00) InitScalers(555); @@ -1228,38 +1243,39 @@ void OSystem_WINCE3::loadGFXMode() { _tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth + 3, _screenHeight + 3, 16, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask); if (_tmpscreen == NULL) - error("_tmpscreen creation failed"); + error("_tmpscreen creation failed (%s)", SDL_GetError()); // Overlay if (CEDevice::hasDesktopResolution()) { _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth * _scaleFactorXm / _scaleFactorXd, _overlayHeight * _scaleFactorYm / _scaleFactorYd, 16, 0, 0, 0, 0); if (_overlayscreen == NULL) - error("_overlayscreen failed"); + error("_overlayscreen failed (%s)", SDL_GetError()); _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth * _scaleFactorXm / _scaleFactorXd + 3, _overlayHeight * _scaleFactorYm / _scaleFactorYd + 3, 16, 0, 0, 0, 0); if (_tmpscreen2 == NULL) - error("_tmpscreen2 failed"); + error("_tmpscreen2 failed (%s)", SDL_GetError()); } else { _overlayscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth, _overlayHeight, 16, 0, 0, 0, 0); if (_overlayscreen == NULL) - error("_overlayscreen failed"); + error("_overlayscreen failed (%s)", SDL_GetError()); _tmpscreen2 = SDL_CreateRGBSurface(SDL_SWSURFACE, _overlayWidth + 3, _overlayHeight + 3, 16, 0, 0, 0, 0); if (_tmpscreen2 == NULL) - error("_tmpscreen2 failed"); + error("_tmpscreen2 failed (%s)", SDL_GetError()); } // Toolbar - uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); + _toolbarHighDrawn = false; + uint16 *toolbar_screen = (uint16 *)calloc(320 * 40, sizeof(uint16)); // *not* leaking memory here _toolbarLow = SDL_CreateRGBSurfaceFrom(toolbar_screen, 320, 40, 16, 320 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask); if (_toolbarLow == NULL) - error("_toolbarLow failed"); + error("_toolbarLow failed (%s)", SDL_GetError()); if (_screenHeight > 240) { uint16 *toolbar_screen = (uint16 *)calloc(640 * 80, sizeof(uint16)); _toolbarHigh = SDL_CreateRGBSurfaceFrom(toolbar_screen, 640, 80, 16, 640 * 2, _hwscreen->format->Rmask, _hwscreen->format->Gmask, _hwscreen->format->Bmask, _hwscreen->format->Amask); if (_toolbarHigh == NULL) - error("_toolbarHigh failed"); + error("_toolbarHigh failed (%s)", SDL_GetError()); } else _toolbarHigh = NULL; @@ -1330,11 +1346,12 @@ void OSystem_WINCE3::hotswapGFXMode() { SDL_FreeSurface(old_overlayscreen); SDL_FreeSurface(old_tmpscreen2); - // Blit everything to the screen + // Blit everything back to the screen + _toolbarHighDrawn = false; internUpdateScreen(); - // Make sure that an Common::EVENT_SCREEN_CHANGED gets sent later - _modeChanged = true; + // Make sure that a Common::EVENT_SCREEN_CHANGED gets sent later -> FIXME this crashes when no game has been loaded. +// _modeChanged = true; } void OSystem_WINCE3::update_keyboard() { @@ -1355,8 +1372,17 @@ void OSystem_WINCE3::update_keyboard() { void OSystem_WINCE3::internUpdateScreen() { SDL_Surface *srcSurf, *origSurf; static bool old_overlayVisible = false; + int numRectsOut = 0; + int16 routx, routy, routw, routh; + assert(_hwscreen != NULL); + // bail if the application is minimized, be nice to OS + if (!_hasfocus) { + Sleep(20); + return; + } + update_keyboard(); // If the shake position changed, fill the dirty area with blackness @@ -1415,7 +1441,7 @@ void OSystem_WINCE3::internUpdateScreen() { // Only draw anything if necessary if (_numDirtyRects > 0) { - SDL_Rect *r; + SDL_Rect *r, *rout; SDL_Rect dst; uint32 srcPitch, dstPitch; SDL_Rect *last_rect = _dirtyRectList + _numDirtyRects; @@ -1424,8 +1450,9 @@ void OSystem_WINCE3::internUpdateScreen() { for (r = _dirtyRectList; r != last_rect; ++r) { dst = *r; - dst.x++; // Shift rect by one since 2xSai needs to acces the data around + dst.x++; // Shift rect by one since 2xSai needs to access the data around dst.y++; // any pixel to scale it, and we want to avoid mem access crashes. + // NOTE: This is also known as BLACK MAGIC, copied from the sdl backend if (SDL_BlitSurface(origSurf, r, srcSurf, &dst) != 0) error("SDL_BlitSurface failed: %s", SDL_GetError()); } @@ -1436,67 +1463,53 @@ void OSystem_WINCE3::internUpdateScreen() { srcPitch = srcSurf->pitch; dstPitch = _hwscreen->pitch; - for (r = _dirtyRectList; r != last_rect; ++r) { - register int dst_y = r->y + _currentShakePos; - register int dst_h = 0; - - // Check if the toolbar is overwritten - if (!_forceFull && toolbarVisible && r->y + r->h >= toolbarOffset) - _toolbarHandler.forceRedraw(); - - if (dst_y < _screenHeight) { - dst_h = r->h; - if (dst_h > _screenHeight - dst_y) - dst_h = _screenHeight - dst_y; - - dst_y *= _scaleFactorYm; - dst_y /= _scaleFactorYd; - - if (_adjustAspectRatio) - dst_h = real2Aspect(dst_h); - - // clip inside platform screen (landscape,bottom only) - if (_orientationLandscape && !_zoomDown && dst_y+dst_h > _screenHeight) - dst_h = _screenHeight - dst_y; - - if (!_zoomDown) - _scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, - (byte *)_hwscreen->pixels + (r->x * 2 * _scaleFactorXm / _scaleFactorXd) + dst_y * dstPitch, dstPitch, r->w, dst_h); - else { - _scalerProc((byte *)srcSurf->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch, - (byte *)_hwscreen->pixels + (r->x * 2 * _scaleFactorXm / _scaleFactorXd) + (dst_y - 240) * dstPitch, dstPitch, r->w, dst_h); + for (r = _dirtyRectList, rout = _dirtyRectOut; r != last_rect; ++r) { + // transform + routx = r->x * _scaleFactorXm / _scaleFactorXd; // locate position in scaled screen + routy = (r->y + _currentShakePos) * _scaleFactorYm / _scaleFactorYd; // adjust for shake offset + routw = r->w * _scaleFactorXm / _scaleFactorXd; + routh = r->h * _scaleFactorYm / _scaleFactorYd; + + // clipping destination rectangle inside device screen (more strict, also more tricky but more stable) + // note that all current scalers do not make dst rect exceed left/right, unless chosen badly (FIXME) + if (_zoomDown) routy -= 240; // adjust for zoom position + if (routy + routh < 0) continue; + if (routy < 0) { + routh += routy; + routy = 0; + } + if (_orientationLandscape) { + if (routy > _platformScreenWidth) continue; + if (routy + routh > _platformScreenWidth) { + routh = _platformScreenWidth - routy; + r->h = routh * _scaleFactorYd / _scaleFactorYm; + } + } else { + if (routy > _platformScreenHeight) continue; + if (routy + routh > _platformScreenHeight) { + routh = _platformScreenHeight - routy; + r->h = routh * _scaleFactorYd / _scaleFactorYm; } - } - r->x = r->x * _scaleFactorXm / _scaleFactorXd; - if (!_zoomDown) - r->y = dst_y; - else - r->y = dst_y - 240; - r->w = r->w * _scaleFactorXm / _scaleFactorXd; - if (!_adjustAspectRatio) - r->h = dst_h * _scaleFactorYm / _scaleFactorYd; - else - r->h = dst_h; + // check if the toolbar is overwritten + if (toolbarVisible && r->y + r->h >= toolbarOffset) + _toolbarHandler.forceRedraw(); + + // blit it (with added voodoo from the sdl backend, shifting the source rect again) + _scalerProc( (byte *)srcSurf->pixels + (r->x * 2 + 2)+ (r->y + 1) * srcPitch, srcPitch, + (byte *)_hwscreen->pixels + routx * 2 + routy * dstPitch, dstPitch, + r->w, r->h); + + // add this rect to output + rout->x = routx; rout->y = routy; + rout->w = routw; rout->h = routh; + numRectsOut++; + rout++; + } SDL_UnlockSurface(srcSurf); SDL_UnlockSurface(_hwscreen); - - // Readjust the dirty rect list in case we are doing a full update. - // This is necessary if shaking is active. - if (_forceFull) { - _dirtyRectList[0].y = 0; - _dirtyRectList[0].h = (_adjustAspectRatio ? 240 : (_zoomUp || _zoomDown ? _screenHeight / 2 : _screenHeight)) * _scaleFactorYm / _scaleFactorYd; - if (_orientationLandscape) - { - if (_dirtyRectList[0].h > _platformScreenWidth) - _dirtyRectList[0].h = _platformScreenWidth; // clip - } else { - if (_dirtyRectList[0].h > _platformScreenHeight) - _dirtyRectList[0].h = _platformScreenHeight; // clip - } - } } // Add the toolbar if needed SDL_Rect toolbar_rect[1]; @@ -1515,8 +1528,6 @@ void OSystem_WINCE3::internUpdateScreen() { SDL_UnlockSurface(_toolbarLow); _toolbarHighDrawn = true; } - else - _toolbarHighDrawn = false; toolbar_rect[0].w *= 2; toolbar_rect[0].h *= 2; toolbarSurface = _toolbarHigh; @@ -1548,8 +1559,8 @@ void OSystem_WINCE3::internUpdateScreen() { } // Finally, blit all our changes to the screen - if (_numDirtyRects > 0) - SDL_UpdateRects(_hwscreen, _numDirtyRects, _dirtyRectList); + if (numRectsOut > 0) + SDL_UpdateRects(_hwscreen, numRectsOut, _dirtyRectOut); _numDirtyRects = 0; _forceFull = false; @@ -1563,30 +1574,6 @@ bool OSystem_WINCE3::saveScreenshot(const char *filename) { return true; } -// FIXME -// Reuse static or proper mapping - -static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode) -{ - if (GUI::Actions::Instance()->mappingActive()) - return key; - - if (key >= SDLK_F1 && key <= SDLK_F9) { - return key - SDLK_F1 + 315; - } else if (key >= SDLK_KP0 && key <= SDLK_KP9) { - return key - SDLK_KP0 + '0'; - } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) { - return key; - } else if (unicode) { - return unicode; - } else if (key >= 'a' && key <= 'z' && mod & KMOD_SHIFT) { - return key & ~0x20; - } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) { - return 0; - } - return key; -} - void OSystem_WINCE3::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { assert (_transactionMode == kTransactionNone); @@ -2048,9 +2035,7 @@ void OSystem_WINCE3::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { else h = 240 - y; } - } - else - if (_zoomDown) { + } else if (_zoomDown) { if (y + h >= 240) { if (y < 240) { h = 240 - y; @@ -2065,8 +2050,24 @@ void OSystem_WINCE3::addDirtyRect(int x, int y, int w, int h, bool mouseRect) { OSystem_SDL::addDirtyRect(x, y, w, h, false); } -// FIXME -// See if some SDL mapping can be useful for HPCs +static int mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode) +{ + if (GUI::Actions::Instance()->mappingActive()) + return key; + + if (key >= SDLK_KP0 && key <= SDLK_KP9) { + return key - SDLK_KP0 + '0'; + } else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) { + return key; + } else if (unicode) { + return unicode; + } else if (key >= 'a' && key <= 'z' && mod & KMOD_SHIFT) { + return key & ~0x20; + } else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) { + return 0; + } + return key; +} bool OSystem_WINCE3::pollEvent(Common::Event &event) { SDL_Event ev; @@ -2096,6 +2097,7 @@ bool OSystem_WINCE3::pollEvent(Common::Event &event) { switch(ev.type) { case SDL_KEYDOWN: // KMOD_RESERVED is used if the key has been injected by an external buffer + debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym)); if (ev.key.keysym.mod != KMOD_RESERVED) { keyEvent = true; _lastKeyPressed = ev.key.keysym.sym; @@ -2117,6 +2119,7 @@ bool OSystem_WINCE3::pollEvent(Common::Event &event) { case SDL_KEYUP: // KMOD_RESERVED is used if the key has been injected by an external buffer + debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym)); if (ev.key.keysym.mod != KMOD_RESERVED) { keyEvent = true; _lastKeyPressed = 0; @@ -2181,12 +2184,13 @@ bool OSystem_WINCE3::pollEvent(Common::Event &event) { if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, true)) { if (!_toolbarHandler.drawn()) + _toolbarHighDrawn = false; internUpdateScreen(); - if (_newOrientation != _orientationLandscape && _mode == GFX_NORMAL) { + if (_newOrientation != _orientationLandscape){ _orientationLandscape = _newOrientation; + _toolbarHighDrawn = false; ConfMan.setInt("landscape", _orientationLandscape); ConfMan.flushToDisk(); - setGraphicsMode(GFX_NORMAL); hotswapGFXMode(); } } else { @@ -2213,6 +2217,7 @@ bool OSystem_WINCE3::pollEvent(Common::Event &event) { if (_toolbarHandler.action(temp_event.mouse.x, temp_event.mouse.y, false)) { if (!_toolbarHandler.drawn()) + _toolbarHighDrawn = false; internUpdateScreen(); } else { if (!_freeLook) @@ -2228,18 +2233,29 @@ bool OSystem_WINCE3::pollEvent(Common::Event &event) { case SDL_QUIT: event.type = Common::EVENT_QUIT; return true; + + case SDL_ACTIVEEVENT: + if (ev.active.state & SDL_APPMOUSEFOCUS) + debug(1, "%s mouse focus.", ev.active.gain ? "Got" : "Lost"); + if (ev.active.state & SDL_APPINPUTFOCUS) + debug(1, "%s input focus.", ev.active.gain ? "Got" : "Lost"); + if (ev.active.state & SDL_APPACTIVE) + debug(1, "%s total focus.", ev.active.gain ? "Got" : "Lost"); + if (ev.active.state & SDL_APPINPUTFOCUS) { + _hasfocus = ev.active.gain; + SDL_PauseAudio(!_hasfocus); + _forceFull |= _hasfocus; + } + break; } } - // Simulate repeated key for Smartphones - - if (!keyEvent) - if (_lastKeyPressed) - if (currentTime > _keyRepeatTime + _keyRepeatTrigger) { - _keyRepeatTime = currentTime; - _keyRepeat++; - GUI_Actions::Instance()->performMapped(_lastKeyPressed, true); - } + // Simulate repeated key for backend + if (!keyEvent && _lastKeyPressed && currentTime > _keyRepeatTime + _keyRepeatTrigger) { + _keyRepeatTime = currentTime; + _keyRepeat++; + GUI_Actions::Instance()->performMapped(_lastKeyPressed, true); + } return false; } @@ -2248,8 +2264,8 @@ void OSystem_WINCE3::quit() { fclose(stdout_file); fclose(stderr_file); if (gDebugLevel <= 0) { - DeleteFile(TEXT("\\scummvm_stdout.txt")); - DeleteFile(TEXT("\\scummvm_stderr.txt")); + DeleteFile(ASCIItoUnicode(stdout_fname)); + DeleteFile(ASCIItoUnicode(stderr_fname)); } CEDevice::end(); OSystem_SDL::quit(); diff --git a/backends/platform/wince/wince-sdl.h b/backends/platform/wince/wince-sdl.h index 7d797e5959..6f7cb7a0c1 100644 --- a/backends/platform/wince/wince-sdl.h +++ b/backends/platform/wince/wince-sdl.h @@ -206,7 +206,9 @@ private: int _scaleFactorXd; // scaler X / int _scaleFactorYm; // scaler Y * int _scaleFactorYd; // scaler Y / + SDL_Rect _dirtyRectOut[NUM_DIRTY_RECT]; bool _scalersChanged; + bool _hasfocus; // scummvm has the top window static int _platformScreenWidth; static int _platformScreenHeight; diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 3255a3bf8a..5583eed30a 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -76,9 +76,9 @@ static const char HELP_STRING[] = " -x, --save-slot[=NUM] Save game slot to load (default: autosave)\n" " -f, --fullscreen Force full-screen mode\n" " -F, --no-fullscreen Force windowed mode\n" - " -g, --gfx-mode=MODE Select graphics scaler (normal,2x,3x,2xsai,\n" - " super2xsai,supereagle,advmame2x,advmame3x,hq2x,\n" - " hq3x,tv2x,dotmatrix)\n" + " -g, --gfx-mode=MODE Select graphics scaler (1x,2x,3x,2xsai,super2xsai,\n" + " supereagle,advmame2x,advmame3x,hq2x,hq3x,tv2x,\n" + " dotmatrix)\n" " --gui-theme=THEME Select GUI theme (default, modern, classic)\n" " --themepath=PATH Path to where GUI themes are stored\n" " -e, --music-driver=MODE Select music driver (see README for details)\n" @@ -251,12 +251,12 @@ void registerDefaults() { // Use this for options which have a required (string) value #define DO_OPTION(shortCmd, longCmd) \ DO_OPTION_OPT(shortCmd, longCmd, 0) \ - if (!option) usage("Option '%s' requires an argument", argv[i]); + if (!option) usage("Option '%s' requires an argument", argv[i-1]); // Use this for options which have a required integer value #define DO_OPTION_INT(shortCmd, longCmd) \ DO_OPTION_OPT(shortCmd, longCmd, 0) \ - if (!option) usage("Option '%s' requires an argument", argv[i]); \ + if (!option) usage("Option '%s' requires an argument", argv[i-1]); \ char *endptr = 0; \ int intValue; intValue = (int)strtol(option, &endptr, 0); \ if (endptr == NULL || *endptr != 0) usage("--%s: Invalid number '%s'", longCmd, option); diff --git a/base/main.cpp b/base/main.cpp index 2737265bca..e353d78deb 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -64,6 +64,8 @@ static bool launcherDialog(OSystem &system) { system.initSize(320, 200); system.endGFXTransaction(); + // Set initial window caption + system.setWindowCaption(gScummVMFullVersion); // Clear the main screen system.clearScreen(); @@ -270,9 +272,6 @@ extern "C" int scummvm_main(int argc, char *argv[]) { // the command line params) was read. system.initBackend(); - // Set initial window caption - system.setWindowCaption(gScummVMFullVersion); - // Unless a game was specified, show the launcher dialog if (0 == ConfMan.getActiveDomain()) { launcherDialog(system); diff --git a/base/plugins.cpp b/base/plugins.cpp index 7734e2c5f3..7e614dd2bd 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -126,6 +126,9 @@ public: #ifndef DISABLE_PARALLACTION LINK_PLUGIN(PARALLACTION) #endif + #ifndef DISABLE_CRUISE + LINK_PLUGIN(CRUISE) + #endif return pl; } @@ -136,8 +139,6 @@ public: #pragma mark - -DECLARE_SINGLETON(PluginManager); - PluginManager::PluginManager() { #ifndef DYNAMIC_MODULES // Add the static plugin provider if we do not build with dynamic diff --git a/common/advancedDetector.cpp b/common/advancedDetector.cpp index 792acf47b2..84b8365584 100644 --- a/common/advancedDetector.cpp +++ b/common/advancedDetector.cpp @@ -254,7 +254,9 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p IntMap filesSize; IntMap allFiles; - String tstr, tstr2; + File testFile; + + String tstr; uint i; char md5str[32+1]; @@ -273,49 +275,47 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) { tstr = String(fileDesc->fileName); tstr.toLowercase(); - tstr2 = tstr + "."; filesList[tstr] = true; - filesList[tstr2] = true; } } - + if (fslist != 0) { + // Get the information of the existing files for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) { - Common::File f; - if (file->isDirectory()) continue; tstr = file->name(); tstr.toLowercase(); - tstr2 = tstr + "."; - allFiles[tstr] = allFiles[tstr2] = 1; + // Strip any trailing dot + if (tstr.lastChar() == '.') + tstr.deleteLastChar(); + + allFiles[tstr] = true; debug(3, "+ %s", tstr.c_str()); - if (!filesList.contains(tstr) && !filesList.contains(tstr2)) continue; + if (!filesList.contains(tstr)) continue; if (!md5_file_string(*file, md5str, params.md5Bytes)) continue; - filesMD5[tstr] = filesMD5[tstr2] = md5str; + filesMD5[tstr] = md5str; debug(3, "> %s: %s", tstr.c_str(), md5str); - if (f.open(file->path())) { - filesSize[tstr] = filesSize[tstr2] = (int32)f.size(); - f.close(); + if (testFile.open(file->path())) { + filesSize[tstr] = (int32)testFile.size(); + testFile.close(); } } } else { - File testFile; - + // Get the information of the requested files for (StringSet::const_iterator file = filesList.begin(); file != filesList.end(); ++file) { tstr = file->_key; - tstr.toLowercase(); debug(3, "+ %s", tstr.c_str()); if (!filesMD5.contains(tstr)) { - if (testFile.open(file->_key)) { - filesSize[tstr] = filesSize[tstr2] = (int32)testFile.size(); + if (testFile.open(tstr) || testFile.open(tstr + ".")) { + filesSize[tstr] = (int32)testFile.size(); testFile.close(); if (md5_file_string(file->_key.c_str(), md5str, params.md5Bytes)) { @@ -330,6 +330,7 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p ADGameDescList matched; int maxFilesMatched = 0; + // MD5 based matching for (i = 0, descPtr = params.descs; ((const ADGameDescription *)descPtr)->gameid != 0; descPtr += params.descItemSize, ++i) { g = (const ADGameDescription *)descPtr; fileMissing = false; @@ -341,18 +342,17 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p continue; } - // Try to open all files for this game + // Try to match all files for this game for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) { tstr = fileDesc->fileName; tstr.toLowercase(); - tstr2 = tstr + "."; - if (!filesMD5.contains(tstr) && !filesMD5.contains(tstr2)) { + if (!filesMD5.contains(tstr)) { fileMissing = true; break; } if (fileDesc->md5 != NULL) { - if (strcmp(fileDesc->md5, filesMD5[tstr].c_str()) && strcmp(fileDesc->md5, filesMD5[tstr2].c_str())) { + if (fileDesc->md5 != filesMD5[tstr]) { debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesMD5[tstr].c_str()); fileMissing = true; break; @@ -360,7 +360,7 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p } if (fileDesc->fileSize != -1) { - if (fileDesc->fileSize != filesSize[tstr] && fileDesc->fileSize != filesSize[tstr2]) { + if (fileDesc->fileSize != filesSize[tstr]) { debug(3, "Size Mismatch. Skipping"); fileMissing = true; break; @@ -378,7 +378,7 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p int curFilesMatched = 0; for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) curFilesMatched++; - + if (curFilesMatched > maxFilesMatched) { debug(2, " ... new best match, removing all previous candidates"); maxFilesMatched = curFilesMatched; @@ -416,26 +416,23 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p printf("\n"); } + // Filename based fallback if (params.fileBasedFallback != 0) { const ADFileBasedFallback *ptr = params.fileBasedFallback; const char* const* filenames = 0; // First we create list of files required for detection. - if (allFiles.empty()) { - File testFile; - - for (; ptr->desc; ptr++) { - filenames = ptr->filenames; - for (; *filenames; filenames++) { - tstr = String(*filenames); - tstr.toLowercase(); - - if (!allFiles.contains(tstr)) { - if (testFile.open(tstr)) { - tstr2 = tstr + "."; - allFiles[tstr] = allFiles[tstr2] = 1; - testFile.close(); - } + // The filenames can be different than the MD5 based match ones. + for (; ptr->desc; ptr++) { + filenames = ptr->filenames; + for (; *filenames; filenames++) { + tstr = String(*filenames); + tstr.toLowercase(); + + if (!allFiles.contains(tstr)) { + if (testFile.open(tstr) || testFile.open(tstr + ".")) { + allFiles[tstr] = true; + testFile.close(); } } } @@ -461,12 +458,10 @@ static ADGameDescList detectGame(const FSList *fslist, const Common::ADParams &p } tstr = String(*filenames); - tstr.toLowercase(); - tstr2 = tstr + "."; debug(3, "++ %s", *filenames); - if (!allFiles.contains(tstr) && !allFiles.contains(tstr2)) { + if (!allFiles.contains(tstr)) { fileMissing = true; continue; } diff --git a/common/algorithm.h b/common/algorithm.h new file mode 100644 index 0000000000..616dc67317 --- /dev/null +++ b/common/algorithm.h @@ -0,0 +1,103 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#ifndef COMMON_ALGORITHM_H +#define COMMON_ALGORITHM_H + +#include "common/scummsys.h" + +namespace Common { + +template<class In, class Out> +Out copy(In first, In last, Out dst) { + while (first != last) + *dst++ = *first++; + return dst; +} + +template<class In, class Out> +Out copy_backward(In first, In last, Out dst) { + while (first != last) + *--dst = *--last; + return dst; +} + +template<class In, class Out, class Op> +Out copy_if(In first, In last, Out dst, Op op) { + while (first != last) { + if (op(*first)) + *dst++ = *first; + ++first; + } + return dst; +} + +template<class In, class T> +In find(In first, In last, const T &v) { + while (first != last) { + if (*first == v) + return first; + ++first; + } + return last; +} + +template<class In, class Pred> +In find_if(In first, In last, Pred p) { + while (first != last) { + if (p(*first)) + return first; + ++first; + } + return last; +} + +template<class In, class Op> +Op for_each(In first, In last, Op f) { + while (first != last) f(*first++); + return f; +} + +// Simple sort function, modelled after std::sort. +// Use it like this: sort(container.begin(), container.end()). +// Also work on plain old int arrays etc. +template<class T> +void sort(T first, T last) { + if (first == last) + return; + + // Simple selection sort + T i(first); + for (; i != last; ++i) { + T minElem(i); + T j(i); + ++j; + for (; j != last; ++j) + if (*j < *minElem) + minElem = j; + if (minElem != i) + SWAP(*minElem, *i); + } +} + +} // end of namespace Common +#endif + diff --git a/common/array.h b/common/array.h index d0be7fa194..97ee6abdf4 100644 --- a/common/array.h +++ b/common/array.h @@ -23,6 +23,7 @@ #define COMMON_ARRAY_H #include "common/scummsys.h" +#include "common/algorithm.h" namespace Common { @@ -37,14 +38,15 @@ public: typedef T *iterator; typedef const T *const_iterator; + typedef T value_type; + public: Array() : _capacity(0), _size(0), _data(0) {} Array(const Array<T>& array) : _capacity(0), _size(0), _data(0) { _size = array._size; _capacity = _size + 32; _data = new T[_capacity]; - for (int i = 0; i < _size; i++) - _data[i] = array._data[i]; + copy(array._data, array._data + _size, _data); } ~Array() { @@ -59,21 +61,14 @@ public: void push_back(const Array<T>& array) { ensureCapacity(_size + array._size); - for (int i = 0; i < array._size; i++) - _data[_size++] = array._data[i]; + copy(array._data, array._data + array._size, _data + _size); + _size += array._size; } void insert_at(int idx, const T& element) { assert(idx >= 0 && idx <= _size); ensureCapacity(_size + 1); - // The following loop is not efficient if you can just memcpy things around. - // e.g. if you have a list of ints. But for real objects (String...), memcpy - // usually isn't correct (specifically, for any class which has a non-default - // copy behaviour. E.g. the String class uses a refCounter which has to be - // updated whenever a String is copied. - for (int i = _size; i > idx; i--) { - _data[i] = _data[i-1]; - } + copy_backward(_data + idx, _data + _size, _data + _size + 1); _data[idx] = element; _size++; } @@ -81,8 +76,7 @@ public: T remove_at(int idx) { assert(idx >= 0 && idx < _size); T tmp = _data[idx]; - for (int i = idx; i < _size - 1; i++) - _data[i] = _data[i+1]; + copy(_data + idx + 1, _data + _size, _data + idx); _size--; return tmp; } @@ -108,8 +102,7 @@ public: _size = array._size; _capacity = _size + 32; _data = new T[_capacity]; - for (int i = 0; i < _size; i++) - _data[i] = array._data[i]; + copy(array._data, array._data + _size, _data); return *this; } @@ -149,11 +142,7 @@ public: } bool contains(const T &key) const { - for (const_iterator i = begin(); i != end(); ++i) { - if (*i == key) - return true; - } - return false; + return find(begin(), end(), key) != end(); } @@ -168,8 +157,7 @@ protected: if (old_data) { // Copy old data - for (int i = 0; i < _size; i++) - _data[i] = old_data[i]; + copy(old_data, old_data + _size, _data); delete [] old_data; } } diff --git a/common/config-manager.cpp b/common/config-manager.cpp index f8426f18d0..41f3c1a7e9 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -33,8 +33,6 @@ #include "common/file.h" #include "common/util.h" -DECLARE_SINGLETON(Common::ConfigManager); - #ifdef __PLAYSTATION2__ #include "backends/platform/ps2/systemps2.h" #endif diff --git a/common/endian.h b/common/endian.h index 173605dde4..c2e9267b58 100644 --- a/common/endian.h +++ b/common/endian.h @@ -131,7 +131,7 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { #endif -#if defined(SCUMM_NEED_ALIGNMENT) || defined(SCUMM_BIG_ENDIAN) +#if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_LITTLE_ENDIAN) FORCEINLINE uint16 READ_LE_UINT16(const void *ptr) { const byte *b = (const byte *)ptr; return (b[1] << 8) + b[0]; @@ -168,7 +168,7 @@ FORCEINLINE uint16 SWAP_BYTES_16(uint16 a) { #endif -#if defined(SCUMM_NEED_ALIGNMENT) || defined(SCUMM_LITTLE_ENDIAN) +#if defined(SCUMM_NEED_ALIGNMENT) || !defined(SCUMM_BIG_ENDIAN) FORCEINLINE uint16 READ_BE_UINT16(const void *ptr) { const byte *b = (const byte *)ptr; return (b[0] << 8) + b[1]; diff --git a/common/func.h b/common/func.h index b644f6569b..19d0ceafec 100644 --- a/common/func.h +++ b/common/func.h @@ -26,16 +26,219 @@ namespace Common { -template <class T> -struct EqualTo { - bool operator()(const T& x, const T& y) const { return x == y; } +template<class Arg, class Result> +struct UnaryFunction { + typedef Arg ArgumenType; + typedef Result ResultType; }; -template <class T> -struct Less { - bool operator()(const T& x, const T& y) const { return x < y; } +template<class Arg1, class Arg2, class Result> +struct BinaryFunction { + typedef Arg1 FirstArgumentType; + typedef Arg2 SecondArgumentType; + typedef Result ResultType; }; +template<class T> +struct EqualTo : public BinaryFunction<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x == y; } +}; + +template<class T> +struct Less : public BinaryFunction<T, T, bool> { + bool operator()(const T& x, const T& y) const { return x < y; } +}; + +template<class Op> +class Binder1st : public UnaryFunction<typename Op::SecondArgumentType, typename Op::ResultType> { +private: + Op _op; + typename Op::FirstArgumentType _arg1; +public: + Binder1st(const Op &op, const typename Op::FirstArgumentType &arg1) : _op(op), _arg1(arg1) {} + + typename Op::ResultType operator()(typename Op::SecondArgumentType v) const { + return _op(_arg1, v); + } +}; + +template<class Op, class T> +inline Binder1st<Op> bind1st(const Op &op, const T &t) { + return Binder1st<Op>(op, t); +} + +template<class Op> +class Binder2nd : public UnaryFunction<typename Op::FirstArgumentType, typename Op::ResultType> { +private: + Op _op; + typename Op::SecondArgumentType _arg2; +public: + Binder2nd(const Op &op, const typename Op::SecondArgumentType &arg2) : _op(op), _arg2(arg2) {} + + typename Op::ResultType operator()(typename Op::FirstArgumentType v) const { + return _op(v, _arg2); + } +}; + +template<class Op, class T> +inline Binder2nd<Op> bind2nd(const Op &op, const T &t) { + return Binder2nd<Op>(op, t); +} + +template<class Arg, class Result> +class PointerToUnaryFunc : public UnaryFunction<Arg, Result> { +private: + Result (*_func)(Arg); +public: + typedef Result (*FuncType)(Arg); + + PointerToUnaryFunc(const FuncType &func) : _func(func) {} + Result operator()(Arg v) const { + return _func(v); + } +}; + +template<class Arg1, class Arg2, class Result> +class PointerToBinaryFunc : public BinaryFunction<Arg1, Arg2, Result> { +private: + Result (*_func)(Arg1, Arg2); +public: + typedef Result (*FuncType)(Arg1, Arg2); + + PointerToBinaryFunc(const FuncType &func) : _func(func) {} + Result operator()(Arg1 v1, Arg2 v2) const { + return _func(v1, v2); + } +}; + +template<class Arg, class Result> +inline PointerToUnaryFunc<Arg, Result> ptr_fun(Result (*func)(Arg)) { + return PointerToUnaryFunc<Arg, Result>(func); +} + +template<class Arg1, class Arg2, class Result> +inline PointerToBinaryFunc<Arg1, Arg2, Result> ptr_fun(Result (*func)(Arg1, Arg2)) { + return PointerToBinaryFunc<Arg1, Arg2, Result>(func); +} + +template<class Result, class T> +class MemFunc0 : public UnaryFunction<T*, Result> { +private: + Result (T::*_func)(); +public: + typedef Result (T::*FuncType)(); + + MemFunc0(const FuncType &func) : _func(func) {} + Result operator()(T *v) const { + return (v->*_func)(); + } +}; + +template<class Result, class T> +class ConstMemFunc0 : public UnaryFunction<T*, Result> { +private: + Result (T::*_func)() const; +public: + typedef Result (T::*FuncType)() const; + + ConstMemFunc0(const FuncType &func) : _func(func) {} + Result operator()(T *v) const { + return (v->*_func)(); + } +}; + +template<class Result, class Arg, class T> +class MemFunc1 : public BinaryFunction<T*, Arg, Result> { +private: + Result (T::*_func)(Arg); +public: + typedef Result (T::*FuncType)(Arg); + + MemFunc1(const FuncType &func) : _func(func) {} + Result operator()(T *v1, Arg v2) const { + return (v1->*_func)(v2); + } +}; + +template<class Result, class Arg, class T> +class ConstMemFunc1 : public BinaryFunction<T*, Arg, Result> { +private: + Result (T::*_func)(Arg) const; +public: + typedef Result (T::*FuncType)(Arg) const; + + ConstMemFunc1(const FuncType &func) : _func(func) {} + Result operator()(T *v1, Arg v2) const { + return (v1->*_func)(v2); + } +}; + +template<class Result, class T> +inline MemFunc0<Result, T> mem_fun(Result (T::*f)()) { + return MemFunc0<Result, T>(f); +} + +template<class Result, class T> +inline ConstMemFunc0<Result, T> mem_fun(Result (T::*f)() const) { + return ConstMemFunc0<Result, T>(f); +} + +template<class Result, class Arg, class T> +inline MemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg)) { + return MemFunc1<Result, Arg, T>(f); +} + +template<class Result, class Arg, class T> +inline ConstMemFunc1<Result, Arg, T> mem_fun(Result (T::*f)(Arg) const) { + return ConstMemFunc1<Result, Arg, T>(f); +} + +template<class Cont> +class BackInsertIterator { +private: + Cont *_container; + +public: + BackInsertIterator(Cont &c) : _container(&c) {} + + BackInsertIterator &operator =(const typename Cont::value_type &v) { + _container->push_back(v); + return *this; + } + + BackInsertIterator &operator *() { return *this; } + BackInsertIterator &operator ++() { return *this; } + BackInsertIterator operator ++(int) { return *this; } +}; + +template<class Cont> +BackInsertIterator<Cont> back_inserter(Cont &c) { + return BackInsertIterator<Cont>(c); +} + +template<class Cont> +class FrontInsertIterator { +private: + Cont *_container; + +public: + FrontInsertIterator(Cont &c) : _container(&c) {} + + FrontInsertIterator &operator =(const typename Cont::value_type &v) { + _container->push_front(v); + return *this; + } + + FrontInsertIterator &operator *() { return *this; } + FrontInsertIterator &operator ++() { return *this; } + FrontInsertIterator operator ++(int) { return *this; } +}; + +template<class Cont> +FrontInsertIterator<Cont> front_inserter(Cont &c) { + return FrontInsertIterator<Cont>(c); +} + /** * Base template for hash functor objects, used by HashMap. * This needs to be specialized for every type that you need to hash. @@ -61,30 +264,7 @@ GENERATE_TRIVIAL_HASH_FUNCTOR(unsigned long); #undef GENERATE_TRIVIAL_HASH_FUNCTOR - -// Simple sort function, modelled after std::sort. -// Use it like this: sort(container.begin(), container.end()). -// Also work on plain old int arrays etc. -template <typename T> -void sort(T first, T last) { - if (first == last) - return; - - // Simple selection sort - T i(first); - for (; i != last; ++i) { - T minElem(i); - T j(i); - ++j; - for (; j != last; ++j) - if (*j < *minElem) - minElem = j; - if (minElem != i) - SWAP(*minElem, *i); - } -} - - } // End of namespace Common #endif + diff --git a/common/hash-str.h b/common/hash-str.h index bb61e3091d..99ebf99a10 100644 --- a/common/hash-str.h +++ b/common/hash-str.h @@ -29,6 +29,8 @@ namespace Common { uint hashit(const char *str); uint hashit_lower(const char *str); // Generate a hash based on the lowercase version of the string +inline uint hashit(const String &str) { return hashit(str.c_str()); } +inline uint hashit_lower(const String &str) { return hashit_lower(str.c_str()); } // FIXME: The following functors obviously are not consistently named diff --git a/common/iff_container.h b/common/iff_container.h new file mode 100644 index 0000000000..730163254f --- /dev/null +++ b/common/iff_container.h @@ -0,0 +1,228 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#ifndef COMMON_IFF_CONTAINER_H +#define COMMON_IFF_CONTAINER_H + +#include "common/stdafx.h" +#include "common/scummsys.h" +#include "common/endian.h" +#include "common/stream.h" +#include "common/util.h" + +namespace Common { + +typedef uint32 IFF_ID; + +#define ID_FORM MKID_BE('FORM') +/* EA IFF 85 group identifier */ +#define ID_CAT MKID_BE('CAT ') +/* EA IFF 85 group identifier */ +#define ID_LIST MKID_BE('LIST') +/* EA IFF 85 group identifier */ +#define ID_PROP MKID_BE('PROP') +/* EA IFF 85 group identifier */ +#define ID_END MKID_BE('END ') +/* unofficial END-of-FORM identifier (see Amiga RKM Devices Ed.3 +page 376) */ +#define ID_ILBM MKID_BE('ILBM') +/* EA IFF 85 raster bitmap form */ +#define ID_DEEP MKID_BE('DEEP') +/* Chunky pixel image files (Used in TV Paint) */ +#define ID_RGB8 MKID_BE('RGB8') +/* RGB image forms, Turbo Silver (Impulse) */ +#define ID_RGBN MKID_BE('RGBN') +/* RGB image forms, Turbo Silver (Impulse) */ +#define ID_PBM MKID_BE('PBM ') +/* 256-color chunky format (DPaint 2 ?) */ +#define ID_ACBM MKID_BE('ACBM') +/* Amiga Contiguous Bitmap (AmigaBasic) */ +#define ID_8SVX MKID_BE('8SVX') +/* Amiga 8 bits voice */ + +/* generic */ + +#define ID_FVER MKID_BE('FVER') +/* AmigaOS version string */ +#define ID_JUNK MKID_BE('JUNK') +/* always ignore this chunk */ +#define ID_ANNO MKID_BE('ANNO') +/* EA IFF 85 Generic Annotation chunk */ +#define ID_AUTH MKID_BE('AUTH') +/* EA IFF 85 Generic Author chunk */ +#define ID_CHRS MKID_BE('CHRS') +/* EA IFF 85 Generic character string chunk */ +#define ID_NAME MKID_BE('NAME') +/* EA IFF 85 Generic Name of art, music, etc. chunk */ +#define ID_TEXT MKID_BE('TEXT') +/* EA IFF 85 Generic unformatted ASCII text chunk */ +#define ID_copy MKID_BE('(c) ') +/* EA IFF 85 Generic Copyright text chunk */ + +/* ILBM chunks */ + +#define ID_BMHD MKID_BE('BMHD') +/* ILBM BitmapHeader */ +#define ID_CMAP MKID_BE('CMAP') +/* ILBM 8bit RGB colormap */ +#define ID_GRAB MKID_BE('GRAB') +/* ILBM "hotspot" coordiantes */ +#define ID_DEST MKID_BE('DEST') +/* ILBM destination image info */ +#define ID_SPRT MKID_BE('SPRT') +/* ILBM sprite identifier */ +#define ID_CAMG MKID_BE('CAMG') +/* Amiga viewportmodes */ +#define ID_BODY MKID_BE('BODY') +/* ILBM image data */ +#define ID_CRNG MKID_BE('CRNG') +/* color cycling */ +#define ID_CCRT MKID_BE('CCRT') +/* color cycling */ +#define ID_CLUT MKID_BE('CLUT') +/* Color Lookup Table chunk */ +#define ID_DPI MKID_BE('DPI ') +/* Dots per inch chunk */ +#define ID_DPPV MKID_BE('DPPV') +/* DPaint perspective chunk (EA) */ +#define ID_DRNG MKID_BE('DRNG') +/* DPaint IV enhanced color cycle chunk (EA) */ +#define ID_EPSF MKID_BE('EPSF') +/* Encapsulated Postscript chunk */ +#define ID_CMYK MKID_BE('CMYK') +/* Cyan, Magenta, Yellow, & Black color map (Soft-Logik) */ +#define ID_CNAM MKID_BE('CNAM') +/* Color naming chunk (Soft-Logik) */ +#define ID_PCHG MKID_BE('PCHG') +/* Line by line palette control information (Sebastiano Vigna) */ +#define ID_PRVW MKID_BE('PRVW') +/* A mini duplicate ILBM used for preview (Gary Bonham) */ +#define ID_XBMI MKID_BE('XBMI') +/* eXtended BitMap Information (Soft-Logik) */ +#define ID_CTBL MKID_BE('CTBL') +/* Newtek Dynamic Ham color chunk */ +#define ID_DYCP MKID_BE('DYCP') +/* Newtek Dynamic Ham chunk */ +#define ID_SHAM MKID_BE('SHAM') +/* Sliced HAM color chunk */ +#define ID_ABIT MKID_BE('ABIT') +/* ACBM body chunk */ +#define ID_DCOL MKID_BE('DCOL') +/* unofficial direct color */ +#define ID_DPPS MKID_BE('DPPS') +/* ? */ +#define ID_TINY MKID_BE('TINY') +/* ? */ +#define ID_DPPV MKID_BE('DPPV') +/* ? */ + +/* 8SVX chunks */ + +#define ID_VHDR MKID_BE('VHDR') +/* 8SVX Voice8Header */ + + +char * ID2string(Common::IFF_ID id); + + +class IFFChunk : public Common::ReadStream { + +protected: + Common::ReadStream *_input; + uint32 bytesRead; + +public: + IFF_ID id; + uint32 size; + + IFFChunk(Common::ReadStream *input): _input(input) { + size = bytesRead = 0; + } + + void incBytesRead(uint32 inc) { + bytesRead += inc; + if (bytesRead > size) { + error("Chunk overead"); + } + } + + void readHeader() { + id = _input->readUint32BE(); + size = _input->readUint32BE(); + bytesRead = 0; + } + + void feed() { + if (size % 2) { + size++; + } + while (!_input->eos() && !eos()) { + readByte(); + } + } + + // Common::ReadStream implementation + bool eos() const { + return (size - bytesRead) == 0; + } + + uint32 read(void *dataPtr, uint32 dataSize) { + incBytesRead(dataSize); + return _input->read(dataPtr, dataSize); + } + +}; + +class IFFParser { +public: + IFFParser(Common::ReadStream &input) : _formChunk(&input), _chunk(&input) { + _formChunk.readHeader(); + if (_formChunk.id != ID_FORM) { + error("IFFDecoder input is not a FORM type IFF file"); + } + _typeId = _formChunk.readUint32BE(); + } + + virtual ~IFFParser() {} + + IFFChunk *nextChunk() { + _chunk.feed(); + _formChunk.incBytesRead(_chunk.size); + + if (_formChunk.eos()) + return 0; + + _formChunk.incBytesRead(8); + _chunk.readHeader(); + + return &_chunk; + } + + IFF_ID _typeId; + +protected: + IFFChunk _formChunk; + IFFChunk _chunk; +}; + +} // namespace Common + +#endif diff --git a/common/list.h b/common/list.h index da20f22cf1..68a464d194 100644 --- a/common/list.h +++ b/common/list.h @@ -111,8 +111,10 @@ public: NodeBase *_anchor; public: - typedef Iterator<T> iterator; - typedef Iterator<const T> const_iterator; + typedef Iterator<T> iterator; + typedef Iterator<const T> const_iterator; + + typedef T value_type; public: List() { diff --git a/common/rect.h b/common/rect.h index 7751d9a84a..be1035669a 100644 --- a/common/rect.h +++ b/common/rect.h @@ -36,9 +36,9 @@ struct Point { int16 x; //!< The horizontal part of the point int16 y; //!< The vertical part of the point - Point() : x(0), y(0) {}; - Point(const Point &p) : x(p.x), y(p.y) {}; - explicit Point(int16 x1, int16 y1) : x(x1), y(y1) {}; + Point() : x(0), y(0) {} + Point(const Point &p) : x(p.x), y(p.y) {} + explicit Point(int16 x1, int16 y1) : x(x1), y(y1) {} Point & operator=(const Point & p) { x = p.x; y = p.y; return *this; }; bool operator==(const Point & p) const { return x == p.x && y == p.y; }; bool operator!=(const Point & p) const { return x != p.x || y != p.y; }; diff --git a/common/scummsys.h b/common/scummsys.h index 94593bf03b..0ba3f67bd8 100644 --- a/common/scummsys.h +++ b/common/scummsys.h @@ -203,27 +203,31 @@ #elif defined(__PALMOS_TRAPS__) || defined (__PALMOS_ARMLET__) - #define scumm_stricmp stricmp - #define scumm_strnicmp strnicmp - #ifdef PALMOS_68K - #define SCUMM_BIG_ENDIAN + # include "globals.h" + # define SCUMM_BIG_ENDIAN + + # define scumm_stricmp StrCaselessCompare + # define scumm_strnicmp StrNCaselessCompare + #else - #define SCUMM_LITTLE_ENDIAN + + # include <extras_string.h> + # define SCUMM_LITTLE_ENDIAN + + # define scumm_stricmp stricmp + # define scumm_strnicmp strnicmp #endif #define SCUMM_NEED_ALIGNMENT - - #include "palmversion.h" - #include "globals.h" - #include "extend.h" - #define STRINGBUFLEN 256 + + extern const char *SCUMMVM_SAVEPATH; #if !defined(COMPILE_ZODIAC) && !defined(COMPILE_OS5) - #define NEWGUI_256 + # define NEWGUI_256 #else - #undef UNUSED + # undef UNUSED #endif #elif defined(__MORPHOS__) diff --git a/common/singleton.h b/common/singleton.h index 5e72e72230..f26324999e 100644 --- a/common/singleton.h +++ b/common/singleton.h @@ -37,8 +37,6 @@ private: Singleton<T>(const Singleton<T>&); Singleton<T>& operator= (const Singleton<T>&); - static T* _singleton; - /** * The default object factory used by the template class Singleton. * By specialising this template function, one can make a singleton use a @@ -58,16 +56,13 @@ public: public: static T& instance() { - // TODO: We aren't thread safe. For now we ignore it since the - // only thing using this singleton template is the config manager, - // and that is first instantiated long before any threads. + // TODO: We aren't thread safe. // TODO: We don't leak, but the destruction order is nevertheless // semi-random. If we use multiple singletons, the destruction // order might become an issue. There are various approaches // to solve that problem, but for now this is sufficient - if (!_singleton) - _singleton = T::makeInstance(); - return *_singleton; + static T *instance = T::makeInstance(); + return *instance; } protected: Singleton<T>() { } @@ -80,8 +75,6 @@ protected: typedef T SingletonBaseType; }; -#define DECLARE_SINGLETON(T) template<> T* Common::Singleton<T>::_singleton=0 - } // End of namespace Common #endif diff --git a/common/str.cpp b/common/str.cpp index 31cbb7cd22..e5272bd133 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -211,6 +211,11 @@ bool String::hasSuffix(const char *x) const { return *x == 0; } +bool String::contains(const char *x) const { + assert(x != 0); + return strstr(c_str(), x) != NULL; +} + void String::deleteLastChar() { deleteChar(_len - 1); } diff --git a/common/str.h b/common/str.h index 16122b579f..9fbb6734f5 100644 --- a/common/str.h +++ b/common/str.h @@ -125,10 +125,10 @@ public: int compareTo(const char *x) const; // strcmp clone int compareToIgnoreCase(const char *x) const; // stricmp clone - - bool hasSuffix(const char *x) const; bool hasPrefix(const char *x) const; + + bool contains(const char *x) const; inline const char *c_str() const { return _str; } inline uint size() const { return _len; } diff --git a/common/system.h b/common/system.h index 4f2f1c37fe..c1ff066095 100644 --- a/common/system.h +++ b/common/system.h @@ -352,14 +352,14 @@ public: * of the relevant methods simply do nothing. * @see endGFXTransaction */ - virtual void beginGFXTransaction() {}; + virtual void beginGFXTransaction() {} /** * End (and thereby commit) the current GFX transaction. * @see beginGFXTransaction */ - virtual void endGFXTransaction() {}; + virtual void endGFXTransaction() {} /** @@ -656,7 +656,7 @@ public: * @see setPalette * @see kFeatureCursorHasPalette */ - virtual void setCursorPalette(const byte *colors, uint start, uint num) {}; + virtual void setCursorPalette(const byte *colors, uint start, uint num) {} /** * Disable or enable cursor palette. @@ -668,7 +668,7 @@ public: * @see setPalette * @see kFeatureCursorHasPalette */ - virtual void disableCursorPalette(bool disable) {}; + virtual void disableCursorPalette(bool disable) {} //@} diff --git a/common/util.cpp b/common/util.cpp index 6089681484..5e5d719e31 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -144,24 +144,24 @@ uint RandomSource::getRandomNumberRng(uint min, uint max) { const LanguageDescription g_languages[] = { + {"zh", "Chinese (Taiwan)", ZH_TWN}, + {"cz", "Czech", CZ_CZE}, + {"nl", "Dutch", NL_NLD}, {"en", "English", EN_ANY}, // Generic English (when only one game version exist) - {"us", "English (US)", EN_USA}, {"gb", "English (GB)", EN_GRB}, - {"de", "German", DE_DEU}, + {"us", "English (US)", EN_USA}, {"fr", "French", FR_FRA}, + {"de", "German", DE_DEU}, + {"hb", "Hebrew", HB_ISR}, {"it", "Italian", IT_ITA}, - {"br", "Portuguese", PT_BRA}, - {"es", "Spanish", ES_ESP}, {"jp", "Japanese", JA_JPN}, - {"zh", "Chinese (Taiwan)", ZH_TWN}, {"kr", "Korean", KO_KOR}, - {"se", "Swedish", SE_SWE}, - {"hb", "Hebrew", HB_ISR}, - {"ru", "Russian", RU_RUS}, - {"cz", "Czech", CZ_CZE}, - {"nl", "Dutch", NL_NLD}, {"nb", "Norwegian Bokm\xE5l", NB_NOR}, {"pl", "Polish", PL_POL}, + {"br", "Portuguese", PT_BRA}, + {"ru", "Russian", RU_RUS}, + {"es", "Spanish", ES_ESP}, + {"se", "Swedish", SE_SWE}, {0, 0, UNK_LANG} }; @@ -415,12 +415,10 @@ static void debugHelper(const char *in_buf, bool caret = true) { strcpy(buf, in_buf); } -#ifndef _WIN32_WCE if (caret) printf("%s\n", buf); else printf("%s", buf); -#endif #if defined( USE_WINDBG ) if (caret) @@ -551,6 +549,7 @@ void NORETURN CDECL error(const char *s, ...) { #endif #ifdef PALMOS_MODE + extern void PalmFatalError(const char *err); PalmFatalError(buf_output); #endif diff --git a/common/util.h b/common/util.h index da76bd7220..d6cfeca89f 100644 --- a/common/util.h +++ b/common/util.h @@ -89,25 +89,24 @@ public: * List of game language. */ enum Language { + ZH_TWN, + CZ_CZE, + NL_NLD, EN_ANY, // Generic English (when only one game version exist) - EN_USA, EN_GRB, - - DE_DEU, + EN_USA, FR_FRA, + DE_DEU, + HB_ISR, IT_ITA, - PT_BRA, - ES_ESP, JA_JPN, - ZH_TWN, KO_KOR, - SE_SWE, - HB_ISR, - RU_RUS, - CZ_CZE, - NL_NLD, NB_NOR, PL_POL, + PT_BRA, + RU_RUS, + ES_ESP, + SE_SWE, UNK_LANG = -1 // Use default language (i.e. none specified) }; @@ -61,7 +61,8 @@ _build_lure=no _build_cine=yes _build_agi=yes _build_touche=yes -_build_parallaction=no +_build_parallaction=yes +_build_cruise=no _need_memalign=no _build_plugins=no _nasm=auto @@ -130,7 +131,7 @@ echocheck () { # # For now the variable is always set to 1, but we could add # another parameter for that... -add_flag_to_config_mk() { +add_flag_to_config_mk_if_no() { if test "$1" = no ; then _config_mk_data="$_config_mk_data"' '"$2 = 1" @@ -321,22 +322,24 @@ Special configuration feature: Optional Features: --disable-debug disable building with debugging symbols --enable-Werror treat warnings as errors + --disable-agi don't build the AGI engine + --disable-agos don't build the AGOS engine + --disable-cine don't build the Cinematique engine evo 1 + --enable-cruise build the Cruise for a Corpse engine + --disable-gob don't build the Gobli*ns engine + --disable-kyra don't build the Legend of Kyrandia engine + --enable-lure build the Lure of the Temptress engine + --disable-he exclude HE70+ games in SCUMM engine + --disable-parallaction don't build the Parallaction engine + --disable-queen don't build the Flight of the Amazon Queen engine + --disable-saga don't build the SAGA engine --disable-scumm don't build the SCUMM engine --disable-scumm-7-8 exclude v7 and v8 game in SCUMM engine (ft, dig, comi and demos) - --disable-he exclude HE70+ games in SCUMM engine - --disable-agos don't build the AGOS engine --disable-sky don't build the Beneath a Steel Sky engine --disable-sword1 don't build the Broken Sword 1 engine --disable-sword2 don't build the Broken Sword 2 engine - --disable-queen don't build the Flight of the Amazon Queen engine - --disable-saga don't build the SAGA engine - --disable-gob don't build the Gobli*ns engine - --disable-kyra don't build the Legend of Kyrandia engine - --enable-lure build the Lure of the Temptress engine - --disable-cine don't build the Cinematique engine evo 1 - --disable-agi don't build the AGI engine --disable-touche don't build the Touche: The Adventures of the Fifth Musketeer engine - --enable-parallaction build the Parallaction engine + --enable-plugins build engines as loadable modules instead of static linking them --disable-mt32emu don't enable the integrated MT-32 emulator @@ -406,7 +409,8 @@ for ac_option in $@; do --disable-cine) _build_cine=no ;; --disable-agi) _build_agi=no ;; --disable-touche) _build_touche=no ;; - --enable-parallaction) _build_parallaction=yes ;; + --disable-parallaction) _build_parallaction=no ;; + --enable-cruise) _build_cruise=yes ;; --disable-hq-scalers) _build_hq_scalers=no ;; --disable-scalers) _build_scalers=no ;; --enable-alsa) _alsa=yes ;; @@ -676,30 +680,31 @@ if test "$_cxx_major" -ge "3" ; then CXXFLAGS="$CXXFLAGS -ansi -W -Wno-unused-parameter" ;; esac - add_flag_to_config_mk no 'HAVE_GCC3' + add_flag_to_config_mk_if_no no 'HAVE_GCC3' fi; # # Engine selection # -add_flag_to_config_mk $_build_scumm 'DISABLE_SCUMM' -add_flag_to_config_mk $_build_scumm_7_8 'DISABLE_SCUMM_7_8' -add_flag_to_config_mk $_build_he 'DISABLE_HE' -add_flag_to_config_mk $_build_agos 'DISABLE_AGOS' -add_flag_to_config_mk $_build_sky 'DISABLE_SKY' -add_flag_to_config_mk $_build_sword1 'DISABLE_SWORD1' -add_flag_to_config_mk $_build_sword2 'DISABLE_SWORD2' -add_flag_to_config_mk $_build_queen 'DISABLE_QUEEN' -add_flag_to_config_mk $_build_kyra 'DISABLE_KYRA' -add_flag_to_config_mk $_build_saga 'DISABLE_SAGA' -add_flag_to_config_mk $_build_gob 'DISABLE_GOB' -add_flag_to_config_mk $_build_lure 'DISABLE_LURE' -add_flag_to_config_mk $_build_cine 'DISABLE_CINE' -add_flag_to_config_mk $_build_agi 'DISABLE_AGI' -add_flag_to_config_mk $_build_touche 'DISABLE_TOUCHE' -add_flag_to_config_mk $_build_parallaction 'DISABLE_PARALLACTION' -add_flag_to_config_mk $_build_hq_scalers 'DISABLE_HQ_SCALERS' -add_flag_to_config_mk $_build_scalers 'DISABLE_SCALERS' +add_flag_to_config_mk_if_no $_build_scumm 'DISABLE_SCUMM' +add_flag_to_config_mk_if_no $_build_scumm_7_8 'DISABLE_SCUMM_7_8' +add_flag_to_config_mk_if_no $_build_he 'DISABLE_HE' +add_flag_to_config_mk_if_no $_build_agos 'DISABLE_AGOS' +add_flag_to_config_mk_if_no $_build_sky 'DISABLE_SKY' +add_flag_to_config_mk_if_no $_build_sword1 'DISABLE_SWORD1' +add_flag_to_config_mk_if_no $_build_sword2 'DISABLE_SWORD2' +add_flag_to_config_mk_if_no $_build_queen 'DISABLE_QUEEN' +add_flag_to_config_mk_if_no $_build_kyra 'DISABLE_KYRA' +add_flag_to_config_mk_if_no $_build_saga 'DISABLE_SAGA' +add_flag_to_config_mk_if_no $_build_gob 'DISABLE_GOB' +add_flag_to_config_mk_if_no $_build_lure 'DISABLE_LURE' +add_flag_to_config_mk_if_no $_build_cine 'DISABLE_CINE' +add_flag_to_config_mk_if_no $_build_agi 'DISABLE_AGI' +add_flag_to_config_mk_if_no $_build_touche 'DISABLE_TOUCHE' +add_flag_to_config_mk_if_no $_build_parallaction 'DISABLE_PARALLACTION' +add_flag_to_config_mk_if_no $_build_cruise 'DISABLE_CRUISE' +add_flag_to_config_mk_if_no $_build_hq_scalers 'DISABLE_HQ_SCALERS' +add_flag_to_config_mk_if_no $_build_scalers 'DISABLE_SCALERS' if test -n "$_host"; then # Cross-compiling mode - add your target here if needed @@ -1035,10 +1040,10 @@ fi # if test "$_mt32emu" = no ; then _def_mt32emu='#undef USE_MT32EMU' - add_flag_to_config_mk yes 'USE_MT32EMU' + add_flag_to_config_mk_if_no yes 'USE_MT32EMU' else _def_mt32emu='#define USE_MT32EMU' - add_flag_to_config_mk no 'USE_MT32EMU' + add_flag_to_config_mk_if_no no 'USE_MT32EMU' fi # @@ -1058,8 +1063,10 @@ if test "$_vorbis" = yes ; then _def_vorbis='#define USE_VORBIS' LIBS="$LIBS $OGG_LIBS $VORBIS_LIBS -lvorbisfile -lvorbis -logg" INCLUDES="$INCLUDES $OGG_CFLAGS $VORBIS_CFLAGS" + add_flag_to_config_mk_if_no no 'USE_VORBIS' else _def_vorbis='#undef USE_VORBIS' + add_flag_to_config_mk_if_no yes 'USE_VORBIS' fi echo "$_vorbis" @@ -1077,15 +1084,17 @@ cc_check $LDFLAGS $CXXFLAGS $TREMOR_CFLAGS $TREMOR_LIBS -lvorbisidec && \ _tremor=yes fi if test "$_tremor" = yes && test "$_vorbis" = no; then - _def_tremor='#define USE_TREMOR' - _def_vorbis='#define USE_VORBIS' - LIBS="$LIBS $TREMOR_LIBS -lvorbisidec" - INCLUDES="$INCLUDES $TREMOR_CFLAGS" + _def_tremor='#define USE_TREMOR' + _def_vorbis='#define USE_VORBIS' + LIBS="$LIBS $TREMOR_LIBS -lvorbisidec" + INCLUDES="$INCLUDES $TREMOR_CFLAGS" + add_flag_to_config_mk_if_no no 'USE_TREMOR' else - if test "$_vorbis" = yes; then - _tremor="no (Ogg Vorbis/Tremor support is mutually exclusive)" - fi - _def_tremor='#undef USE_TREMOR' + if test "$_vorbis" = yes; then + _tremor="no (Ogg Vorbis/Tremor support is mutually exclusive)" + fi + _def_tremor='#undef USE_TREMOR' + add_flag_to_config_mk_if_no yes 'USE_TREMOR' fi echo "$_tremor" @@ -1106,8 +1115,10 @@ if test "$_flac" = yes ; then _def_flac='#define USE_FLAC' LIBS="$LIBS $FLAC_LIBS $OGG_LIBS -lFLAC -logg" INCLUDES="$INCLUDES $FLAC_CFLAGS" + add_flag_to_config_mk_if_no no 'USE_FLAC' else _def_flac='#undef USE_FLAC' + add_flag_to_config_mk_if_no yes 'USE_FLAC' fi echo "$_flac" @@ -1127,8 +1138,10 @@ if test "$_mad" = yes ; then _def_mad='#define USE_MAD' LIBS="$LIBS $MAD_LIBS -lmad" INCLUDES="$INCLUDES $MAD_CFLAGS" + add_flag_to_config_mk_if_no no 'USE_MAD' else _def_mad='#undef USE_MAD' + add_flag_to_config_mk_if_no yes 'USE_MAD' fi echo "$_mad" @@ -1214,8 +1227,10 @@ if test "$_mpeg2" = yes ; then _def_mpeg2='#define USE_MPEG2' INCLUDES="$INCLUDES $MPEG2_CFLAGS" LIBS="$LIBS $MPEG2_LIBS -lmpeg2" + add_flag_to_config_mk_if_no no 'USE_MPEG2' else _def_mpeg2='#undef USE_MPEG2' + add_flag_to_config_mk_if_no yes 'USE_MPEG2' fi echo "$_mpeg2" rm -f $TMPC $TMPO$EXEEXT @@ -1251,10 +1266,10 @@ fi if test "$_nasm" = yes ; then _def_nasm='#define USE_NASM' - add_flag_to_config_mk no 'HAVE_NASM' + add_flag_to_config_mk_if_no no 'HAVE_NASM' else _def_nasm='#undef USE_NASM' - add_flag_to_config_mk yes 'HAVE_NASM' + add_flag_to_config_mk_if_no yes 'HAVE_NASM' fi # @@ -1331,6 +1346,9 @@ fi if test "$_build_parallaction" = yes ; then echo " Parallaction" fi +if test "$_build_cruise" = yes ; then + echo " Cinematique evo 2" +fi echo diff --git a/dists/codeblocks/parallaction.cbp b/dists/codeblocks/parallaction.cbp index 875460da59..60b08ef32e 100644 --- a/dists/codeblocks/parallaction.cbp +++ b/dists/codeblocks/parallaction.cbp @@ -17,6 +17,7 @@ <Option createDefFile="1" /> <Compiler> <Add option="-O2" /> + <Add option="-Wno-multichar" /> <Add directory="..\..\engines" /> <Add directory="..\..\..\scummvm" /> </Compiler> @@ -57,6 +58,12 @@ <Option compilerVar="CPP" /> <Option target="default" /> </Unit> + <Unit filename="..\..\engines\parallaction\debug.h"> + <Option compilerVar="CPP" /> + <Option compile="0" /> + <Option link="0" /> + <Option target="default" /> + </Unit> <Unit filename="..\..\engines\parallaction\defs.h"> <Option compilerVar="CPP" /> <Option compile="0" /> @@ -81,6 +88,10 @@ <Option link="0" /> <Option target="default" /> </Unit> + <Unit filename="..\..\engines\parallaction\font.cpp"> + <Option compilerVar="CPP" /> + <Option target="default" /> + </Unit> <Unit filename="..\..\engines\parallaction\graphics.cpp"> <Option compilerVar="CPP" /> <Option target="default" /> @@ -125,38 +136,38 @@ <Option link="0" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\music.cpp"> + <Unit filename="..\..\engines\parallaction\parallaction.cpp"> <Option compilerVar="CPP" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\music.h"> + <Unit filename="..\..\engines\parallaction\parallaction.h"> <Option compilerVar="CPP" /> <Option compile="0" /> <Option link="0" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\parallaction.cpp"> + <Unit filename="..\..\engines\parallaction\parser.cpp"> <Option compilerVar="CPP" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\parallaction.h"> + <Unit filename="..\..\engines\parallaction\parser.h"> <Option compilerVar="CPP" /> <Option compile="0" /> <Option link="0" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\parser.cpp"> + <Unit filename="..\..\engines\parallaction\saveload.cpp"> <Option compilerVar="CPP" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\parser.h"> + <Unit filename="..\..\engines\parallaction\sound.cpp"> <Option compilerVar="CPP" /> - <Option compile="0" /> - <Option link="0" /> <Option target="default" /> </Unit> - <Unit filename="..\..\engines\parallaction\saveload.cpp"> + <Unit filename="..\..\engines\parallaction\sound.h"> <Option compilerVar="CPP" /> + <Option compile="0" /> + <Option link="0" /> <Option target="default" /> </Unit> <Unit filename="..\..\engines\parallaction\staticres.cpp"> diff --git a/dists/codeblocks/parallaction.depend b/dists/codeblocks/parallaction.depend index 5fddf3f7c2..c4ac3106ea 100644 --- a/dists/codeblocks/parallaction.depend +++ b/dists/codeblocks/parallaction.depend @@ -1,410 +1 @@ # depslib dependency file v1.0 -1174137321 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\animation.cpp - "parallaction/disk.h" - "parallaction/parallaction.h" - "parallaction/graphics.h" - "parallaction/music.h" - "parallaction/parser.h" - "parallaction/zone.h" - -1173995808 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\disk.h - "parallaction/defs.h" - "common/file.h" - -1174137600 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\defs.h - "common/stdafx.h" - "common/system.h" - -1173562730 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stdafx.h - <portdefs.h> - <strings.h> - <stdio.h> - <stdlib.h> - <string.h> - <stdarg.h> - <assert.h> - <ctype.h> - <time.h> - <math.h> - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\system.h - "common/scummsys.h" - "common/mutex.h" - "common/noncopyable.h" - "common/rect.h" - -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\scummsys.h - "config.h" - <SDL_byteorder.h> - "palmversion.h" - "globals.h" - "extend.h" - "nds/jtypes.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\mutex.h - "common/scummsys.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\noncopyable.h - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\rect.h - "common/scummsys.h" - "common/util.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\util.h - "common/scummsys.h" - "common/str.h" - "common/array.h" - -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\str.h - "common/scummsys.h" - "common/array.h" - -1173785171 c:\documents and settings\usoquotidiano\desktop\scummvm\common\array.h - "common/scummsys.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\file.h - "common/stdafx.h" - "common/scummsys.h" - "common/str.h" - "common/stream.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stream.h - "common/stdafx.h" - "common/scummsys.h" - -1174137600 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\parallaction.h - "engines/engine.h" - "parallaction/defs.h" - "parallaction/inventory.h" - "parallaction/parser.h" - "parallaction/disk.h" - "parallaction/zone.h" - "common/str.h" - "gui/dialog.h" - "gui/widget.h" - -1173398879 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\engine.h - "common/stdafx.h" - "common/scummsys.h" - "common/str.h" - -1173731024 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\inventory.h - -1173398860 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\parser.h - "parallaction/defs.h" - "common/stream.h" - -1174137600 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\zone.h - "parallaction/defs.h" - -1174117751 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\dialog.h - "common/scummsys.h" - "common/str.h" - "gui/object.h" - "gui/widget.h" - -1174117751 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\object.h - -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\widget.h - "common/scummsys.h" - "common/str.h" - "graphics/font.h" - "graphics/surface.h" - "gui/object.h" - -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\font.h - "common/str.h" - "graphics/surface.h" - -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\surface.h - "common/scummsys.h" - "common/rect.h" - -1174077965 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\graphics.h - "parallaction/defs.h" - "common/stream.h" - "common/pack-start.h" - "common/pack-end.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\pack-start.h - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\pack-end.h - -1173398860 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\music.h - "common/util.h" - "common/mutex.h" - "sound/mididrv.h" - -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mididrv.h - "common/scummsys.h" - "common/timer.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\timer.h - "common/scummsys.h" - "common/noncopyable.h" - -1173398860 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\archive.cpp - "common/file.h" - "parallaction/disk.h" - -1174137321 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\callables.cpp - "parallaction/disk.h" - "parallaction/parallaction.h" - "parallaction/graphics.h" - "parallaction/inventory.h" - "parallaction/menu.h" - "parallaction/music.h" - "parallaction/zone.h" - "common/file.h" - -1173626357 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\menu.h - "parallaction/defs.h" - -1173398860 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\debug.cpp - "common/stdafx.h" - "common/system.h" - "parallaction/parallaction.h" - "parallaction/graphics.h" - -1173398860 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\detection.cpp - "common/stdafx.h" - "base/plugins.h" - "common/advancedDetector.h" - "parallaction/parallaction.h" - -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\plugins.h - "common/stdafx.h" - "common/array.h" - "common/list.h" - "common/singleton.h" - "common/util.h" - "base/game.h" - -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\list.h - "common/scummsys.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\singleton.h - "common/noncopyable.h" - -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\game.h - "common/stdafx.h" - "common/str.h" - "common/array.h" - "common/hash-str.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\hash-str.h - "common/hashmap.h" - "common/str.h" - -1173785171 c:\documents and settings\usoquotidiano\desktop\scummvm\common\hashmap.h - "common/stdafx.h" - "common/func.h" - "common/str.h" - "common/util.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\func.h - "common/scummsys.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\advanceddetector.h - "common/fs.h" - "base/game.h" - "base/plugins.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\fs.h - "common/array.h" - "common/str.h" - -1174136052 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\dialogue.cpp - "parallaction/commands.h" - "parallaction/parallaction.h" - "parallaction/graphics.h" - "parallaction/disk.h" - "parallaction/inventory.h" - "parallaction/parser.h" - "parallaction/zone.h" - "common/events.h" - -1174137600 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\commands.h - "parallaction/defs.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\events.h - "common/rect.h" - "common/system.h" - "common/noncopyable.h" - -1173995808 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\disk.cpp - "parallaction/defs.h" - "parallaction/graphics.h" - "parallaction/parallaction.h" - "parallaction/disk.h" - "parallaction/walk.h" - -1173740074 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\walk.h - "parallaction/defs.h" - -1174136052 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\graphics.cpp - "common/file.h" - "parallaction/graphics.h" - "parallaction/parser.h" - "parallaction/parallaction.h" - "parallaction/disk.h" - "parallaction/zone.h" - -1173909457 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\intro.cpp - "parallaction/parallaction.h" - "parallaction/menu.h" - "parallaction/music.h" - "parallaction/graphics.h" - "parallaction/zone.h" - -1174137321 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\inventory.cpp - "parallaction/parallaction.h" - "parallaction/disk.h" - "parallaction/zone.h" - "parallaction/graphics.h" - "parallaction/inventory.h" - -1173995808 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\menu.cpp - "parallaction/menu.h" - "parallaction/disk.h" - "parallaction/music.h" - "parallaction/graphics.h" - "parallaction/parallaction.h" - -1173647915 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\music.cpp - "common/stdafx.h" - "common/file.h" - "parallaction/parallaction.h" - "common/stream.h" - "sound/midiparser.h" - "parallaction/music.h" - -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser.h - "common/scummsys.h" - "common/endian.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\endian.h - "common/scummsys.h" - -1174137321 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\parallaction.cpp - "common/stdafx.h" - "common/config-manager.h" - "common/events.h" - "common/file.h" - "common/util.h" - "sound/mididrv.h" - "sound/mixer.h" - "parallaction/parallaction.h" - "parallaction/menu.h" - "parallaction/parser.h" - "parallaction/disk.h" - "parallaction/music.h" - "parallaction/inventory.h" - "parallaction/graphics.h" - "parallaction/walk.h" - "parallaction/zone.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-manager.h - "common/array.h" - "common/hashmap.h" - "common/singleton.h" - "common/str.h" - "common/hash-str.h" - -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mixer.h - "common/stdafx.h" - "common/scummsys.h" - "common/mutex.h" - -1173398860 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\parser.cpp - "parallaction/defs.h" - "parallaction/parser.h" - "parallaction/parallaction.h" - "parallaction/disk.h" - -1174118148 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\saveload.cpp - "parallaction/parallaction.h" - "parallaction/disk.h" - "parallaction/graphics.h" - "parallaction/zone.h" - "common/savefile.h" - "gui/widget.h" - "gui/ListWidget.h" - "gui/message.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\savefile.h - "common/stdafx.h" - "common/noncopyable.h" - "common/scummsys.h" - "common/stream.h" - -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\listwidget.h - "gui/editable.h" - "common/str.h" - -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\editable.h - "common/str.h" - "common/rect.h" - "gui/widget.h" - "gui/newgui.h" - -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\newgui.h - "common/scummsys.h" - "common/singleton.h" - "common/stack.h" - "common/str.h" - "graphics/fontman.h" - "gui/theme.h" - "gui/widget.h" - -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stack.h - "common/scummsys.h" - "common/array.h" - -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fontman.h - "common/stdafx.h" - "common/scummsys.h" - "common/singleton.h" - "common/str.h" - "common/hashmap.h" - "common/hash-str.h" - "graphics/font.h" - -1173562730 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme.h - "common/stdafx.h" - "common/system.h" - "common/rect.h" - "common/str.h" - "common/file.h" - "common/config-file.h" - "graphics/surface.h" - "graphics/fontman.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-file.h - "common/config-manager.h" - "common/list.h" - "common/str.h" - "common/stream.h" - -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\message.h - "gui/dialog.h" - "common/str.h" - -1173732116 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\staticres.cpp - "parallaction/graphics.h" - -1174137321 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\walk.cpp - "parallaction/defs.h" - "parallaction/parallaction.h" - "parallaction/commands.h" - "parallaction/graphics.h" - "parallaction/walk.h" - "parallaction/zone.h" - -1174137321 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\parallaction\zone.cpp - "parallaction/parser.h" - "parallaction/parallaction.h" - "parallaction/graphics.h" - "parallaction/inventory.h" - "parallaction/zone.h" - diff --git a/dists/codeblocks/parallaction.layout b/dists/codeblocks/parallaction.layout index 835e249700..4f11f206db 100644 --- a/dists/codeblocks/parallaction.layout +++ b/dists/codeblocks/parallaction.layout @@ -1,100 +1,103 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <CodeBlocks_layout_file> <ActiveTarget name="default" /> - <File name="..\..\engines\parallaction\animation.cpp" open="1" top="0" tabpos="2"> - <Cursor position="7368" topLine="252" /> + <File name="..\..\engines\parallaction\animation.cpp" open="0" top="0" tabpos="4"> + <Cursor position="2198" topLine="48" /> </File> - <File name="..\..\engines\parallaction\archive.cpp" open="0" top="0" tabpos="14"> - <Cursor position="1310" topLine="26" /> + <File name="..\..\engines\parallaction\archive.cpp" open="0" top="0" tabpos="12"> + <Cursor position="3311" topLine="71" /> </File> - <File name="..\..\engines\parallaction\callables.cpp" open="1" top="0" tabpos="15"> - <Cursor position="9374" topLine="303" /> + <File name="..\..\engines\parallaction\callables.cpp" open="0" top="0" tabpos="2"> + <Cursor position="11738" topLine="405" /> </File> - <File name="..\..\engines\parallaction\commands.cpp" open="1" top="0" tabpos="16"> - <Cursor position="5835" topLine="166" /> + <File name="..\..\engines\parallaction\commands.cpp" open="0" top="0" tabpos="4"> + <Cursor position="8339" topLine="280" /> </File> - <File name="..\..\engines\parallaction\commands.h" open="1" top="0" tabpos="13"> - <Cursor position="1490" topLine="35" /> + <File name="..\..\engines\parallaction\commands.h" open="0" top="0" tabpos="10"> + <Cursor position="1669" topLine="24" /> </File> - <File name="..\..\engines\parallaction\debug.cpp" open="0" top="0" tabpos="11"> - <Cursor position="1671" topLine="19" /> + <File name="..\..\engines\parallaction\debug.cpp" open="0" top="0" tabpos="7"> + <Cursor position="1523" topLine="18" /> </File> - <File name="..\..\engines\parallaction\defs.h" open="1" top="0" tabpos="4"> - <Cursor position="1241" topLine="29" /> + <File name="..\..\engines\parallaction\defs.h" open="0" top="0" tabpos="9"> + <Cursor position="1167" topLine="15" /> </File> - <File name="..\..\engines\parallaction\detection.cpp" open="0" top="0" tabpos="12"> - <Cursor position="1049" topLine="7" /> + <File name="..\..\engines\parallaction\detection.cpp" open="0" top="0" tabpos="13"> + <Cursor position="3283" topLine="50" /> </File> - <File name="..\..\engines\parallaction\dialogue.cpp" open="1" top="0" tabpos="3"> - <Cursor position="6759" topLine="211" /> + <File name="..\..\engines\parallaction\dialogue.cpp" open="0" top="0" tabpos="12"> + <Cursor position="9886" topLine="331" /> </File> - <File name="..\..\engines\parallaction\disk.cpp" open="1" top="0" tabpos="10"> - <Cursor position="2449" topLine="96" /> + <File name="..\..\engines\parallaction\disk.cpp" open="1" top="1" tabpos="1"> + <Cursor position="12394" topLine="590" /> </File> - <File name="..\..\engines\parallaction\disk.h" open="0" top="0" tabpos="12"> - <Cursor position="3242" topLine="73" /> + <File name="..\..\engines\parallaction\disk.h" open="0" top="0" tabpos="10"> + <Cursor position="2566" topLine="85" /> </File> - <File name="..\..\engines\parallaction\graphics.cpp" open="1" top="0" tabpos="5"> - <Cursor position="19121" topLine="767" /> + <File name="..\..\engines\parallaction\font.cpp" open="0" top="0" tabpos="12"> + <Cursor position="2879" topLine="102" /> </File> - <File name="..\..\engines\parallaction\graphics.h" open="1" top="0" tabpos="12"> - <Cursor position="4260" topLine="125" /> + <File name="..\..\engines\parallaction\graphics.cpp" open="0" top="0" tabpos="4"> + <Cursor position="9121" topLine="275" /> </File> - <File name="..\..\engines\parallaction\intro.cpp" open="0" top="0" tabpos="4"> - <Cursor position="8671" topLine="158" /> + <File name="..\..\engines\parallaction\graphics.h" open="0" top="0" tabpos="2"> + <Cursor position="4971" topLine="148" /> </File> - <File name="..\..\engines\parallaction\inventory.cpp" open="1" top="0" tabpos="6"> - <Cursor position="3395" topLine="89" /> + <File name="..\..\engines\parallaction\intro.cpp" open="0" top="0" tabpos="3"> + <Cursor position="7371" topLine="0" /> </File> - <File name="..\..\engines\parallaction\inventory.h" open="0" top="0" tabpos="9"> - <Cursor position="1418" topLine="10" /> + <File name="..\..\engines\parallaction\inventory.cpp" open="0" top="0" tabpos="7"> + <Cursor position="2257" topLine="42" /> </File> - <File name="..\..\engines\parallaction\location.cpp" open="1" top="0" tabpos="11"> - <Cursor position="0" topLine="0" /> + <File name="..\..\engines\parallaction\inventory.h" open="0" top="0" tabpos="14"> + <Cursor position="1402" topLine="10" /> </File> - <File name="..\..\engines\parallaction\menu.cpp" open="0" top="0" tabpos="11"> - <Cursor position="8465" topLine="57" /> + <File name="..\..\engines\parallaction\location.cpp" open="0" top="0" tabpos="15"> + <Cursor position="5172" topLine="133" /> </File> - <File name="..\..\engines\parallaction\menu.h" open="0" top="0" tabpos="2"> - <Cursor position="1282" topLine="7" /> + <File name="..\..\engines\parallaction\menu.cpp" open="0" top="0" tabpos="8"> + <Cursor position="6240" topLine="250" /> </File> - <File name="..\..\engines\parallaction\module.mk" open="0" top="0" tabpos="12"> - <Cursor position="165" topLine="0" /> + <File name="..\..\engines\parallaction\menu.h" open="0" top="0" tabpos="17"> + <Cursor position="1131" topLine="7" /> </File> - <File name="..\..\engines\parallaction\music.cpp" open="0" top="0" tabpos="15"> - <Cursor position="2102" topLine="49" /> + <File name="..\..\engines\parallaction\module.mk" open="0" top="0" tabpos="8"> + <Cursor position="373" topLine="0" /> </File> - <File name="..\..\engines\parallaction\music.h" open="0" top="0" tabpos="21"> - <Cursor position="1311" topLine="0" /> + <File name="..\..\engines\parallaction\music.cpp" open="0" top="0" tabpos="1"> + <Cursor position="7456" topLine="265" /> </File> - <File name="..\..\engines\parallaction\parallaction.cpp" open="1" top="0" tabpos="7"> - <Cursor position="22155" topLine="929" /> + <File name="..\..\engines\parallaction\music.h" open="0" top="0" tabpos="6"> + <Cursor position="2468" topLine="45" /> </File> - <File name="..\..\engines\parallaction\parallaction.h" open="1" top="0" tabpos="14"> - <Cursor position="2196" topLine="78" /> + <File name="..\..\engines\parallaction\parallaction.cpp" open="0" top="0" tabpos="8"> + <Cursor position="6534" topLine="267" /> </File> - <File name="..\..\engines\parallaction\parser.cpp" open="0" top="0" tabpos="19"> - <Cursor position="1734" topLine="21" /> + <File name="..\..\engines\parallaction\parallaction.h" open="0" top="0" tabpos="11"> + <Cursor position="1559" topLine="78" /> </File> - <File name="..\..\engines\parallaction\parser.h" open="0" top="0" tabpos="12"> - <Cursor position="1200" topLine="9" /> + <File name="..\..\engines\parallaction\parser.cpp" open="0" top="0" tabpos="1"> + <Cursor position="3952" topLine="52" /> </File> - <File name="..\..\engines\parallaction\saveload.cpp" open="0" top="0" tabpos="10"> - <Cursor position="4740" topLine="129" /> + <File name="..\..\engines\parallaction\parser.h" open="0" top="0" tabpos="6"> + <Cursor position="1430" topLine="4" /> </File> - <File name="..\..\engines\parallaction\staticres.cpp" open="0" top="0" tabpos="1"> - <Cursor position="1069" topLine="0" /> + <File name="..\..\engines\parallaction\saveload.cpp" open="0" top="0" tabpos="16"> + <Cursor position="9837" topLine="365" /> </File> - <File name="..\..\engines\parallaction\walk.cpp" open="1" top="0" tabpos="8"> - <Cursor position="4566" topLine="154" /> + <File name="..\..\engines\parallaction\staticres.cpp" open="0" top="0" tabpos="15"> + <Cursor position="2760" topLine="59" /> </File> - <File name="..\..\engines\parallaction\walk.h" open="0" top="0" tabpos="12"> - <Cursor position="1105" topLine="0" /> + <File name="..\..\engines\parallaction\walk.cpp" open="0" top="0" tabpos="5"> + <Cursor position="4484" topLine="128" /> </File> - <File name="..\..\engines\parallaction\zone.cpp" open="1" top="0" tabpos="9"> - <Cursor position="12421" topLine="420" /> + <File name="..\..\engines\parallaction\walk.h" open="0" top="0" tabpos="2"> + <Cursor position="1668" topLine="23" /> </File> - <File name="..\..\engines\parallaction\zone.h" open="1" top="1" tabpos="1"> - <Cursor position="5008" topLine="133" /> + <File name="..\..\engines\parallaction\zone.cpp" open="0" top="0" tabpos="13"> + <Cursor position="7574" topLine="239" /> + </File> + <File name="..\..\engines\parallaction\zone.h" open="0" top="0" tabpos="14"> + <Cursor position="2831" topLine="28" /> </File> </CodeBlocks_layout_file> diff --git a/dists/codeblocks/scummvm.cbp b/dists/codeblocks/scummvm.cbp index 4dfd874890..2f111d5111 100644 --- a/dists/codeblocks/scummvm.cbp +++ b/dists/codeblocks/scummvm.cbp @@ -14,7 +14,7 @@ <Option external_deps="scummvm\engines\parallaction\libparallaction.a;scummvm\engines\agi\libagi.a;scummvm\engines\agos\libagos.a;scummvm\engines\saga\libsaga.a;scummvm\engines\lure\liblure.a;scummvm\engines\kyra\libkyra.a;" /> <Option type="1" /> <Option compiler="gcc" /> - <Option parameters="-d 9 --debugflags=location,disk,jobs,dialogue" /> + <Option parameters="-d 9 --debugflags=location,disk" /> <Option projectIncludeDirsRelation="2" /> <ResourceCompiler> <Add directory="..\..\dists" /> @@ -38,6 +38,7 @@ <Add option="-DDISABLE_SWORD1" /> <Add option="-DDISABLE_SWORD2" /> <Add option="-DDISABLE_SAGA" /> + <Add option="-DDISABLE_CRUISE" /> <Add directory="..\.." /> <Add directory="..\..\engines" /> <Add directory="..\..\common" /> @@ -383,11 +384,11 @@ <Option compilerVar="CPP" /> <Option target="default" /> </Unit> - <Unit filename="..\..\graphics\ilbm.cpp"> + <Unit filename="..\..\graphics\iff.cpp"> <Option compilerVar="CPP" /> <Option target="default" /> </Unit> - <Unit filename="..\..\graphics\ilbm.h"> + <Unit filename="..\..\graphics\iff.h"> <Option compilerVar="CPP" /> <Option compile="0" /> <Option link="0" /> diff --git a/dists/codeblocks/scummvm.depend b/dists/codeblocks/scummvm.depend index 287915b1d3..f99e51aafa 100644 --- a/dists/codeblocks/scummvm.depend +++ b/dists/codeblocks/scummvm.depend @@ -1,31 +1,13 @@ # depslib dependency file v1.0 -1164571478 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\fs\windows\windows-fs.cpp - <windows.h> +1174164454 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\events\default\default-events.cpp "common/stdafx.h" - "backends/fs/abstract-fs.h" - <stdio.h> - <stdlib.h> - <windows.h> - <tchar.h> + "common/system.h" + "backends/events/default/default-events.h" -1173387063 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\stdafx.h +1173566330 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stdafx.h <portdefs.h> - <stdio.h> - <stdlib.h> - <string.h> - <stdarg.h> - <assert.h> - <ctype.h> - <time.h> - <math.h> - <devices/timer.h> - <sys/types.h> - <sys/uio.h> - <sys/param.h> - <unistd.h> <strings.h> <stdio.h> - <fcntl.h> <stdlib.h> <string.h> <stdarg.h> @@ -34,1367 +16,50 @@ <time.h> <math.h> -1170576449 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\fs\abstract-fs.h - "common/array.h" - "common/str.h" - "common/fs.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\array.h +1177614536 c:\documents and settings\usoquotidiano\desktop\scummvm\common\system.h "common/scummsys.h" - <assert.h> + "common/mutex.h" + "common/noncopyable.h" + "common/rect.h" -1173384058 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\scummsys.h - <stdlib.h> - <stdio.h> +1178025620 c:\documents and settings\usoquotidiano\desktop\scummvm\common\scummsys.h "config.h" <SDL_byteorder.h> - "palmversion.h" "globals.h" - "extend.h" + <extras_string.h> "nds/jtypes.h" - <stdarg.h> - <ctype.h> - <string.h> - <math.h> - <time.h> - -1164571450 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\ps2\fileio.h - "common/scummsys.h" - -1171400932 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\str.h - "common/scummsys.h" - "common/array.h" - <assert.h> - <string.h> - -1173384058 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\fs.h - "common/array.h" - "common/str.h" - -1173387305 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\midi\windows.cpp - <windows.h> - <mmsystem.h> - "common/stdafx.h" - "sound/mpu401.h" - "common/util.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mpu401.h - "common/stdafx.h" - "sound/mididrv.h" - -1171653923 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mididrv.h - "common/scummsys.h" - "common/timer.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\timer.h - "common/scummsys.h" - -1172929597 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\util.h - "common/scummsys.h" - "common/str.h" - "common/array.h" - -1165164464 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\sdl\events.cpp - "backends/platform/sdl/sdl-common.h" - "common/util.h" - -1171110864 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\sdl\sdl-common.h - <SDL.h> - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "graphics/scaler.h" - "backends/intern.h" -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\system.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\mutex.h "common/scummsys.h" - "common/mutex.h" - "common/rect.h" -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\mutex.h - "common/scummsys.h" +1174136164 c:\documents and settings\usoquotidiano\desktop\scummvm\common\noncopyable.h -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\rect.h +1177701567 c:\documents and settings\usoquotidiano\desktop\scummvm\common\rect.h "common/scummsys.h" "common/util.h" -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler.h - "common/stdafx.h" - "common/scummsys.h" - "graphics/surface.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\surface.h +1177505823 c:\documents and settings\usoquotidiano\desktop\scummvm\common\util.h "common/scummsys.h" - "common/rect.h" - -1164571479 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\intern.h - "common/system.h" - -1164571444 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\sdl\graphics.cpp - "backends/platform/sdl/sdl-common.h" - "common/util.h" - "graphics/font.h" - "graphics/fontman.h" - "graphics/scaler.h" - "graphics/surface.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\font.h - "common/str.h" - "graphics/surface.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\fontman.h - "common/stdafx.h" - "common/scummsys.h" - "common/singleton.h" - "common/str.h" - "common/hashmap.h" - "common/hash-str.h" - "graphics/font.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\singleton.h - -1173025754 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\hashmap.h - "common/stdafx.h" - "common/func.h" - "common/str.h" - "common/util.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\func.h - "common/scummsys.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\hash-str.h - "common/hashmap.h" - "common/str.h" - -1173387330 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\sdl\sdl.cpp - "backends/platform/sdl/sdl-common.h" - "backends/plugins/sdl/sdl-provider.h" - "common/config-manager.h" - "common/util.h" - "base/main.h" - "backends/saves/default/default-saves.h" - "backends/timer/default/default-timer.h" - "sound/mixer.h" - "icons/scummvm.xpm" - "SymbianOs.h" - <windows.h> - -1164571437 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\plugins\sdl\sdl-provider.h - "common/stdafx.h" - "base/plugins.h" - -1169328812 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\plugins.h - "common/stdafx.h" - "common/array.h" - "common/list.h" - "common/singleton.h" - "common/util.h" - "base/game.h" - -1172690841 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\list.h - "common/scummsys.h" - <assert.h> - -1170187002 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\game.h - "common/stdafx.h" "common/str.h" "common/array.h" - "common/hash-str.h" - -1173384058 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\config-manager.h - "common/array.h" - "common/hashmap.h" - "common/singleton.h" - "common/str.h" - "common/hash-str.h" - -1164571436 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\main.h - "common/scummsys.h" - -1164571437 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\saves\default\default-saves.h - "common/stdafx.h" - "common/savefile.h" - -1171788214 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\savefile.h - "common/stdafx.h" - "common/scummsys.h" - "common/stream.h" - -1173025754 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\stream.h - "common/stdafx.h" - "common/scummsys.h" - -1164571436 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\timer\default\default-timer.h - "common/timer.h" - "common/mutex.h" - -1172866046 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mixer.h - "common/stdafx.h" - "common/scummsys.h" - "common/mutex.h" - -1164571480 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\icons\scummvm.xpm - -1171877633 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\saves\compressed\compressed-saves.cpp - "common/stdafx.h" - "common/savefile.h" - "common/util.h" - "backends/saves/compressed/compressed-saves.h" - <zlib.h> - -1171788215 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\saves\compressed\compressed-saves.h - "common/stdafx.h" - "common/savefile.h" - -1171788215 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\saves\default\default-saves.cpp - "common/stdafx.h" - "common/savefile.h" - "common/util.h" - "backends/saves/default/default-saves.h" - "backends/saves/compressed/compressed-saves.h" - <stdio.h> - <string.h> - <errno.h> - <sys/stat.h> - -1164571437 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\saves\savefile.cpp - "common/stdafx.h" - "common/util.h" - "common/config-manager.h" - "common/savefile.h" - <stdio.h> - <string.h> - -1169844668 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\timer\default\default-timer.cpp - "common/stdafx.h" - "common/scummsys.h" - "backends/timer/default/default-timer.h" - "common/util.h" - "common/system.h" - -1172929597 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\commandline.cpp - "common/stdafx.h" - "engines/engine.h" - "base/commandLine.h" - "base/plugins.h" - "base/version.h" - "common/config-manager.h" - "common/system.h" - "sound/mididrv.h" - "sound/mixer.h" - "common/fs.h" - -1164571397 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\engines\engine.h - "common/stdafx.h" - "common/scummsys.h" - "common/str.h" - -1164571436 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\commandline.h - "common/str.h" - "common/config-manager.h" - -1164571436 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\version.h - -1170792000 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\game.cpp - "base/game.h" - "base/plugins.h" - -1172866046 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\main.cpp - "common/stdafx.h" - "engines/engine.h" - "base/commandLine.h" - "base/plugins.h" - "base/version.h" - "common/config-manager.h" - "common/file.h" - "common/fs.h" - "common/system.h" - "gui/newgui.h" - "gui/message.h" - "backends/platform/wince/CELauncherDialog.h" - "backends/platform/dc/DCLauncherDialog.h" - "gui/launcher.h" - "args.h" - -1173384058 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\file.h - "common/stdafx.h" - "common/scummsys.h" - "common/str.h" - "common/stream.h" -1171110863 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\newgui.h +1176747595 c:\documents and settings\usoquotidiano\desktop\scummvm\common\str.h "common/scummsys.h" - "common/singleton.h" - "common/stack.h" - "common/str.h" - "graphics/fontman.h" - "gui/theme.h" - "gui/widget.h" - -1171826383 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\stack.h - "common/scummsys.h" - <assert.h> "common/array.h" -1171405441 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\theme.h - "common/stdafx.h" - "common/system.h" - "common/rect.h" - "common/str.h" - "common/file.h" - "common/config-file.h" - "graphics/surface.h" - "graphics/fontman.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\config-file.h - "common/config-manager.h" - "common/list.h" - "common/str.h" - "common/stream.h" - -1170576438 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\widget.h - "common/scummsys.h" - "common/str.h" - "graphics/font.h" - "graphics/surface.h" - "gui/object.h" - -1171309680 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\object.h - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\message.h - "gui/dialog.h" - "common/str.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\dialog.h +1173788771 c:\documents and settings\usoquotidiano\desktop\scummvm\common\array.h "common/scummsys.h" - "common/str.h" - "gui/object.h" - "gui/widget.h" - -1170576449 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\wince\celauncherdialog.h - "base/plugins.h" - "common/fs.h" - "gui/launcher.h" -1171826383 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\launcher.h - "gui/dialog.h" - "common/str.h" - -1164571454 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\dc\dclauncherdialog.h - -1170922364 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\plugins.cpp - "base/plugins.h" - "common/util.h" - -1164571436 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\version.cpp - "common/stdafx.h" - "common/scummsys.h" - "base/internal_version.h" - "base/version.h" - "backends/platform/symbian/src/main_features.inl" - -1164571436 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\base\internal_version.h - -1167415214 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\symbian\src\main_features.inl - -1171826383 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\advanceddetector.cpp +1174164454 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\events\default\default-events.h "common/stdafx.h" - "base/plugins.h" - "common/util.h" - "common/hash-str.h" - "common/file.h" - "common/md5.h" - "common/advancedDetector.h" - "common/config-manager.h" - -1171527697 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\md5.h - "common/scummsys.h" - "common/fs.h" - "common/stream.h" - -1171527697 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\advanceddetector.h - "common/fs.h" - "base/game.h" - "base/plugins.h" - -1171400932 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\config-file.cpp - "common/stdafx.h" - "common/config-file.h" - "common/file.h" - "common/savefile.h" - "common/system.h" - "common/util.h" - -1173387285 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\config-manager.cpp - "common/stdafx.h" - "common/config-manager.h" - "common/file.h" - "common/util.h" - <windows.h> - "backends/platform/ps2/systemps2.h" - -1164571450 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\ps2\systemps2.h - "common/stdafx.h" - "common/system.h" - -1173384058 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\file.cpp - "common/file.h" - "common/fs.h" - "common/hashmap.h" - "common/util.h" - "common/hash-str.h" - "CoreFoundation/CoreFoundation.h" - "backends/platform/ps2/fileio.h" - -1170576446 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\fs.cpp - "common/stdafx.h" - "backends/fs/abstract-fs.h" - "common/util.h" - -1164571400 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\hashmap.cpp - "common/hashmap.h" - <ctype.h> - -1171527697 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\md5.cpp - <string.h> - "common/file.h" - "common/md5.h" - "common/util.h" - "common/endian.h" - <stdlib.h> - <stdio.h> - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\endian.h - "common/scummsys.h" - -1164571400 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\mutex.cpp - "common/stdafx.h" - "common/mutex.h" - "common/system.h" - -1171400932 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\str.cpp - "common/stdafx.h" - "common/str.h" - "common/hash-str.h" - "common/util.h" - <ctype.h> - -1172012045 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\stream.cpp - "common/stdafx.h" - "common/stream.h" - "common/str.h" - "common/util.h" - -1164571400 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\system.cpp - "common/stdafx.h" - "backends/intern.h" - "gui/message.h" - "common/config-manager.h" - "common/system.h" - "common/timer.h" - "common/util.h" - "sound/mixer.h" - -1171826383 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\unzip.cpp - "common/stdafx.h" - "common/scummsys.h" - <stdio.h> - <stdlib.h> - <string.h> - <zlib.h> - "common/unzip.h" - "common/file.h" - <stddef.h> - <string.h> - <stdlib.h> - <errno.h> - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\unzip.h - "common/stdafx.h" - "common/scummsys.h" - <zlib.h> - -1173384058 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\util.cpp - "common/stdafx.h" - "engines/engine.h" - "common/util.h" - "common/system.h" - "gui/debugger.h" - "backends/platform/ps2/fileio.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\debugger.h - -1172012044 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\engines\engine.cpp - "common/stdafx.h" - "engines/engine.h" - "common/config-manager.h" - "common/file.h" - "common/timer.h" - "common/savefile.h" - "common/system.h" - "gui/message.h" - "sound/mixer.h" - -1171307211 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\cursorman.cpp - "graphics/cursorman.h" - "common/system.h" - "common/stack.h" - -1171307211 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\cursorman.h - "common/stdafx.h" - "common/scummsys.h" - "common/stack.h" - "common/singleton.h" - -1170576447 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\dxa_player.cpp - "common/stdafx.h" - "common/endian.h" - "graphics/dxa_player.h" - "common/util.h" - <zlib.h> - -1167415212 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\dxa_player.h - "common/scummsys.h" - "common/file.h" - -1173384058 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\font.cpp - "common/stdafx.h" - "common/stream.h" - "common/file.h" - "common/endian.h" - "graphics/font.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\fontman.cpp - "graphics/fontman.h" - -1164571409 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\fonts\consolefont.cpp - "common/stdafx.h" - "graphics/font.h" - -1164571409 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\fonts\newfont.cpp - "common/stdafx.h" - "graphics/font.h" - -1164571409 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\fonts\newfont_big.cpp - "common/stdafx.h" - "graphics/font.h" - -1164571409 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\fonts\scummfont.cpp - "common/stdafx.h" - "graphics/font.h" - "scumm_globals.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\ilbm.cpp - "common/stdafx.h" - "common/endian.h" - "common/stream.h" - "graphics/surface.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\imagedec.cpp - "graphics/imagedec.h" - "common/system.h" - "common/file.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\imagedec.h - "common/stdafx.h" - "common/scummsys.h" - "common/str.h" - "common/stream.h" - "graphics/surface.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\imageman.cpp - "graphics/imagedec.h" - "graphics/imageman.h" - "graphics/surface.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\imageman.h - "common/stdafx.h" - "common/scummsys.h" - "common/singleton.h" - "common/str.h" - "common/list.h" - "common/unzip.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\primitives.cpp - "common/stdafx.h" - "common/util.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler.cpp - "graphics/scaler/intern.h" - "graphics/scaler/scalebit.h" - "common/util.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\intern.h - "common/stdafx.h" - "common/scummsys.h" - "graphics/colormasks.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\colormasks.h - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\scalebit.h - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\2xsai.cpp - "graphics/scaler/intern.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\aspect.cpp - "graphics/scaler/intern.h" - "graphics/scaler.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\hq2x.cpp - "graphics/scaler/intern.h" - "graphics/scaler/hq2x.h" - "graphics/scaler/hq2x.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\hq2x.h - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\hq3x.cpp - "graphics/scaler/intern.h" - "graphics/scaler/hq3x.h" - "graphics/scaler/hq3x.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\hq3x.h - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\scale2x.cpp - "common/stdafx.h" - "common/scummsys.h" - "graphics/scaler/intern.h" - "graphics/scaler/scale2x.h" - <assert.h> - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\scale2x.h - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\scale3x.cpp - "common/stdafx.h" - "common/scummsys.h" - "graphics/scaler/intern.h" - "graphics/scaler/scale3x.h" - <assert.h> - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\scale3x.h - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\scalebit.cpp - "common/stdafx.h" - "common/scummsys.h" - "graphics/scaler/intern.h" - "graphics/scaler/scale2x.h" - "graphics/scaler/scale3x.h" - <alloca.h> - <assert.h> - <stdlib.h> - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\scaler\thumbnail.cpp - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "graphics/scaler.h" - "graphics/scaler/intern.h" - -1164571411 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\surface.cpp - "common/stdafx.h" - "common/util.h" - "graphics/primitives.h" - "graphics/surface.h" - -1164571411 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\graphics\primitives.h - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\actions.cpp - "common/stdafx.h" - "gui/Actions.h" - "gui/message.h" - "scumm/scumm.h" - "common/config-manager.h" - "backends/platform/wince/CEActionsPocket.h" - "backends/platform/wince/CEActionsSmartphone.h" - "backends/platform/symbian/src/SymbianActions.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\actions.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "gui/Key.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\key.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - -1172345868 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\engines\scumm\scumm.h - "engines/engine.h" - "common/endian.h" - "common/file.h" - "common/rect.h" - "common/str.h" - "graphics/surface.h" - "scumm/gfx.h" - "scumm/plugin.h" - "scumm/script.h" - "sound/mididrv.h" - -1171911145 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\engines\scumm\gfx.h - "graphics/surface.h" - -1171527695 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\engines\scumm\plugin.h - "common/util.h" - -1171911145 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\engines\scumm\script.h - "engines/engine.h" - -1164571453 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\wince\ceactionspocket.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "wince-sdl.h" - "gui/Key.h" - "gui/Actions.h" - -1171307212 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\wince\wince-sdl.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "graphics/scaler.h" - "backends/intern.h" - "backends/platform/sdl/sdl-common.h" - "CEGUI.h" - "CEKeys.h" - "CEDevice.h" - "CEScaler.h" - <SDL.h> - -1164571453 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\wince\cedevice.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "common/str.h" - -1164571453 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\wince\cescaler.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "graphics/scaler.h" - "graphics/scaler/intern.h" - -1164571453 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\wince\ceactionssmartphone.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "wince-sdl.h" - "gui/Key.h" - "gui/Actions.h" - -1164571445 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\backends\platform\symbian\src\symbianactions.h - "common/stdafx.h" - "common/scummsys.h" - "common/system.h" - "gui/Key.h" - "gui/Actions.h" - -1169400236 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\edittextwidget.cpp - "common/stdafx.h" - "gui/EditTextWidget.h" - "gui/dialog.h" - "gui/eval.h" - "gui/newgui.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\edittextwidget.h - "gui/editable.h" - "common/str.h" + "common/events.h" -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\editable.h - "common/str.h" +1174164453 c:\documents and settings\usoquotidiano\desktop\scummvm\common\events.h "common/rect.h" - "gui/widget.h" - "gui/newgui.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\eval.h - "common/stdafx.h" - "common/str.h" - "common/hashmap.h" - "common/hash-str.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\key.cpp - "common/stdafx.h" - "gui/Key.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\listwidget.cpp - "common/stdafx.h" - "common/system.h" - "gui/ListWidget.h" - "gui/ScrollBarWidget.h" - "gui/dialog.h" - "gui/eval.h" - "gui/newgui.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\listwidget.h - "gui/editable.h" - "common/str.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\scrollbarwidget.h - "gui/widget.h" - -1172567053 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\popupwidget.cpp - "common/stdafx.h" - "common/system.h" - "gui/dialog.h" - "gui/eval.h" - "gui/newgui.h" - "gui/PopUpWidget.h" - "engines/engine.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\popupwidget.h - "gui/widget.h" - "common/str.h" - "common/array.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\scrollbarwidget.cpp - "common/stdafx.h" - "ScrollBarWidget.h" - "gui/dialog.h" - "gui/newgui.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\tabwidget.cpp - "common/stdafx.h" - "common/util.h" - "gui/TabWidget.h" - "gui/dialog.h" - "gui/newgui.h" - "gui/eval.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\tabwidget.h - "widget.h" - "common/str.h" - "common/array.h" - -1171110863 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\themeclassic.cpp - "gui/ThemeClassic.h" - "gui/eval.h" - -1171110863 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\themeclassic.h - "gui/theme.h" - -1172605215 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\thememodern.cpp - "gui/ThemeModern.h" - "gui/eval.h" - "graphics/imageman.h" - "graphics/imagedec.h" - "graphics/colormasks.h" - "graphics/cursorman.h" - "common/config-manager.h" - "common/file.h" - -1171110863 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\thememodern.h - "gui/theme.h" - -1171110863 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\about.cpp - "common/stdafx.h" - "engines/engine.h" - "base/plugins.h" - "base/version.h" - "common/system.h" - "common/util.h" - "gui/about.h" - "gui/eval.h" - "gui/newgui.h" - "gui/widget.h" - "gui/credits.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\about.h - "gui/dialog.h" - "common/str.h" - "graphics/surface.h" - -1171653915 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\credits.h - -1168167088 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\browser.cpp - "common/stdafx.h" - "gui/browser.h" - "gui/newgui.h" - "gui/ListWidget.h" - "common/config-manager.h" - "common/fs.h" - "common/system.h" - "common/func.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\browser.h - "gui/dialog.h" - "common/str.h" - "common/fs.h" - <Carbon/Carbon.h> - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\chooser.cpp - "common/stdafx.h" - "common/system.h" - "gui/chooser.h" - "gui/newgui.h" - "gui/ListWidget.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\chooser.h - "common/str.h" - "gui/dialog.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\console.cpp - "common/stdafx.h" - "gui/console.h" - "gui/ScrollBarWidget.h" - "gui/eval.h" - "engines/engine.h" - "base/version.h" - "common/system.h" - "graphics/font.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\console.h - "gui/dialog.h" - "gui/newgui.h" - <stdarg.h> - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\debugger.cpp - "common/stdafx.h" - "common/system.h" - "gui/debugger.h" - "gui/console.h" - -1167415200 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\dialog.cpp - "common/stdafx.h" - "gui/newgui.h" - "gui/dialog.h" - "gui/widget.h" - "gui/PopUpWidget.h" - "common/system.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\editable.cpp - "common/stdafx.h" - "gui/editable.h" - "gui/newgui.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\eval.cpp - "common/stdafx.h" - "common/system.h" - "gui/eval.h" - "gui/widget.h" - "gui/newgui.h" - "graphics/scaler.h" - -1171826383 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\launcher.cpp - "common/stdafx.h" - "engines/engine.h" - "base/game.h" - "base/plugins.h" - "base/version.h" - "common/config-manager.h" - "common/fs.h" - "common/util.h" - "common/system.h" - "gui/about.h" - "gui/browser.h" - "gui/chooser.h" - "gui/eval.h" - "gui/launcher.h" - "gui/massadd.h" - "gui/message.h" - "gui/newgui.h" - "gui/options.h" - "gui/EditTextWidget.h" - "gui/ListWidget.h" - "gui/TabWidget.h" - "gui/PopUpWidget.h" - "sound/mididrv.h" - -1171826383 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\massadd.h - "gui/dialog.h" - "common/fs.h" - "common/stack.h" - -1171400932 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\options.h - "gui/dialog.h" - "common/str.h" - "gui/KeysDialog.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\keysdialog.h - "gui/newgui.h" - "gui/dialog.h" - "gui/ListWidget.h" - "common/str.h" - -1171826383 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\massadd.cpp - "common/stdafx.h" - "engines/engine.h" - "base/game.h" - "base/plugins.h" - "gui/launcher.h" - "gui/massadd.h" - "gui/newgui.h" - "gui/widget.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\message.cpp - "common/stdafx.h" - "common/str.h" - "common/system.h" - "gui/message.h" - "gui/newgui.h" - "gui/widget.h" - -1171307210 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\newgui.cpp - "common/stdafx.h" - "common/system.h" - "common/util.h" - "graphics/cursorman.h" - "gui/newgui.h" - "gui/dialog.h" - "gui/eval.h" - "gui/ThemeModern.h" - "gui/ThemeClassic.h" - "common/config-manager.h" - -1173384058 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\options.cpp - "common/stdafx.h" - "gui/browser.h" - "gui/themebrowser.h" - "gui/chooser.h" - "gui/eval.h" - "gui/newgui.h" - "gui/options.h" - "gui/PopUpWidget.h" - "gui/TabWidget.h" - "common/fs.h" - "common/config-manager.h" "common/system.h" - "graphics/scaler.h" - "sound/mididrv.h" - "sound/mixer.h" - -1164571274 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\themebrowser.h - "gui/dialog.h" - "common/str.h" - "common/fs.h" - "common/array.h" - -1171400932 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\theme-config.cpp - "gui/theme.h" - "gui/eval.h" - -1170576438 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\theme.cpp - "gui/theme.h" - "gui/eval.h" - "common/unzip.h" - -1164571274 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\themebrowser.cpp - "common/stdafx.h" - "gui/themebrowser.h" - "gui/ListWidget.h" - "gui/widget.h" - "gui/theme.h" - "common/fs.h" - "CoreFoundation/CoreFoundation.h" - -1170576438 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\gui\widget.cpp - "common/stdafx.h" - "common/util.h" - "graphics/fontman.h" - "gui/widget.h" - "gui/dialog.h" - "gui/eval.h" - "gui/newgui.h" - -1164571405 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\adpcm.cpp - "common/stdafx.h" - "common/endian.h" - "sound/adpcm.h" - "sound/audiostream.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\adpcm.h - "common/stdafx.h" - "common/scummsys.h" - "common/stream.h" - -1172866046 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\audiostream.h - "common/stdafx.h" - "common/util.h" - "common/scummsys.h" - -1172389580 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\audiocd.cpp - "common/stdafx.h" - "sound/audiocd.h" - "sound/mp3.h" - "sound/vorbis.h" - "sound/flac.h" - "engines/engine.h" - "common/file.h" - "common/util.h" - "common/system.h" - -1172389580 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\audiocd.h - "common/stdafx.h" - "common/scummsys.h" - "common/singleton.h" - "sound/mixer.h" - -1172012046 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mp3.h - "common/stdafx.h" - "common/scummsys.h" - -1172305644 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\vorbis.h - "common/stdafx.h" - "common/scummsys.h" - -1172305644 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\flac.h - "common/stdafx.h" - "common/scummsys.h" - -1172866046 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\audiostream.cpp - "common/stdafx.h" - "common/endian.h" - "common/file.h" - "common/list.h" - "common/util.h" - "sound/audiostream.h" - "sound/mixer.h" - "sound/mp3.h" - "sound/vorbis.h" - "sound/flac.h" - -1173025754 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\flac.cpp - "sound/flac.h" - "common/file.h" - "common/util.h" - "sound/audiostream.h" - "sound/audiocd.h" - <FLAC/export.h> - <FLAC/seekable_stream_decoder.h> - <FLAC/stream_decoder.h> - -1165164464 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\fmopl.cpp - "common/stdafx.h" - <stdio.h> - <stdlib.h> - <string.h> - <stdarg.h> - <math.h> - "sound/fmopl.h" - "common/util.h" - "common/config-manager.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\fmopl.h - "common/scummsys.h" - -1164571405 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mididrv.cpp - "common/stdafx.h" - "engines/engine.h" - "common/config-manager.h" - "common/str.h" - "common/system.h" - "common/util.h" - "sound/mididrv.h" - -1171653923 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\midiparser.cpp - "common/stdafx.h" - "sound/midiparser.h" - "sound/mididrv.h" - "common/util.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\midiparser.h - "common/scummsys.h" - "common/endian.h" - -1171826383 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\midiparser_smf.cpp - "common/stdafx.h" - "sound/midiparser.h" - "sound/mididrv.h" - "common/util.h" - -1171653923 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\midiparser_xmidi.cpp - "common/stdafx.h" - "sound/midiparser.h" - "sound/mididrv.h" - "common/util.h" - -1172866046 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mixer.cpp - "common/stdafx.h" - "common/file.h" - "common/util.h" - "common/system.h" - "sound/mixer.h" - "sound/rate.h" - "sound/audiostream.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\rate.h - "common/scummsys.h" - "engines/engine.h" - -1172389580 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mp3.cpp - "sound/mp3.h" - "common/file.h" - "common/util.h" - "sound/audiocd.h" - "sound/audiostream.h" - <mad.h> - -1164571405 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\mpu401.cpp - "common/stdafx.h" - "sound/mpu401.h" - "common/system.h" - "common/timer.h" - "common/util.h" - -1164571405 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\null.cpp - "common/stdafx.h" - "sound/mpu401.h" - -1172174660 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\rate.cpp - "common/stdafx.h" - "sound/audiostream.h" - "sound/rate.h" - "sound/mixer.h" - "common/util.h" - -1172012045 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\adlib.cpp - "sound/softsynth/emumidi.h" - "common/util.h" - "sound/fmopl.h" - -1172012045 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\emumidi.h - "common/stdafx.h" - "sound/audiostream.h" - "sound/mididrv.h" - "sound/mixer.h" - -1164571405 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\fluidsynth.cpp - "common/stdafx.h" - "common/scummsys.h" - "common/stdafx.h" - "common/config-manager.h" - "sound/mpu401.h" - "sound/softsynth/emumidi.h" - <fluidsynth.h> - -1164571405 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32.cpp - "common/stdafx.h" - "common/scummsys.h" - "sound/softsynth/mt32/mt32emu.h" - "sound/softsynth/emumidi.h" - "sound/mpu401.h" - "common/util.h" - "common/file.h" - "common/config-manager.h" - "common/system.h" - "graphics/fontman.h" - "graphics/surface.h" - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\mt32emu.h - "freeverb.h" - "structures.h" - "i386.h" - "mt32_file.h" - "tables.h" - "partial.h" - "partialManager.h" - "part.h" - "synth.h" - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\freeverb.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\structures.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\i386.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\mt32_file.h - <stdio.h> - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\tables.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\partial.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\partialmanager.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\part.h - -1164571404 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\synth.h - <stdarg.h> - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\freeverb.cpp - "common/stdafx.h" - "sound/softsynth/mt32/freeverb.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\i386.cpp - "mt32emu.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\mt32_file.cpp - <stdio.h> - "mt32emu.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\part.cpp - <string.h> - <math.h> - "mt32emu.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\partial.cpp - <stdlib.h> - <math.h> - <string.h> - "mt32emu.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\partialmanager.cpp - <string.h> - "mt32emu.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\synth.cpp - <math.h> - <string.h> - <stdlib.h> - "mt32emu.h" - -1164571404 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\mt32\tables.cpp - <stdlib.h> - <string.h> - <math.h> - "mt32emu.h" - -1172012045 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\softsynth\ym2612.cpp - "sound/softsynth/emumidi.h" - <math.h> - "common/util.h" - -1172866046 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\voc.cpp - "common/stdafx.h" - "common/endian.h" - "common/util.h" - "common/stream.h" - "sound/audiostream.h" - "sound/mixer.h" - "sound/voc.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\voc.h - "common/stdafx.h" - "common/scummsys.h" - "common/pack-start.h" - "common/pack-end.h" - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\pack-start.h - -1164571400 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\common\pack-end.h - -1172389580 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\vorbis.cpp - "sound/vorbis.h" - "common/file.h" - "common/util.h" - "sound/audiostream.h" - "sound/audiocd.h" - <ivorbisfile.h> - <tremor/ivorbisfile.h> - <vorbis/vorbisfile.h> - -1172866046 source:c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\wave.cpp - "common/stdafx.h" - "common/util.h" - "common/stream.h" - "sound/audiostream.h" - "sound/mixer.h" - "sound/wave.h" - "sound/adpcm.h" - -1164571405 c:\documents and settings\usoquotidiano\documenti\soft\scummvm\scummvm\sound\wave.h - "common/stdafx.h" - "common/scummsys.h" + "common/noncopyable.h" -1173398975 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\fs\windows\windows-fs.cpp +1173402575 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\fs\windows\windows-fs.cpp <windows.h> "common/stdafx.h" "backends/fs/abstract-fs.h" @@ -1403,71 +68,40 @@ <windows.h> <tchar.h> -1173562730 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stdafx.h - <portdefs.h> - <strings.h> - <stdio.h> - <stdlib.h> - <string.h> - <stdarg.h> - <assert.h> - <ctype.h> - <time.h> - <math.h> - -1173398976 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\fs\abstract-fs.h +1173402576 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\fs\abstract-fs.h "common/array.h" "common/str.h" "common/fs.h" -1173785171 c:\documents and settings\usoquotidiano\desktop\scummvm\common\array.h - "common/scummsys.h" - -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\scummsys.h - "config.h" - <SDL_byteorder.h> - "palmversion.h" - "globals.h" - "extend.h" - "nds/jtypes.h" - -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\str.h - "common/scummsys.h" - "common/array.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\fs.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\fs.h "common/array.h" "common/str.h" -1173399217 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\midi\windows.cpp +1173402817 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\midi\windows.cpp <windows.h> <mmsystem.h> "common/stdafx.h" "sound/mpu401.h" "common/util.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mpu401.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mpu401.h "common/stdafx.h" "sound/mididrv.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mididrv.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mididrv.h "common/scummsys.h" "common/timer.h" -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\timer.h +1174136164 c:\documents and settings\usoquotidiano\desktop\scummvm\common\timer.h "common/scummsys.h" "common/noncopyable.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\util.h - "common/scummsys.h" - "common/str.h" - "common/array.h" - -1173398934 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\events.cpp +1175021323 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\events.cpp "backends/platform/sdl/sdl-common.h" "common/util.h" + "common/events.h" -1173398934 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\sdl-common.h +1177614537 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\sdl-common.h <SDL.h> "common/stdafx.h" "common/scummsys.h" @@ -1475,32 +109,19 @@ "graphics/scaler.h" "backends/intern.h" -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\system.h - "common/scummsys.h" - "common/mutex.h" - "common/noncopyable.h" - "common/rect.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\mutex.h - "common/scummsys.h" - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\rect.h - "common/scummsys.h" - "common/util.h" - -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler.h +1173402496 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler.h "common/stdafx.h" "common/scummsys.h" "graphics/surface.h" -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\surface.h +1173402496 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\surface.h "common/scummsys.h" "common/rect.h" -1173398976 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\intern.h +1173402576 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\intern.h "common/system.h" -1173398934 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\graphics.cpp +1174164455 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\graphics.cpp "backends/platform/sdl/sdl-common.h" "common/util.h" "graphics/font.h" @@ -1508,11 +129,11 @@ "graphics/scaler.h" "graphics/surface.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\font.h +1177614536 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\font.h "common/str.h" "graphics/surface.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fontman.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fontman.h "common/stdafx.h" "common/scummsys.h" "common/singleton.h" @@ -1521,23 +142,24 @@ "common/hash-str.h" "graphics/font.h" -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\singleton.h +1174136164 c:\documents and settings\usoquotidiano\desktop\scummvm\common\singleton.h "common/noncopyable.h" -1173785171 c:\documents and settings\usoquotidiano\desktop\scummvm\common\hashmap.h +1173788771 c:\documents and settings\usoquotidiano\desktop\scummvm\common\hashmap.h "common/stdafx.h" "common/func.h" "common/str.h" "common/util.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\func.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\func.h "common/scummsys.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\hash-str.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\hash-str.h "common/hashmap.h" "common/str.h" -1173399217 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\sdl.cpp +1174157119 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\sdl\sdl.cpp + <windows.h> "backends/platform/sdl/sdl-common.h" "backends/plugins/sdl/sdl-provider.h" "common/config-manager.h" @@ -1547,14 +169,13 @@ "backends/timer/default/default-timer.h" "sound/mixer.h" "icons/scummvm.xpm" - <windows.h> "SymbianOs.h" -1173398926 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\plugins\sdl\sdl-provider.h +1173402526 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\plugins\sdl\sdl-provider.h "common/stdafx.h" "base/plugins.h" -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\plugins.h +1173402525 c:\documents and settings\usoquotidiano\desktop\scummvm\base\plugins.h "common/stdafx.h" "common/array.h" "common/list.h" @@ -1562,62 +183,62 @@ "common/util.h" "base/game.h" -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\list.h +1173537096 c:\documents and settings\usoquotidiano\desktop\scummvm\common\list.h "common/scummsys.h" -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\game.h +1173402525 c:\documents and settings\usoquotidiano\desktop\scummvm\base\game.h "common/stdafx.h" "common/str.h" "common/array.h" "common/hash-str.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-manager.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-manager.h "common/array.h" "common/hashmap.h" "common/singleton.h" "common/str.h" "common/hash-str.h" -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\main.h +1173402525 c:\documents and settings\usoquotidiano\desktop\scummvm\base\main.h "common/scummsys.h" -1174117753 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\default\default-saves.h +1174121353 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\default\default-saves.h "common/stdafx.h" "common/savefile.h" -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\savefile.h +1174136164 c:\documents and settings\usoquotidiano\desktop\scummvm\common\savefile.h "common/stdafx.h" "common/noncopyable.h" "common/scummsys.h" "common/stream.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stream.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stream.h "common/stdafx.h" "common/scummsys.h" -1173398926 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\timer\default\default-timer.h +1173402526 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\timer\default\default-timer.h "common/timer.h" "common/mutex.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mixer.h +1177614536 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mixer.h "common/stdafx.h" "common/scummsys.h" "common/mutex.h" -1173398977 c:\documents and settings\usoquotidiano\desktop\scummvm\icons\scummvm.xpm +1173402577 c:\documents and settings\usoquotidiano\desktop\scummvm\icons\scummvm.xpm -1173641251 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\compressed\compressed-saves.cpp +1173644851 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\compressed\compressed-saves.cpp "common/stdafx.h" "common/savefile.h" "common/util.h" "backends/saves/compressed/compressed-saves.h" <zlib.h> -1173398926 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\compressed\compressed-saves.h +1173402526 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\compressed\compressed-saves.h "common/stdafx.h" "common/savefile.h" -1174117753 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\default\default-saves.cpp +1174121353 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\default\default-saves.cpp "common/stdafx.h" "common/savefile.h" "common/util.h" @@ -1628,7 +249,7 @@ <errno.h> <sys/stat.h> -1173398926 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\savefile.cpp +1173402526 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\saves\savefile.cpp "common/stdafx.h" "common/util.h" "common/config-manager.h" @@ -1636,14 +257,14 @@ <stdio.h> <string.h> -1173398925 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\timer\default\default-timer.cpp +1173402525 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\timer\default\default-timer.cpp "common/stdafx.h" "common/scummsys.h" "backends/timer/default/default-timer.h" "common/util.h" "common/system.h" -1173567046 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\commandline.cpp +1173570646 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\commandline.cpp "common/stdafx.h" "engines/engine.h" "base/commandLine.h" @@ -1655,22 +276,22 @@ "sound/mixer.h" "common/fs.h" -1173398879 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\engine.h +1175450743 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\engine.h "common/stdafx.h" "common/scummsys.h" "common/str.h" -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\commandline.h +1173402525 c:\documents and settings\usoquotidiano\desktop\scummvm\base\commandline.h "common/str.h" "common/config-manager.h" -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\version.h +1173402525 c:\documents and settings\usoquotidiano\desktop\scummvm\base\version.h -1173398925 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\game.cpp +1173402525 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\game.cpp "base/game.h" "base/plugins.h" -1173398925 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\main.cpp +1177095928 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\main.cpp "common/stdafx.h" "engines/engine.h" "base/commandLine.h" @@ -1687,13 +308,13 @@ "gui/launcher.h" "args.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\file.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\file.h "common/stdafx.h" "common/scummsys.h" "common/str.h" "common/stream.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\newgui.h +1174157116 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\newgui.h "common/scummsys.h" "common/singleton.h" "common/stack.h" @@ -1702,11 +323,11 @@ "gui/theme.h" "gui/widget.h" -1173533496 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stack.h +1173537096 c:\documents and settings\usoquotidiano\desktop\scummvm\common\stack.h "common/scummsys.h" "common/array.h" -1173562730 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme.h +1177614532 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme.h "common/stdafx.h" "common/system.h" "common/rect.h" @@ -1716,58 +337,58 @@ "graphics/surface.h" "graphics/fontman.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-file.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-file.h "common/config-manager.h" "common/list.h" "common/str.h" "common/stream.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\widget.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\widget.h "common/scummsys.h" "common/str.h" "graphics/font.h" "graphics/surface.h" "gui/object.h" -1174117751 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\object.h +1174121351 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\object.h -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\message.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\message.h "gui/dialog.h" "common/str.h" -1174117751 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\dialog.h +1176747594 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\dialog.h "common/scummsys.h" "common/str.h" "gui/object.h" "gui/widget.h" -1173398947 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\celauncherdialog.h +1173402547 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\celauncherdialog.h "base/plugins.h" "common/fs.h" "gui/launcher.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\launcher.h +1174157116 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\launcher.h "gui/dialog.h" "common/str.h" -1173398948 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\dc\dclauncherdialog.h +1173402548 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\dc\dclauncherdialog.h -1173906517 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\plugins.cpp +1177701568 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\plugins.cpp "base/plugins.h" "common/util.h" -1173398925 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\version.cpp +1173402525 source:c:\documents and settings\usoquotidiano\desktop\scummvm\base\version.cpp "common/stdafx.h" "common/scummsys.h" "base/internal_version.h" "base/version.h" "backends/platform/symbian/src/main_features.inl" -1173398925 c:\documents and settings\usoquotidiano\desktop\scummvm\base\internal_version.h +1173402525 c:\documents and settings\usoquotidiano\desktop\scummvm\base\internal_version.h -1173398935 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\symbian\src\main_features.inl +1173402535 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\symbian\src\main_features.inl -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\advanceddetector.cpp +1177701567 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\advanceddetector.cpp "common/stdafx.h" "base/plugins.h" "common/util.h" @@ -1777,17 +398,17 @@ "common/advancedDetector.h" "common/config-manager.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\md5.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\md5.h "common/scummsys.h" "common/fs.h" "common/stream.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\advanceddetector.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\advanceddetector.h "common/fs.h" "base/game.h" "base/plugins.h" -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-file.cpp +1173402482 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-file.cpp "common/stdafx.h" "common/config-file.h" "common/file.h" @@ -1795,19 +416,19 @@ "common/system.h" "common/util.h" -1173399217 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-manager.cpp +1174157118 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\config-manager.cpp + <windows.h> "common/stdafx.h" "common/config-manager.h" "common/file.h" "common/util.h" - <windows.h> "backends/platform/ps2/systemps2.h" -1173398943 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\ps2\systemps2.h +1174164456 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\ps2\systemps2.h "common/stdafx.h" "common/system.h" -1173641249 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\file.cpp +1175936376 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\file.cpp "common/file.h" "common/fs.h" "common/hashmap.h" @@ -1816,18 +437,18 @@ "CoreFoundation/CoreFoundation.h" "backends/platform/ps2/fileio.h" -1173398943 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\ps2\fileio.h +1173402543 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\ps2\fileio.h "common/scummsys.h" -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\fs.cpp +1173402482 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\fs.cpp "common/stdafx.h" "backends/fs/abstract-fs.h" "common/util.h" -1173533496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\hashmap.cpp +1173537096 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\hashmap.cpp "common/hashmap.h" -1173533496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\md5.cpp +1173537096 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\md5.cpp "common/file.h" "common/md5.h" "common/util.h" @@ -1835,27 +456,27 @@ <stdlib.h> <stdio.h> -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\endian.h +1177854384 c:\documents and settings\usoquotidiano\desktop\scummvm\common\endian.h "common/scummsys.h" -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\mutex.cpp +1173402482 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\mutex.cpp "common/stdafx.h" "common/mutex.h" "common/system.h" -1173533496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\str.cpp +1176747595 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\str.cpp "common/stdafx.h" "common/str.h" "common/hash-str.h" "common/util.h" -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\stream.cpp +1173402482 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\stream.cpp "common/stdafx.h" "common/stream.h" "common/str.h" "common/util.h" -1174117753 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\system.cpp +1174121353 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\system.cpp "common/stdafx.h" "backends/intern.h" "backends/events/default/default-events.h" @@ -1866,7 +487,7 @@ "common/util.h" "sound/mixer.h" -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\unzip.cpp +1173402482 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\unzip.cpp "common/stdafx.h" "common/scummsys.h" <stdio.h> @@ -1880,12 +501,12 @@ <stdlib.h> <errno.h> -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\unzip.h +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\unzip.h "common/stdafx.h" "common/scummsys.h" <zlib.h> -1173398882 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\util.cpp +1178025620 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\util.cpp "common/stdafx.h" "engines/engine.h" "common/util.h" @@ -1893,9 +514,11 @@ "gui/debugger.h" "backends/platform/ps2/fileio.h" -1173900476 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\debugger.h +1173904076 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\debugger.h -1173399217 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\engine.cpp +1175450743 source:c:\documents and settings\usoquotidiano\desktop\scummvm\engines\engine.cpp + <windows.h> + <direct.h> "common/stdafx.h" "engines/engine.h" "common/config-manager.h" @@ -1905,82 +528,83 @@ "common/system.h" "gui/message.h" "sound/mixer.h" - <windows.h> - <direct.h> -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\cursorman.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\cursorman.cpp "graphics/cursorman.h" "common/system.h" "common/stack.h" -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\cursorman.h +1173402496 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\cursorman.h "common/stdafx.h" "common/scummsys.h" "common/stack.h" "common/singleton.h" -1173398896 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\dxa_player.cpp +1173402496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\dxa_player.cpp "common/stdafx.h" "common/endian.h" "graphics/dxa_player.h" "common/util.h" <zlib.h> -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\dxa_player.h +1173402496 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\dxa_player.h "common/scummsys.h" "common/file.h" -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\font.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\font.cpp "common/stdafx.h" "common/stream.h" "common/file.h" "common/endian.h" "graphics/font.h" -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fontman.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fontman.cpp "graphics/fontman.h" -1173398893 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\consolefont.cpp +1173402493 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\consolefont.cpp "common/stdafx.h" "graphics/font.h" -1173398893 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\newfont.cpp +1173402493 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\newfont.cpp "common/stdafx.h" "graphics/font.h" -1173398893 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\newfont_big.cpp +1173402493 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\newfont_big.cpp "common/stdafx.h" "graphics/font.h" -1173398893 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\scummfont.cpp +1173402493 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\fonts\scummfont.cpp "common/stdafx.h" "graphics/font.h" "scumm_globals.h" -1173398896 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\ilbm.cpp +1177969963 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\ilbm.cpp "common/stdafx.h" "common/endian.h" "common/stream.h" "graphics/surface.h" + "graphics/ilbm.h" + +1177969881 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\ilbm.h -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imagedec.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imagedec.cpp "graphics/imagedec.h" "common/system.h" "common/file.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imagedec.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imagedec.h "common/stdafx.h" "common/scummsys.h" "common/str.h" "common/stream.h" "graphics/surface.h" -1173398896 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imageman.cpp +1173402496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imageman.cpp "graphics/imagedec.h" "graphics/imageman.h" "graphics/surface.h" -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imageman.h +1173402496 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\imageman.h "common/stdafx.h" "common/scummsys.h" "common/singleton.h" @@ -1988,64 +612,64 @@ "common/list.h" "common/unzip.h" -1173398896 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\primitives.cpp +1173402496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\primitives.cpp "common/stdafx.h" "common/util.h" -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler.cpp "graphics/scaler/intern.h" "graphics/scaler/scalebit.h" "common/util.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\intern.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\intern.h "common/stdafx.h" "common/scummsys.h" "graphics/colormasks.h" -1173398896 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\colormasks.h +1173402496 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\colormasks.h -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scalebit.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scalebit.h -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\2xsai.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\2xsai.cpp "graphics/scaler/intern.h" -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\aspect.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\aspect.cpp "graphics/scaler/intern.h" "graphics/scaler.h" -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq2x.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq2x.cpp "graphics/scaler/intern.h" "graphics/scaler/hq2x.h" "graphics/scaler/hq2x.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq2x.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq2x.h -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq3x.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq3x.cpp "graphics/scaler/intern.h" "graphics/scaler/hq3x.h" "graphics/scaler/hq3x.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq3x.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\hq3x.h -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale2x.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale2x.cpp "common/stdafx.h" "common/scummsys.h" "graphics/scaler/intern.h" "graphics/scaler/scale2x.h" <assert.h> -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale2x.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale2x.h -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale3x.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale3x.cpp "common/stdafx.h" "common/scummsys.h" "graphics/scaler/intern.h" "graphics/scaler/scale3x.h" <assert.h> -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale3x.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scale3x.h -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scalebit.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\scalebit.cpp "common/stdafx.h" "common/scummsys.h" "graphics/scaler/intern.h" @@ -2055,22 +679,22 @@ <assert.h> <stdlib.h> -1173398895 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\thumbnail.cpp +1173402495 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\scaler\thumbnail.cpp "common/stdafx.h" "common/scummsys.h" "common/system.h" "graphics/scaler.h" "graphics/scaler/intern.h" -1173398896 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\surface.cpp +1173402496 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\surface.cpp "common/stdafx.h" "common/util.h" "graphics/primitives.h" "graphics/surface.h" -1173398895 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\primitives.h +1173402495 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\primitives.h -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\actions.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\actions.cpp "common/stdafx.h" "gui/Actions.h" "gui/message.h" @@ -2080,18 +704,18 @@ "backends/platform/wince/CEActionsSmartphone.h" "backends/platform/symbian/src/SymbianActions.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\actions.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\actions.h "common/stdafx.h" "common/scummsys.h" "common/system.h" "gui/Key.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\key.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\key.h "common/stdafx.h" "common/scummsys.h" "common/system.h" -1173641246 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\scumm.h +1177854379 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\scumm.h "engines/engine.h" "common/endian.h" "common/file.h" @@ -2099,20 +723,20 @@ "common/str.h" "graphics/surface.h" "scumm/gfx.h" - "scumm/plugin.h" + "scumm/detection.h" "scumm/script.h" "sound/mididrv.h" -1173533494 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\gfx.h +1173537094 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\gfx.h "graphics/surface.h" -1173398810 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\plugin.h +1173402410 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\plugin.h "common/util.h" -1173398809 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\script.h +1173402409 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\script.h "engines/engine.h" -1173398947 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\ceactionspocket.h +1177854385 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\ceactionspocket.h "common/stdafx.h" "common/scummsys.h" "common/system.h" @@ -2120,7 +744,7 @@ "gui/Key.h" "gui/Actions.h" -1173398947 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\wince-sdl.h +1177854385 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\wince-sdl.h "common/stdafx.h" "common/scummsys.h" "common/system.h" @@ -2133,20 +757,20 @@ "CEScaler.h" <SDL.h> -1173398947 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\cedevice.h +1177854385 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\cedevice.h "common/stdafx.h" "common/scummsys.h" "common/system.h" "common/str.h" -1173398947 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\cescaler.h +1173402547 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\cescaler.h "common/stdafx.h" "common/scummsys.h" "common/system.h" "graphics/scaler.h" "graphics/scaler/intern.h" -1173398947 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\ceactionssmartphone.h +1177854385 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\wince\ceactionssmartphone.h "common/stdafx.h" "common/scummsys.h" "common/system.h" @@ -2154,41 +778,41 @@ "gui/Key.h" "gui/Actions.h" -1173900478 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\symbian\src\symbianactions.h +1173904078 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\platform\symbian\src\symbianactions.h "common/stdafx.h" "common/scummsys.h" "common/system.h" "gui/Key.h" "gui/Actions.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\edittextwidget.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\edittextwidget.cpp "common/stdafx.h" "gui/EditTextWidget.h" "gui/dialog.h" "gui/eval.h" "gui/newgui.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\edittextwidget.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\edittextwidget.h "gui/editable.h" "common/str.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\editable.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\editable.h "common/str.h" "common/rect.h" "gui/widget.h" "gui/newgui.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\eval.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\eval.h "common/stdafx.h" "common/str.h" "common/hashmap.h" "common/hash-str.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\key.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\key.cpp "common/stdafx.h" "gui/Key.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\listwidget.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\listwidget.cpp "common/stdafx.h" "common/system.h" "gui/ListWidget.h" @@ -2197,14 +821,14 @@ "gui/eval.h" "gui/newgui.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\listwidget.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\listwidget.h "gui/editable.h" "common/str.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\scrollbarwidget.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\scrollbarwidget.h "gui/widget.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\popupwidget.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\popupwidget.cpp "common/stdafx.h" "common/system.h" "gui/dialog.h" @@ -2213,18 +837,18 @@ "gui/PopUpWidget.h" "engines/engine.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\popupwidget.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\popupwidget.h "gui/widget.h" "common/str.h" "common/array.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\scrollbarwidget.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\scrollbarwidget.cpp "common/stdafx.h" "ScrollBarWidget.h" "gui/dialog.h" "gui/newgui.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\tabwidget.cpp +1176747594 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\tabwidget.cpp "common/stdafx.h" "common/util.h" "gui/TabWidget.h" @@ -2232,19 +856,19 @@ "gui/newgui.h" "gui/eval.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\tabwidget.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\tabwidget.h "widget.h" "common/str.h" "common/array.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themeclassic.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themeclassic.cpp "gui/ThemeClassic.h" "gui/eval.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themeclassic.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themeclassic.h "gui/theme.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\thememodern.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\thememodern.cpp "gui/ThemeModern.h" "gui/eval.h" "graphics/imageman.h" @@ -2254,14 +878,15 @@ "common/config-manager.h" "common/file.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\thememodern.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\thememodern.h "gui/theme.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\about.cpp +1174164453 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\about.cpp "common/stdafx.h" "engines/engine.h" "base/plugins.h" "base/version.h" + "common/events.h" "common/system.h" "common/util.h" "gui/about.h" @@ -2270,14 +895,14 @@ "gui/widget.h" "gui/credits.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\about.h +1174157116 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\about.h "gui/dialog.h" "common/str.h" "graphics/surface.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\credits.h +1177614532 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\credits.h -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\browser.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\browser.cpp "common/stdafx.h" "gui/browser.h" "gui/newgui.h" @@ -2287,44 +912,45 @@ "common/system.h" "common/func.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\browser.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\browser.h "gui/dialog.h" "common/str.h" "common/fs.h" <Carbon/Carbon.h> -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\chooser.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\chooser.cpp "common/stdafx.h" "common/system.h" "gui/chooser.h" "gui/newgui.h" "gui/ListWidget.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\chooser.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\chooser.h "common/str.h" "gui/dialog.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\console.cpp +1174164453 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\console.cpp "common/stdafx.h" "gui/console.h" "gui/ScrollBarWidget.h" "gui/eval.h" "engines/engine.h" "base/version.h" + "common/events.h" "common/system.h" "graphics/font.h" -1173533495 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\console.h +1173537095 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\console.h "gui/dialog.h" "gui/newgui.h" -1173900476 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\debugger.cpp +1173904076 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\debugger.cpp "common/stdafx.h" "common/system.h" "gui/debugger.h" "gui/console.h" -1174117751 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\dialog.cpp +1176747594 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\dialog.cpp "common/stdafx.h" "gui/newgui.h" "gui/dialog.h" @@ -2332,12 +958,12 @@ "gui/PopUpWidget.h" "common/system.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\editable.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\editable.cpp "common/stdafx.h" "gui/editable.h" "gui/newgui.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\eval.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\eval.cpp "common/stdafx.h" "common/system.h" "gui/eval.h" @@ -2345,13 +971,14 @@ "gui/newgui.h" "graphics/scaler.h" -1174117751 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\launcher.cpp +1174164453 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\launcher.cpp "common/stdafx.h" "engines/engine.h" "base/game.h" "base/plugins.h" "base/version.h" "common/config-manager.h" + "common/events.h" "common/fs.h" "common/util.h" "common/system.h" @@ -2370,23 +997,23 @@ "gui/PopUpWidget.h" "sound/mididrv.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\massadd.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\massadd.h "gui/dialog.h" "common/fs.h" "common/stack.h" -1173562730 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\options.h +1173566330 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\options.h "gui/dialog.h" "common/str.h" "gui/KeysDialog.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\keysdialog.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\keysdialog.h "gui/newgui.h" "gui/dialog.h" "gui/ListWidget.h" "common/str.h" -1173562730 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\massadd.cpp +1173566330 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\massadd.cpp "common/stdafx.h" "engines/engine.h" "base/game.h" @@ -2396,7 +1023,7 @@ "gui/newgui.h" "gui/widget.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\message.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\message.cpp "common/stdafx.h" "common/str.h" "common/system.h" @@ -2404,7 +1031,7 @@ "gui/newgui.h" "gui/widget.h" -1174117751 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\newgui.cpp +1177854375 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\newgui.cpp "common/stdafx.h" "common/events.h" "common/system.h" @@ -2417,7 +1044,13 @@ "gui/ThemeClassic.h" "common/config-manager.h" -1173562730 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\options.cpp +1176747594 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\object.cpp + "common/stdafx.h" + "common/system.h" + "gui/object.h" + "gui/widget.h" + +1173566330 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\options.cpp "common/stdafx.h" "gui/browser.h" "gui/themebrowser.h" @@ -2434,22 +1067,22 @@ "sound/mididrv.h" "sound/mixer.h" -1173398764 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themebrowser.h +1173402364 c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themebrowser.h "gui/dialog.h" "common/str.h" "common/fs.h" "common/array.h" -1173562730 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme-config.cpp +1177347977 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme-config.cpp "gui/theme.h" "gui/eval.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme.cpp +1177854375 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\theme.cpp "gui/theme.h" "gui/eval.h" "common/unzip.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themebrowser.cpp +1173402364 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\themebrowser.cpp "common/stdafx.h" "gui/themebrowser.h" "gui/ListWidget.h" @@ -2458,7 +1091,7 @@ "common/fs.h" "CoreFoundation/CoreFoundation.h" -1173398764 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\widget.cpp +1176747594 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\widget.cpp "common/stdafx.h" "common/util.h" "graphics/fontman.h" @@ -2467,25 +1100,26 @@ "gui/eval.h" "gui/newgui.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\adpcm.cpp +1177614536 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\adpcm.cpp "common/stdafx.h" "common/endian.h" "sound/adpcm.h" "sound/audiostream.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\adpcm.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\adpcm.h "common/stdafx.h" "common/scummsys.h" "common/stream.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiostream.h +1176623932 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiostream.h "common/stdafx.h" "common/util.h" "common/scummsys.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiocd.cpp +1176623932 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiocd.cpp "common/stdafx.h" "sound/audiocd.h" + "sound/audiostream.h" "sound/mp3.h" "sound/vorbis.h" "sound/flac.h" @@ -2494,25 +1128,25 @@ "common/util.h" "common/system.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiocd.h +1176623932 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiocd.h "common/stdafx.h" "common/scummsys.h" "common/singleton.h" "sound/mixer.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mp3.h +1176623932 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mp3.h "common/stdafx.h" "common/scummsys.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\vorbis.h +1176623932 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\vorbis.h "common/stdafx.h" "common/scummsys.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\flac.h +1176623932 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\flac.h "common/stdafx.h" "common/scummsys.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiostream.cpp +1176623932 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\audiostream.cpp "common/stdafx.h" "common/endian.h" "common/file.h" @@ -2524,7 +1158,7 @@ "sound/vorbis.h" "sound/flac.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\flac.cpp +1176623932 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\flac.cpp "sound/flac.h" "common/file.h" "common/util.h" @@ -2534,7 +1168,7 @@ <FLAC/seekable_stream_decoder.h> <FLAC/stream_decoder.h> -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\fmopl.cpp +1175936376 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\fmopl.cpp "common/stdafx.h" <stdio.h> <stdlib.h> @@ -2544,11 +1178,12 @@ "sound/fmopl.h" "common/util.h" "common/config-manager.h" + "dsmain.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\fmopl.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\fmopl.h "common/scummsys.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mididrv.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mididrv.cpp "common/stdafx.h" "engines/engine.h" "common/config-manager.h" @@ -2557,29 +1192,29 @@ "common/util.h" "sound/mididrv.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser.cpp "common/stdafx.h" "sound/midiparser.h" "sound/mididrv.h" "common/util.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser.h "common/scummsys.h" "common/endian.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser_smf.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser_smf.cpp "common/stdafx.h" "sound/midiparser.h" "sound/mididrv.h" "common/util.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser_xmidi.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\midiparser_xmidi.cpp "common/stdafx.h" "sound/midiparser.h" "sound/mididrv.h" "common/util.h" -1173562730 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mixer.cpp +1173566330 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mixer.cpp "common/stdafx.h" "common/file.h" "common/util.h" @@ -2588,11 +1223,62 @@ "sound/rate.h" "sound/audiostream.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\rate.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\rate.h "common/scummsys.h" "engines/engine.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mp3.cpp +1173402485 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\infogrames.cpp + "sound/mods/infogrames.h" + "common/endian.h" + +1173402484 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\infogrames.h + "sound/mods/paula.h" + "common/stream.h" + "common/file.h" + +1177701568 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\paula.h + "sound/audiostream.h" + "common/mutex.h" + +1173402485 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\module.cpp + "common/stdafx.h" + "sound/mods/module.h" + "common/util.h" + +1173402485 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\module.h + "common/stream.h" + "common/pack-start.h" + "common/pack-end.h" + +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\pack-start.h + +1173402482 c:\documents and settings\usoquotidiano\desktop\scummvm\common\pack-end.h + +1173402485 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\paula.cpp + "sound/mods/paula.h" + +1173402485 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\protracker.cpp + "common/stdafx.h" + "sound/mods/protracker.h" + "sound/mods/paula.h" + "sound/mods/module.h" + "sound/audiostream.h" + +1177705233 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\protracker.h + "common/stdafx.h" + "common/stream.h" + +1173402485 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\rjp1.cpp + "common/stdafx.h" + "common/endian.h" + "sound/mods/paula.h" + "sound/mods/rjp1.h" + "sound/audiostream.h" + +1173402485 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\rjp1.h + "common/stream.h" + +1176623932 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mp3.cpp "sound/mp3.h" "common/file.h" "common/util.h" @@ -2600,36 +1286,36 @@ "sound/audiostream.h" <mad.h> -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mpu401.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mpu401.cpp "common/stdafx.h" "sound/mpu401.h" "common/system.h" "common/timer.h" "common/util.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\null.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\null.cpp "common/stdafx.h" "sound/mpu401.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\rate.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\rate.cpp "common/stdafx.h" "sound/audiostream.h" "sound/rate.h" "sound/mixer.h" "common/util.h" -1173398889 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\adlib.cpp +1173402489 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\adlib.cpp "sound/softsynth/emumidi.h" "common/util.h" "sound/fmopl.h" -1173398889 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\emumidi.h +1173402489 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\emumidi.h "common/stdafx.h" "sound/audiostream.h" "sound/mididrv.h" "sound/mixer.h" -1173398889 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\fluidsynth.cpp +1173402489 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\fluidsynth.cpp "common/stdafx.h" "common/scummsys.h" "common/stdafx.h" @@ -2638,7 +1324,7 @@ "sound/softsynth/emumidi.h" <fluidsynth.h> -1174117753 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32.cpp +1174164454 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32.cpp "common/stdafx.h" "common/scummsys.h" "sound/softsynth/mt32/mt32emu.h" @@ -2652,7 +1338,7 @@ "graphics/fontman.h" "graphics/surface.h" -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\mt32emu.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\mt32emu.h "freeverb.h" "structures.h" "i386.h" @@ -2663,70 +1349,75 @@ "part.h" "synth.h" -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\freeverb.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\freeverb.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\structures.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\structures.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\i386.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\i386.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\mt32_file.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\mt32_file.h <stdio.h> -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\tables.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\tables.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partial.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partial.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partialmanager.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partialmanager.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\part.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\part.h -1173398888 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\synth.h +1173402488 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\synth.h <stdarg.h> -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\freeverb.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\freeverb.cpp "common/stdafx.h" "sound/softsynth/mt32/freeverb.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\i386.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\i386.cpp "mt32emu.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\mt32_file.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\mt32_file.cpp <stdio.h> "mt32emu.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\part.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\part.cpp <string.h> <math.h> "mt32emu.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partial.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partial.cpp <stdlib.h> <math.h> <string.h> "mt32emu.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partialmanager.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\partialmanager.cpp <string.h> "mt32emu.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\synth.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\synth.cpp <math.h> <string.h> <stdlib.h> "mt32emu.h" -1173398888 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\tables.cpp +1173402488 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\mt32\tables.cpp <stdlib.h> <string.h> <math.h> "mt32emu.h" -1173398889 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\ym2612.cpp - "sound/softsynth/emumidi.h" +1177095927 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\ym2612.cpp <math.h> + "sound/softsynth/ym2612.h" "common/util.h" -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\voc.cpp +1174743688 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\softsynth\ym2612.h + "common/stdafx.h" + "common/scummsys.h" + "sound/softsynth/emumidi.h" + +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\voc.cpp "common/stdafx.h" "common/endian.h" "common/util.h" @@ -2735,17 +1426,13 @@ "sound/mixer.h" "sound/voc.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\voc.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\voc.h "common/stdafx.h" "common/scummsys.h" "common/pack-start.h" "common/pack-end.h" -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\pack-start.h - -1173398882 c:\documents and settings\usoquotidiano\desktop\scummvm\common\pack-end.h - -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\vorbis.cpp +1176623932 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\vorbis.cpp "sound/vorbis.h" "common/file.h" "common/util.h" @@ -2755,7 +1442,7 @@ <tremor/ivorbisfile.h> <vorbis/vorbisfile.h> -1173398891 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\wave.cpp +1173402491 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\wave.cpp "common/stdafx.h" "common/util.h" "common/stream.h" @@ -2764,76 +1451,34 @@ "sound/wave.h" "sound/adpcm.h" -1173398891 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\wave.h +1173402491 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\wave.h "common/stdafx.h" "common/scummsys.h" -1173398885 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\infogrames.cpp - "sound/mods/infogrames.h" - "common/endian.h" - -1173398884 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\infogrames.h - "sound/mods/paula.h" - "common/stream.h" - "common/file.h" - -1173398885 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\paula.h - "sound/audiostream.h" - "common/mutex.h" - -1173398885 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\module.cpp - "common/stdafx.h" - "sound/mods/module.h" +1177854379 c:\documents and settings\usoquotidiano\desktop\scummvm\engines\scumm\detection.h "common/util.h" -1173398885 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\module.h - "common/stream.h" - "common/pack-start.h" - "common/pack-end.h" +1178031885 source:c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\iff.cpp + "graphics/iff.h" + "graphics/surface.h" -1173398885 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\paula.cpp - "sound/mods/paula.h" +1178031629 c:\documents and settings\usoquotidiano\desktop\scummvm\graphics\iff.h + "common/iff_container.h" -1173398885 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\protracker.cpp - "common/stdafx.h" - "sound/mods/protracker.h" - "sound/mods/paula.h" - "sound/mods/module.h" +1178027446 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\iff.cpp + "sound/iff.h" "sound/audiostream.h" + "sound/mixer.h" -1173398885 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\protracker.h - "common/stdafx.h" - "common/stream.h" +1178032147 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\iff.h + "common/iff_container.h" -1173398885 source:c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\rjp1.cpp +1178026710 source:c:\documents and settings\usoquotidiano\desktop\scummvm\common\iff_container.cpp + +1178030342 c:\documents and settings\usoquotidiano\desktop\scummvm\common\iff_container.h "common/stdafx.h" + "common/scummsys.h" "common/endian.h" - "sound/mods/paula.h" - "sound/mods/rjp1.h" - "sound/audiostream.h" - -1173398885 c:\documents and settings\usoquotidiano\desktop\scummvm\sound\mods\rjp1.h "common/stream.h" - -1174117754 c:\documents and settings\usoquotidiano\desktop\scummvm\backends\events\default\default-events.h - "common/stdafx.h" - "common/events.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\events.h - "common/rect.h" - "common/system.h" - "common/noncopyable.h" - -1174117754 source:c:\documents and settings\usoquotidiano\desktop\scummvm\backends\events\default\default-events.cpp - "common/stdafx.h" - "common/system.h" - "backends/events/default/default-events.h" - -1174117751 source:c:\documents and settings\usoquotidiano\desktop\scummvm\gui\object.cpp - "common/stdafx.h" - "common/system.h" - "gui/object.h" - "gui/widget.h" - -1174132564 c:\documents and settings\usoquotidiano\desktop\scummvm\common\noncopyable.h + "common/util.h" diff --git a/dists/codeblocks/scummvm.layout b/dists/codeblocks/scummvm.layout index 4bdc9a3e21..7b88105b61 100644 --- a/dists/codeblocks/scummvm.layout +++ b/dists/codeblocks/scummvm.layout @@ -2,22 +2,22 @@ <CodeBlocks_layout_file> <ActiveTarget name="default" /> <File name="..\..\backends\events\default\default-events.cpp" open="0" top="0" tabpos="0"> - <Cursor position="0" topLine="39" /> + <Cursor position="1060" topLine="8" /> </File> <File name="..\..\backends\events\default\default-events.h" open="0" top="0" tabpos="0"> <Cursor position="0" topLine="13" /> </File> <File name="..\..\backends\fs\windows\windows-fs.cpp" open="0" top="0" tabpos="3"> - <Cursor position="6675" topLine="207" /> + <Cursor position="1326" topLine="28" /> </File> <File name="..\..\backends\midi\windows.cpp" open="0" top="0" tabpos="4"> - <Cursor position="2922" topLine="80" /> + <Cursor position="1606" topLine="24" /> </File> - <File name="..\..\backends\platform\sdl\events.cpp" open="0" top="0" tabpos="0"> - <Cursor position="5928" topLine="213" /> + <File name="..\..\backends\platform\sdl\events.cpp" open="0" top="0" tabpos="1"> + <Cursor position="5716" topLine="196" /> </File> - <File name="..\..\backends\platform\sdl\graphics.cpp" open="0" top="0" tabpos="5"> - <Cursor position="47256" topLine="1698" /> + <File name="..\..\backends\platform\sdl\graphics.cpp" open="0" top="0" tabpos="1"> + <Cursor position="27863" topLine="1022" /> </File> <File name="..\..\backends\platform\sdl\sdl-common.h" open="0" top="0" tabpos="0"> <Cursor position="7253" topLine="206" /> @@ -34,29 +34,29 @@ <File name="..\..\backends\timer\default\default-timer.cpp" open="0" top="0" tabpos="7"> <Cursor position="3304" topLine="82" /> </File> - <File name="..\..\base\commandLine.cpp" open="0" top="0" tabpos="1"> - <Cursor position="13025" topLine="298" /> - </File> - <File name="..\..\base\game.cpp" open="0" top="0" tabpos="0"> - <Cursor position="1060" topLine="27" /> + <File name="..\..\base\commandLine.cpp" open="0" top="0" tabpos="14"> + <Cursor position="13025" topLine="322" /> </File> <File name="..\..\base\main.cpp" open="0" top="0" tabpos="0"> <Cursor position="10180" topLine="267" /> </File> - <File name="..\..\base\plugins.cpp" open="0" top="0" tabpos="8"> - <Cursor position="1245" topLine="19" /> + <File name="..\..\base\main.h" open="0" top="0" tabpos="0"> + <Cursor position="1074" topLine="0" /> </File> - <File name="..\..\base\plugins.h" open="0" top="0" tabpos="0"> - <Cursor position="7833" topLine="188" /> + <File name="..\..\base\plugins.cpp" open="1" top="0" tabpos="5"> + <Cursor position="3400" topLine="86" /> + </File> + <File name="..\..\base\plugins.h" open="0" top="0" tabpos="3"> + <Cursor position="5991" topLine="151" /> </File> <File name="..\..\base\version.cpp" open="0" top="0" tabpos="0"> - <Cursor position="2" topLine="0" /> + <Cursor position="1734" topLine="13" /> </File> - <File name="..\..\common\advancedDetector.cpp" open="0" top="0" tabpos="0"> - <Cursor position="8666" topLine="282" /> + <File name="..\..\common\advancedDetector.cpp" open="0" top="0" tabpos="16"> + <Cursor position="4607" topLine="144" /> </File> - <File name="..\..\common\array.h" open="0" top="0" tabpos="0"> - <Cursor position="1099" topLine="46" /> + <File name="..\..\common\array.h" open="0" top="0" tabpos="2"> + <Cursor position="1882" topLine="45" /> </File> <File name="..\..\common\config-file.cpp" open="0" top="0" tabpos="0"> <Cursor position="4515" topLine="122" /> @@ -68,85 +68,139 @@ <Cursor position="1658" topLine="12" /> </File> <File name="..\..\common\endian.h" open="0" top="0" tabpos="0"> - <Cursor position="5094" topLine="126" /> + <Cursor position="4129" topLine="122" /> </File> <File name="..\..\common\file.cpp" open="0" top="0" tabpos="0"> - <Cursor position="8437" topLine="235" /> + <Cursor position="15663" topLine="480" /> </File> <File name="..\..\common\file.h" open="0" top="0" tabpos="13"> - <Cursor position="1172" topLine="12" /> + <Cursor position="1181" topLine="61" /> + </File> + <File name="..\..\common\fs.cpp" open="0" top="0" tabpos="0"> + <Cursor position="1071" topLine="8" /> + </File> + <File name="..\..\common\func.h" open="0" top="0" tabpos="2"> + <Cursor position="2306" topLine="40" /> + </File> + <File name="..\..\common\hashmap.h" open="0" top="0" tabpos="0"> + <Cursor position="30" topLine="120" /> + </File> + <File name="..\..\common\list.h" open="0" top="0" tabpos="1"> + <Cursor position="3592" topLine="128" /> + </File> + <File name="..\..\common\md5.cpp" open="0" top="0" tabpos="20"> + <Cursor position="1020" topLine="364" /> </File> - <File name="..\..\common\list.h" open="1" top="0" tabpos="17"> - <Cursor position="1602" topLine="26" /> + <File name="..\..\common\md5.h" open="0" top="0" tabpos="19"> + <Cursor position="0" topLine="0" /> </File> - <File name="..\..\common\mutex.cpp" open="0" top="0" tabpos="0"> + <File name="..\..\common\mutex.cpp" open="0" top="0" tabpos="18"> <Cursor position="1316" topLine="24" /> </File> + <File name="..\..\common\mutex.h" open="0" top="0" tabpos="1"> + <Cursor position="1704" topLine="21" /> + </File> <File name="..\..\common\rect.h" open="0" top="0" tabpos="0"> - <Cursor position="5584" topLine="130" /> + <Cursor position="3493" topLine="23" /> </File> <File name="..\..\common\savefile.h" open="0" top="0" tabpos="1"> <Cursor position="1342" topLine="55" /> </File> - <File name="..\..\common\scummsys.h" open="0" top="0" tabpos="0"> - <Cursor position="9547" topLine="341" /> + <File name="..\..\common\scummsys.h" open="0" top="0" tabpos="1"> + <Cursor position="9437" topLine="352" /> </File> <File name="..\..\common\singleton.h" open="0" top="0" tabpos="0"> <Cursor position="0" topLine="39" /> </File> + <File name="..\..\common\stack.h" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="60" /> + </File> <File name="..\..\common\stdafx.h" open="0" top="0" tabpos="1"> - <Cursor position="3750" topLine="55" /> + <Cursor position="27" topLine="0" /> </File> <File name="..\..\common\str.cpp" open="0" top="0" tabpos="0"> - <Cursor position="10347" topLine="401" /> + <Cursor position="3740" topLine="78" /> </File> <File name="..\..\common\str.h" open="0" top="0" tabpos="0"> - <Cursor position="6138" topLine="163" /> + <Cursor position="6115" topLine="165" /> </File> <File name="..\..\common\stream.cpp" open="0" top="0" tabpos="0"> <Cursor position="1828" topLine="46" /> </File> <File name="..\..\common\stream.h" open="0" top="0" tabpos="3"> - <Cursor position="11237" topLine="339" /> + <Cursor position="3529" topLine="125" /> </File> <File name="..\..\common\system.cpp" open="0" top="0" tabpos="0"> <Cursor position="1888" topLine="29" /> </File> <File name="..\..\common\system.h" open="0" top="0" tabpos="2"> - <Cursor position="29061" topLine="781" /> + <Cursor position="27043" topLine="748" /> </File> <File name="..\..\common\timer.h" open="0" top="0" tabpos="0"> <Cursor position="0" topLine="10" /> </File> <File name="..\..\common\unzip.cpp" open="0" top="0" tabpos="0"> - <Cursor position="9067" topLine="298" /> + <Cursor position="35606" topLine="1176" /> </File> <File name="..\..\common\util.cpp" open="0" top="0" tabpos="3"> <Cursor position="11348" topLine="425" /> </File> <File name="..\..\common\util.h" open="0" top="0" tabpos="2"> - <Cursor position="5919" topLine="185" /> + <Cursor position="3" topLine="126" /> </File> <File name="..\..\engines\engine.cpp" open="0" top="0" tabpos="6"> <Cursor position="1299" topLine="6" /> </File> - <File name="..\..\graphics\dxa_player.cpp" open="0" top="0" tabpos="0"> + <File name="..\..\graphics\dxa_player.cpp" open="0" top="0" tabpos="5"> <Cursor position="2699" topLine="98" /> </File> + <File name="..\..\graphics\font.cpp" open="0" top="0" tabpos="0"> + <Cursor position="1610" topLine="46" /> + </File> <File name="..\..\graphics\font.h" open="0" top="0" tabpos="0"> - <Cursor position="1274" topLine="37" /> + <Cursor position="1274" topLine="20" /> + </File> + <File name="..\..\graphics\fontman.h" open="0" top="0" tabpos="0"> + <Cursor position="2503" topLine="36" /> + </File> + <File name="..\..\graphics\ilbm.cpp" open="1" top="0" tabpos="3"> + <Cursor position="9338" topLine="284" /> + </File> + <File name="..\..\graphics\ilbm.h" open="1" top="0" tabpos="2"> + <Cursor position="1674" topLine="36" /> + </File> + <File name="..\..\graphics\imagedec.cpp" open="1" top="0" tabpos="1"> + <Cursor position="3897" topLine="4" /> + </File> + <File name="..\..\graphics\imagedec.h" open="0" top="0" tabpos="0"> + <Cursor position="1720" topLine="11" /> </File> - <File name="..\..\graphics\ilbm.cpp" open="0" top="0" tabpos="1"> - <Cursor position="8845" topLine="271" /> + <File name="..\..\graphics\imageman.cpp" open="0" top="0" tabpos="0"> + <Cursor position="1217" topLine="0" /> </File> - <File name="..\..\graphics\ilbm.h" open="0" top="0" tabpos="2"> - <Cursor position="1053" topLine="0" /> + <File name="..\..\graphics\imageman.h" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="21" /> </File> - <File name="..\..\graphics\surface.cpp" open="0" top="0" tabpos="0"> - <Cursor position="2432" topLine="171" /> + <File name="..\..\graphics\primitives.cpp" open="0" top="0" tabpos="0"> + <Cursor position="1071" topLine="17" /> </File> - <File name="..\..\graphics\surface.h" open="0" top="0" tabpos="10"> - <Cursor position="1817" topLine="25" /> + <File name="..\..\graphics\primitives.h" open="0" top="0" tabpos="0"> + <Cursor position="1194" topLine="0" /> + </File> + <File name="..\..\graphics\scaler.h" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="33" /> + </File> + <File name="..\..\graphics\scaler\scale2x.cpp" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="17" /> + </File> + <File name="..\..\graphics\scaler\scale2x.h" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="16" /> + </File> + <File name="..\..\graphics\surface.cpp" open="0" top="0" tabpos="4"> + <Cursor position="2096" topLine="9" /> + </File> + <File name="..\..\graphics\surface.h" open="0" top="0" tabpos="3"> + <Cursor position="2124" topLine="19" /> </File> <File name="..\..\gui\ListWidget.h" open="0" top="0" tabpos="0"> <Cursor position="1693" topLine="25" /> @@ -164,7 +218,7 @@ <Cursor position="2732" topLine="48" /> </File> <File name="..\..\gui\dialog.h" open="0" top="0" tabpos="0"> - <Cursor position="1255" topLine="16" /> + <Cursor position="1177" topLine="12" /> </File> <File name="..\..\gui\massadd.cpp" open="0" top="0" tabpos="0"> <Cursor position="5313" topLine="146" /> @@ -187,6 +241,9 @@ <File name="..\..\gui\theme.h" open="0" top="0" tabpos="0"> <Cursor position="8342" topLine="197" /> </File> + <File name="..\..\gui\themebrowser.cpp" open="0" top="0" tabpos="0"> + <Cursor position="4920" topLine="152" /> + </File> <File name="..\..\gui\widget.h" open="0" top="0" tabpos="0"> <Cursor position="5090" topLine="21" /> </File> @@ -194,13 +251,13 @@ <Cursor position="0" topLine="44" /> </File> <File name="..\..\sound\audiostream.h" open="0" top="0" tabpos="0"> - <Cursor position="0" topLine="90" /> + <Cursor position="4511" topLine="87" /> </File> <File name="..\..\sound\flac.h" open="0" top="0" tabpos="0"> <Cursor position="0" topLine="4" /> </File> <File name="..\..\sound\fmopl.h" open="0" top="0" tabpos="0"> - <Cursor position="0" topLine="110" /> + <Cursor position="0" topLine="117" /> </File> <File name="..\..\sound\mididrv.cpp" open="0" top="0" tabpos="0"> <Cursor position="0" topLine="164" /> @@ -209,19 +266,46 @@ <Cursor position="4230" topLine="136" /> </File> <File name="..\..\sound\midiparser.cpp" open="0" top="0" tabpos="3"> - <Cursor position="0" topLine="198" /> + <Cursor position="4149" topLine="130" /> </File> <File name="..\..\sound\midiparser.h" open="0" top="0" tabpos="2"> <Cursor position="0" topLine="325" /> </File> + <File name="..\..\sound\midiparser_xmidi.cpp" open="0" top="0" tabpos="0"> + <Cursor position="4826" topLine="133" /> + </File> + <File name="..\..\sound\mixer.cpp" open="0" top="0" tabpos="0"> + <Cursor position="1483" topLine="50" /> + </File> <File name="..\..\sound\mixer.h" open="0" top="0" tabpos="0"> - <Cursor position="1127" topLine="161" /> + <Cursor position="3013" topLine="69" /> + </File> + <File name="..\..\sound\mods\infogrames.h" open="0" top="0" tabpos="0"> + <Cursor position="1484" topLine="52" /> + </File> + <File name="..\..\sound\mods\module.cpp" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="114" /> + </File> + <File name="..\..\sound\mods\module.h" open="0" top="0" tabpos="0"> + <Cursor position="0" topLine="29" /> </File> <File name="..\..\sound\mods\paula.cpp" open="0" top="0" tabpos="9"> - <Cursor position="1084" topLine="4" /> + <Cursor position="3086" topLine="115" /> </File> <File name="..\..\sound\mods\paula.h" open="0" top="0" tabpos="8"> - <Cursor position="2346" topLine="39" /> + <Cursor position="1360" topLine="37" /> + </File> + <File name="..\..\sound\mods\protracker.cpp" open="0" top="0" tabpos="0"> + <Cursor position="11471" topLine="410" /> + </File> + <File name="..\..\sound\mods\protracker.h" open="0" top="0" tabpos="0"> + <Cursor position="1136" topLine="0" /> + </File> + <File name="..\..\sound\mods\rjp1.cpp" open="0" top="0" tabpos="0"> + <Cursor position="6647" topLine="201" /> + </File> + <File name="..\..\sound\mp3.cpp" open="0" top="0" tabpos="0"> + <Cursor position="3255" topLine="69" /> </File> <File name="..\..\sound\mp3.h" open="0" top="0" tabpos="0"> <Cursor position="0" topLine="4" /> @@ -232,6 +316,9 @@ <File name="..\..\sound\rate.cpp" open="0" top="0" tabpos="0"> <Cursor position="5797" topLine="175" /> </File> + <File name="..\..\sound\softsynth\mt32\freeverb.h" open="0" top="0" tabpos="0"> + <Cursor position="4321" topLine="133" /> + </File> <File name="..\..\sound\softsynth\mt32\mt32_file.cpp" open="0" top="0" tabpos="0"> <Cursor position="1218" topLine="15" /> </File> @@ -245,7 +332,7 @@ <Cursor position="0" topLine="4" /> </File> <File name="..\..\sound\wave.cpp" open="0" top="0" tabpos="0"> - <Cursor position="1130" topLine="0" /> + <Cursor position="4722" topLine="86" /> </File> <File name="..\..\sound\wave.h" open="0" top="0" tabpos="0"> <Cursor position="1159" topLine="6" /> diff --git a/dists/codeblocks/scummvm.workspace b/dists/codeblocks/scummvm.workspace index 755f22dd30..1e42c9f4c9 100644 --- a/dists/codeblocks/scummvm.workspace +++ b/dists/codeblocks/scummvm.workspace @@ -1,9 +1,9 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes" ?> <CodeBlocks_workspace_file> <Workspace title="ScummVM"> - <Project filename="scummvm.cbp"> + <Project filename="scummvm.cbp" active="1"> <Depends filename="parallaction.cbp" /> </Project> - <Project filename="parallaction.cbp" active="1" /> + <Project filename="parallaction.cbp" /> </Workspace> </CodeBlocks_workspace_file> diff --git a/dists/msvc71/agi.vcproj b/dists/msvc71/agi.vcproj index e3c8251484..1995554ac2 100644 --- a/dists/msvc71/agi.vcproj +++ b/dists/msvc71/agi.vcproj @@ -198,9 +198,6 @@ RelativePath="..\..\engines\agi\opcodes.h"> </File> <File - RelativePath="..\..\engines\agi\patches.cpp"> - </File> - <File RelativePath="..\..\engines\agi\picture.cpp"> </File> <File diff --git a/dists/msvc71/agos.vcproj b/dists/msvc71/agos.vcproj index 2b3e06eb69..10c76cdc59 100644 --- a/dists/msvc71/agos.vcproj +++ b/dists/msvc71/agos.vcproj @@ -144,13 +144,16 @@ RelativePath="..\..\engines\agos\debugger.h"> </File> <File - RelativePath="..\..\engines\agos\draw.cpp"> + RelativePath="..\..\engines\agos\detection.cpp"> </File> <File - RelativePath="..\..\engines\agos\event.cpp"> + RelativePath="..\..\engines\agos\detection_tables.h"> + </File> + <File + RelativePath="..\..\engines\agos\draw.cpp"> </File> <File - RelativePath="..\..\engines\agos\game.cpp"> + RelativePath="..\..\engines\agos\event.cpp"> </File> <File RelativePath="..\..\engines\agos\gfx.cpp"> diff --git a/dists/msvc71/cine.vcproj b/dists/msvc71/cine.vcproj index 7e12ebe76f..a7e2d687b2 100644 --- a/dists/msvc71/cine.vcproj +++ b/dists/msvc71/cine.vcproj @@ -185,28 +185,16 @@ RelativePath="..\..\engines\cine\rel.h"> </File> <File - RelativePath="..\..\engines\cine\resource.cpp"> - </File> - <File - RelativePath="..\..\engines\cine\resource.h"> - </File> - <File RelativePath="..\..\engines\cine\script.cpp"> </File> <File RelativePath="..\..\engines\cine\script.h"> </File> <File - RelativePath="..\..\engines\cine\sfx_player.cpp"> - </File> - <File - RelativePath="..\..\engines\cine\sfx_player.h"> - </File> - <File - RelativePath="..\..\engines\cine\sound_driver.cpp"> + RelativePath="..\..\engines\cine\sound.cpp"> </File> <File - RelativePath="..\..\engines\cine\sound_driver.h"> + RelativePath="..\..\engines\cine\sound.h"> </File> <File RelativePath="..\..\engines\cine\texte.cpp"> diff --git a/dists/msvc71/cruise.vcproj b/dists/msvc71/cruise.vcproj new file mode 100644 index 0000000000..03e8a4a8f0 --- /dev/null +++ b/dists/msvc71/cruise.vcproj @@ -0,0 +1,287 @@ +<?xml version="1.0" encoding="Windows-1250"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="7.10" + Name="cruise" + ProjectGUID="{CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC}" + Keyword="Win32Proj"> + <Platforms> + <Platform + Name="Win32"/> + </Platforms> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="cruise_Debug" + IntermediateDirectory="cruise_Debug" + ConfigurationType="4" + CharacterSet="2"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702" + Optimization="0" + AdditionalIncludeDirectories="../..;../../engines" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" + MinimalRebuild="TRUE" + ExceptionHandling="TRUE" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + BufferSecurityCheck="TRUE" + EnableFunctionLevelLinking="TRUE" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + SuppressStartupBanner="FALSE" + DebugInformationFormat="4"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/cruise.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="cruise_Release" + IntermediateDirectory="cruise_Release" + ConfigurationType="4" + CharacterSet="2" + WholeProgramOptimization="FALSE"> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702" + Optimization="2" + InlineFunctionExpansion="1" + OmitFramePointers="TRUE" + AdditionalIncludeDirectories="../..;../../engines" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" + StringPooling="TRUE" + ExceptionHandling="TRUE" + RuntimeLibrary="0" + BufferSecurityCheck="FALSE" + EnableFunctionLevelLinking="FALSE" + DisableLanguageExtensions="FALSE" + ForceConformanceInForLoopScope="TRUE" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="0"/> + <Tool + Name="VCCustomBuildTool"/> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/cruise.lib"/> + <Tool + Name="VCMIDLTool"/> + <Tool + Name="VCPostBuildEventTool"/> + <Tool + Name="VCPreBuildEventTool"/> + <Tool + Name="VCPreLinkEventTool"/> + <Tool + Name="VCResourceCompilerTool"/> + <Tool + Name="VCWebServiceProxyGeneratorTool"/> + <Tool + Name="VCXMLDataGeneratorTool"/> + <Tool + Name="VCManagedWrapperGeneratorTool"/> + <Tool + Name="VCAuxiliaryManagedWrapperGeneratorTool"/> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath="..\..\engines\cruise\actor.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\actor.h"> + </File> + <File + RelativePath="..\..\engines\cruise\background.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\background.h"> + </File> + <File + RelativePath="..\..\engines\cruise\backgroundIncrust.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\backgroundIncrust.h"> + </File> + <File + RelativePath="..\..\engines\cruise\cell.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\cell.h"> + </File> + <File + RelativePath="..\..\engines\cruise\cruise.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\cruise.h"> + </File> + <File + RelativePath="..\..\engines\cruise\cruise_main.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\cruise_main.h"> + </File> + <File + RelativePath="..\..\engines\cruise\ctp.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\ctp.h"> + </File> + <File + RelativePath="..\..\engines\cruise\dataLoader.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\dataLoader.h"> + </File> + <File + RelativePath="..\..\engines\cruise\decompiler.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\delphine-unpack.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\detection.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\font.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\font.h"> + </File> + <File + RelativePath="..\..\engines\cruise\fontCharacterTable.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\fontCharacterTable.h"> + </File> + <File + RelativePath="..\..\engines\cruise\function.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\function.h"> + </File> + <File + RelativePath="..\..\engines\cruise\gfxModule.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\gfxModule.h"> + </File> + <File + RelativePath="..\..\engines\cruise\linker.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\linker.h"> + </File> + <File + RelativePath="..\..\engines\cruise\mainDraw.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\mainDraw.h"> + </File> + <File + RelativePath="..\..\engines\cruise\menu.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\menu.h"> + </File> + <File + RelativePath="..\..\engines\cruise\mouse.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\mouse.h"> + </File> + <File + RelativePath="..\..\engines\cruise\object.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\object.h"> + </File> + <File + RelativePath="..\..\engines\cruise\overlay.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\overlay.h"> + </File> + <File + RelativePath="..\..\engines\cruise\perso.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\perso.h"> + </File> + <File + RelativePath="..\..\engines\cruise\polys.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\polys.h"> + </File> + <File + RelativePath="..\..\engines\cruise\saveload.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\saveload.h"> + </File> + <File + RelativePath="..\..\engines\cruise\script.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\script.h"> + </File> + <File + RelativePath="..\..\engines\cruise\stack.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\stack.h"> + </File> + <File + RelativePath="..\..\engines\cruise\stringSupport.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\stringSupport.h"> + </File> + <File + RelativePath="..\..\engines\cruise\various.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\various.h"> + </File> + <File + RelativePath="..\..\engines\cruise\vars.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\vars.h"> + </File> + <File + RelativePath="..\..\engines\cruise\volume.cpp"> + </File> + <File + RelativePath="..\..\engines\cruise\volume.h"> + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/dists/msvc71/gob.vcproj b/dists/msvc71/gob.vcproj index 97ed84e612..b506a9532d 100644 --- a/dists/msvc71/gob.vcproj +++ b/dists/msvc71/gob.vcproj @@ -110,12 +110,6 @@ </References> <Files> <File - RelativePath="..\..\engines\gob\anim.cpp"> - </File> - <File - RelativePath="..\..\engines\gob\anim.h"> - </File> - <File RelativePath="..\..\engines\gob\cdrom.cpp"> </File> <File @@ -188,6 +182,15 @@ RelativePath="..\..\engines\gob\goblin_v2.cpp"> </File> <File + RelativePath="..\..\engines\gob\goblin_v3.cpp"> + </File> + <File + RelativePath="..\..\engines\gob\imd.cpp"> + </File> + <File + RelativePath="..\..\engines\gob\imd.h"> + </File> + <File RelativePath="..\..\engines\gob\init.cpp"> </File> <File @@ -200,6 +203,9 @@ RelativePath="..\..\engines\gob\init_v2.cpp"> </File> <File + RelativePath="..\..\engines\gob\init_v3.cpp"> + </File> + <File RelativePath="..\..\engines\gob\inter.cpp"> </File> <File @@ -215,6 +221,9 @@ RelativePath="..\..\engines\gob\inter_v2.cpp"> </File> <File + RelativePath="..\..\engines\gob\inter_v3.cpp"> + </File> + <File RelativePath="..\..\engines\gob\map.cpp"> </File> <File @@ -245,12 +254,6 @@ RelativePath="..\..\engines\gob\music.h"> </File> <File - RelativePath="..\..\engines\gob\pack.cpp"> - </File> - <File - RelativePath="..\..\engines\gob\pack.h"> - </File> - <File RelativePath="..\..\engines\gob\palanim.cpp"> </File> <File @@ -269,6 +272,18 @@ RelativePath="..\..\engines\gob\parse_v2.cpp"> </File> <File + RelativePath="..\..\engines\gob\saveload.cpp"> + </File> + <File + RelativePath="..\..\engines\gob\saveload.h"> + </File> + <File + RelativePath="..\..\engines\gob\saveload_v2.cpp"> + </File> + <File + RelativePath="..\..\engines\gob\saveload_v3.cpp"> + </File> + <File RelativePath="..\..\engines\gob\scenery.cpp"> </File> <File @@ -287,12 +302,6 @@ RelativePath="..\..\engines\gob\sound.h"> </File> <File - RelativePath="..\..\engines\gob\timer.cpp"> - </File> - <File - RelativePath="..\..\engines\gob\timer.h"> - </File> - <File RelativePath="..\..\engines\gob\util.cpp"> </File> <File diff --git a/dists/msvc71/kyra.vcproj b/dists/msvc71/kyra.vcproj index 82f30198d7..d1e9a33392 100644 --- a/dists/msvc71/kyra.vcproj +++ b/dists/msvc71/kyra.vcproj @@ -122,6 +122,9 @@ RelativePath="..\..\engines\kyra\debugger.h"> </File> <File + RelativePath="..\..\engines\kyra\detection.cpp"> + </File> + <File RelativePath="..\..\engines\kyra\gui.cpp"> </File> <File @@ -134,19 +137,22 @@ RelativePath="..\..\engines\kyra\kyra.h"> </File> <File - RelativePath="..\..\engines\kyra\kyra2.cpp"> + RelativePath="..\..\engines\kyra\kyra_v1.cpp"> + </File> + <File + RelativePath="..\..\engines\kyra\kyra_v1.h"> </File> <File - RelativePath="..\..\engines\kyra\kyra2.h"> + RelativePath="..\..\engines\kyra\kyra_v2.cpp"> </File> <File - RelativePath="..\..\engines\kyra\kyra3.cpp"> + RelativePath="..\..\engines\kyra\kyra_v2.h"> </File> <File - RelativePath="..\..\engines\kyra\kyra3.h"> + RelativePath="..\..\engines\kyra\kyra_v3.cpp"> </File> <File - RelativePath="..\..\engines\kyra\plugin.cpp"> + RelativePath="..\..\engines\kyra\kyra_v3.h"> </File> <File RelativePath="..\..\engines\kyra\resource.cpp"> diff --git a/dists/msvc71/lure.vcproj b/dists/msvc71/lure.vcproj index 98ba70e5a7..a2d984f016 100644 --- a/dists/msvc71/lure.vcproj +++ b/dists/msvc71/lure.vcproj @@ -140,6 +140,9 @@ RelativePath="..\..\engines\lure\decode.h"> </File> <File + RelativePath="..\..\engines\lure\detection.cpp"> + </File> + <File RelativePath="..\..\engines\lure\disk.cpp"> </File> <File @@ -238,12 +241,6 @@ <File RelativePath="..\..\engines\lure\surface.h"> </File> - <File - RelativePath="..\..\engines\lure\system.cpp"> - </File> - <File - RelativePath="..\..\engines\lure\system.h"> - </File> </Files> <Globals> </Globals> diff --git a/dists/msvc71/parallaction.vcproj b/dists/msvc71/parallaction.vcproj index dd7e5891a3..ece38c72ca 100644 --- a/dists/msvc71/parallaction.vcproj +++ b/dists/msvc71/parallaction.vcproj @@ -129,6 +129,9 @@ RelativePath="..\..\engines\parallaction\debug.cpp"> </File> <File + RelativePath="..\..\engines\parallaction\debug.h"> + </File> + <File RelativePath="..\..\engines\parallaction\defs.h"> </File> <File @@ -144,6 +147,9 @@ RelativePath="..\..\engines\parallaction\disk.h"> </File> <File + RelativePath="..\..\engines\parallaction\font.cpp"> + </File> + <File RelativePath="..\..\engines\parallaction\graphics.cpp"> </File> <File @@ -168,12 +174,6 @@ RelativePath="..\..\engines\parallaction\menu.h"> </File> <File - RelativePath="..\..\engines\parallaction\music.cpp"> - </File> - <File - RelativePath="..\..\engines\parallaction\music.h"> - </File> - <File RelativePath="..\..\engines\parallaction\parallaction.cpp"> </File> <File @@ -189,12 +189,21 @@ RelativePath="..\..\engines\parallaction\saveload.cpp"> </File> <File + RelativePath="..\..\engines\parallaction\sound.cpp"> + </File> + <File + RelativePath="..\..\engines\parallaction\sound.h"> + </File> + <File RelativePath="..\..\engines\parallaction\staticres.cpp"> </File> <File RelativePath="..\..\engines\parallaction\walk.cpp"> </File> <File + RelativePath="..\..\engines\parallaction\walk.h"> + </File> + <File RelativePath="..\..\engines\parallaction\zone.cpp"> </File> <File diff --git a/dists/msvc71/saga.vcproj b/dists/msvc71/saga.vcproj index 90a0b481a1..44c72c04b0 100644 --- a/dists/msvc71/saga.vcproj +++ b/dists/msvc71/saga.vcproj @@ -128,6 +128,15 @@ RelativePath="..\..\engines\saga\console.h"> </File> <File + RelativePath="..\..\engines\saga\detection.cpp"> + </File> + <File + RelativePath="..\..\engines\saga\detection_tables.h"> + </File> + <File + RelativePath="..\..\engines\saga\displayinfo.h"> + </File> + <File RelativePath="..\..\engines\saga\events.cpp"> </File> <File @@ -143,9 +152,6 @@ RelativePath="..\..\engines\saga\font_map.cpp"> </File> <File - RelativePath="..\..\engines\saga\game.cpp"> - </File> - <File RelativePath="..\..\engines\saga\gfx.cpp"> </File> <File @@ -227,9 +233,6 @@ RelativePath="..\..\engines\saga\saga.h"> </File> <File - RelativePath="..\..\engines\saga\sagagame.h"> - </File> - <File RelativePath="..\..\engines\saga\sagaresnames.h"> </File> <File diff --git a/dists/msvc71/scumm.vcproj b/dists/msvc71/scumm.vcproj index 715335cc93..e47aa63a18 100644 --- a/dists/msvc71/scumm.vcproj +++ b/dists/msvc71/scumm.vcproj @@ -390,6 +390,15 @@ RelativePath="..\..\engines\scumm\debugger.h"> </File> <File + RelativePath="..\..\engines\scumm\detection.cpp"> + </File> + <File + RelativePath="..\..\engines\scumm\detection.h"> + </File> + <File + RelativePath="..\..\engines\scumm\detection_tables.h"> + </File> + <File RelativePath="..\..\engines\scumm\dialogs.cpp"> </File> <File @@ -480,12 +489,6 @@ RelativePath="..\..\engines\scumm\player_v3a.h"> </File> <File - RelativePath="..\..\engines\scumm\plugin.cpp"> - </File> - <File - RelativePath="..\..\engines\scumm\plugin.h"> - </File> - <File RelativePath="..\..\engines\scumm\resource.cpp"> </File> <File diff --git a/dists/msvc71/scummvm.sln b/dists/msvc71/scummvm.sln index 7bbdb22d5e..989bffb419 100644 --- a/dists/msvc71/scummvm.sln +++ b/dists/msvc71/scummvm.sln @@ -4,6 +4,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scummvm", "scummvm.vcproj", {43C2D921-FEE3-40BE-B58A-A6CA34235731} = {43C2D921-FEE3-40BE-B58A-A6CA34235731} {6CC3E421-779D-4E80-8100-520886A0F9FF} = {6CC3E421-779D-4E80-8100-520886A0F9FF} {AA83E230-EC4A-44DF-896C-4472F20CE168} = {AA83E230-EC4A-44DF-896C-4472F20CE168} + {CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC} = {CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC} {C8AAE83E-198B-4ECA-A877-166827953979} = {C8AAE83E-198B-4ECA-A877-166827953979} {B6AFD548-63D2-40CD-A652-E87095AFCBAF} = {B6AFD548-63D2-40CD-A652-E87095AFCBAF} {B5527758-2F51-4CCD-AAE1-B0E28654BD6A} = {B5527758-2F51-4CCD-AAE1-B0E28654BD6A} @@ -73,6 +74,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parallaction", "parallactio ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cruise", "cruise.vcproj", "{CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -141,6 +146,10 @@ Global {0068957B-E2E1-4988-8C87-D541D84DAF20}.Debug.Build.0 = Debug|Win32 {0068957B-E2E1-4988-8C87-D541D84DAF20}.Release.ActiveCfg = Release|Win32 {0068957B-E2E1-4988-8C87-D541D84DAF20}.Release.Build.0 = Release|Win32 + {CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC}.Debug.ActiveCfg = Debug|Win32 + {CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC}.Debug.Build.0 = Debug|Win32 + {CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC}.Release.ActiveCfg = Release|Win32 + {CD9AEE36-CEBD-40CE-A6B3-B71523AB8DEC}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/dists/msvc71/scummvm.vcproj b/dists/msvc71/scummvm.vcproj index cf87be6f3f..d198329046 100644 --- a/dists/msvc71/scummvm.vcproj +++ b/dists/msvc71/scummvm.vcproj @@ -38,7 +38,7 @@ Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" - AdditionalDependencies="winmm.lib sdl.lib zdll.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib agi_debug/agi.lib cine_debug/cine.lib gob_debug/gob.lib kyra_debug/kyra.lib lure_debug/lure.lib queen_debug/queen.lib saga_debug/saga.lib scumm_debug/scumm.lib agos_debug/agos.lib sky_debug/sky.lib sword1_debug/sword1.lib sword2_debug/sword2.lib touche_debug/touche.lib parallaction_debug/parallaction.lib" + AdditionalDependencies="winmm.lib sdl.lib zdll.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib agi_debug/agi.lib cine_debug/cine.lib gob_debug/gob.lib kyra_debug/kyra.lib lure_debug/lure.lib queen_debug/queen.lib saga_debug/saga.lib scumm_debug/scumm.lib agos_debug/agos.lib sky_debug/sky.lib sword1_debug/sword1.lib sword2_debug/sword2.lib touche_debug/touche.lib parallaction_debug/parallaction.lib cruise_debug/cruise.lib" OutputFile="$(OutDir)/scummvm.exe" LinkIncremental="2" IgnoreDefaultLibraryNames="libcmtd.lib" @@ -97,7 +97,7 @@ Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" - AdditionalDependencies="winmm.lib sdl.lib zdll.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib agi_release/agi.lib cine_release/cine.lib gob_release/gob.lib kyra_release/kyra.lib lure_release/lure.lib queen_release/queen.lib saga_release/saga.lib scumm_release/scumm.lib agos_release/agos.lib sky_release/sky.lib sword1_release/sword1.lib sword2_release/sword2.lib touche_release/touche.lib parallaction_release/parallaction.lib" + AdditionalDependencies="winmm.lib sdl.lib zdll.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib agi_release/agi.lib cine_release/cine.lib gob_release/gob.lib kyra_release/kyra.lib lure_release/lure.lib queen_release/queen.lib saga_release/saga.lib scumm_release/scumm.lib agos_release/agos.lib sky_release/sky.lib sword1_release/sword1.lib sword2_release/sword2.lib touche_release/touche.lib parallaction_release/parallaction.lib cruise_release/cruise.lib" OutputFile="$(OutDir)/scummvm.exe" LinkIncremental="1" SuppressStartupBanner="TRUE" @@ -221,6 +221,9 @@ RelativePath="..\..\common\hashmap.h"> </File> <File + RelativePath="..\..\common\iff_container.h"> + </File> + <File RelativePath="..\..\common\list.h"> </File> <File @@ -303,6 +306,12 @@ RelativePath="..\..\sound\adpcm.h"> </File> <File + RelativePath="..\..\sound\aiff.cpp"> + </File> + <File + RelativePath="..\..\sound\aiff.h"> + </File> + <File RelativePath="..\..\sound\audiocd.cpp"> </File> <File @@ -327,6 +336,12 @@ RelativePath="..\..\sound\fmopl.h"> </File> <File + RelativePath="..\..\sound\iff.cpp"> + </File> + <File + RelativePath="..\..\sound\iff.h"> + </File> + <File RelativePath="..\..\sound\mididrv.cpp"> </File> <File @@ -499,6 +514,12 @@ <File RelativePath="..\..\sound\mods\rjp1.h"> </File> + <File + RelativePath="..\..\sound\mods\soundfx.cpp"> + </File> + <File + RelativePath="..\..\sound\mods\soundfx.h"> + </File> </Filter> </Filter> <Filter @@ -595,6 +616,16 @@ RelativePath="..\..\backends\saves\savefile.cpp"> </File> </Filter> + <Filter + Name="events" + Filter=""> + <File + RelativePath="..\..\backends\events\default\default-events.cpp"> + </File> + <File + RelativePath="..\..\backends\events\default\default-events.h"> + </File> + </Filter> </Filter> <Filter Name="gui" @@ -793,10 +824,22 @@ RelativePath="..\..\graphics\fontman.h"> </File> <File - RelativePath="..\..\graphics\ilbm.cpp"> + RelativePath="..\..\graphics\iff.cpp"> + <FileConfiguration + Name="Debug|Win32"> + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)/$(InputName)1.obj"/> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32"> + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)/$(InputName)1.obj"/> + </FileConfiguration> </File> <File - RelativePath="..\..\graphics\ilbm.h"> + RelativePath="..\..\graphics\iff.h"> </File> <File RelativePath="..\..\graphics\imagedec.cpp"> diff --git a/dists/msvc71/touche.vcproj b/dists/msvc71/touche.vcproj index d46197bb6c..5cd7de5391 100644 --- a/dists/msvc71/touche.vcproj +++ b/dists/msvc71/touche.vcproj @@ -110,6 +110,9 @@ </References> <Files> <File + RelativePath="..\..\engines\touche\detection.cpp"> + </File> + <File RelativePath="..\..\engines\touche\graphics.cpp"> </File> <File @@ -125,9 +128,6 @@ RelativePath="..\..\engines\touche\opcodes.cpp"> </File> <File - RelativePath="..\..\engines\touche\plugin.cpp"> - </File> - <File RelativePath="..\..\engines\touche\resource.cpp"> </File> <File diff --git a/dists/msvc8/agi.vcproj b/dists/msvc8/agi.vcproj index 4f9ea61c3c..c858028554 100644 --- a/dists/msvc8/agi.vcproj +++ b/dists/msvc8/agi.vcproj @@ -277,10 +277,6 @@ > </File> <File - RelativePath="..\..\engines\agi\patches.cpp" - > - </File> - <File RelativePath="..\..\engines\agi\picture.cpp" > </File> diff --git a/dists/msvc8/agos.vcproj b/dists/msvc8/agos.vcproj index cc86090f25..a0aabf03ea 100644 --- a/dists/msvc8/agos.vcproj +++ b/dists/msvc8/agos.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="agos" ProjectGUID="{E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA}" + RootNamespace="agos" Keyword="Win32Proj" > <Platforms> @@ -91,6 +92,7 @@ ConfigurationType="4" ATLMinimizesCRunTimeLibraryUsage="true" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -204,15 +206,19 @@ > </File> <File - RelativePath="..\..\engines\agos\draw.cpp" + RelativePath="..\..\engines\agos\detection.cpp" > </File> <File - RelativePath="..\..\engines\agos\event.cpp" + RelativePath="..\..\engines\agos\detection_tables.h" > </File> <File - RelativePath="..\..\engines\agos\game.cpp" + RelativePath="..\..\engines\agos\draw.cpp" + > + </File> + <File + RelativePath="..\..\engines\agos\event.cpp" > </File> <File diff --git a/dists/msvc8/cine.vcproj b/dists/msvc8/cine.vcproj index 9372928494..02d319b1aa 100644 --- a/dists/msvc8/cine.vcproj +++ b/dists/msvc8/cine.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="cine" ProjectGUID="{1CA4AC50-5426-433A-8B5E-FFE39568098E}" + RootNamespace="cine" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="cine_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -259,14 +261,6 @@ > </File> <File - RelativePath="..\..\engines\cine\resource.cpp" - > - </File> - <File - RelativePath="..\..\engines\cine\resource.h" - > - </File> - <File RelativePath="..\..\engines\cine\script.cpp" > </File> @@ -275,19 +269,11 @@ > </File> <File - RelativePath="..\..\engines\cine\sfx_player.cpp" - > - </File> - <File - RelativePath="..\..\engines\cine\sfx_player.h" - > - </File> - <File - RelativePath="..\..\engines\cine\sound_driver.cpp" + RelativePath="..\..\engines\cine\sound.cpp" > </File> <File - RelativePath="..\..\engines\cine\sound_driver.h" + RelativePath="..\..\engines\cine\sound.h" > </File> <File diff --git a/dists/msvc8/cruise.vcproj b/dists/msvc8/cruise.vcproj new file mode 100644 index 0000000000..68c19e0db5 --- /dev/null +++ b/dists/msvc8/cruise.vcproj @@ -0,0 +1,394 @@ +<?xml version="1.0" encoding="windows-1250"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8,00" + Name="cruise" + ProjectGUID="{8863B00B-059A-471E-876D-A955ECEFD0D2}" + RootNamespace="cruise" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="cruise_Debug" + IntermediateDirectory="cruise_Debug" + ConfigurationType="4" + CharacterSet="2" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702 /wd4996" + Optimization="0" + AdditionalIncludeDirectories="../..;../../engines" + PreprocessorDefinitions="WIN32;_DEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" + MinimalRebuild="true" + ExceptionHandling="1" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + BufferSecurityCheck="true" + EnableFunctionLevelLinking="true" + ForceConformanceInForLoopScope="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + SuppressStartupBanner="false" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/cruise.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="cruise_Release" + IntermediateDirectory="cruise_Release" + ConfigurationType="4" + CharacterSet="2" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/wd4201 /wd4512 /wd4511 /wd4100 /wd4121 /wd4310 /wd4706 /wd4127 /wd4189 /wd4702 /wd4996" + Optimization="2" + InlineFunctionExpansion="1" + OmitFramePointers="true" + AdditionalIncludeDirectories="../..;../../engines" + PreprocessorDefinitions="WIN32;NDEBUG;USE_ZLIB;USE_MAD;USE_VORBIS" + StringPooling="true" + ExceptionHandling="1" + RuntimeLibrary="0" + BufferSecurityCheck="false" + EnableFunctionLevelLinking="false" + ForceConformanceInForLoopScope="true" + UsePrecompiledHeader="0" + WarningLevel="4" + WarnAsError="true" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLibrarianTool" + OutputFile="$(OutDir)/cruise.lib" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <File + RelativePath="..\..\engines\cruise\actor.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\actor.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\background.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\background.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\backgroundIncrust.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\backgroundIncrust.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\cell.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\cell.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\cruise.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\cruise.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\cruise_main.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\cruise_main.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\ctp.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\ctp.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\dataLoader.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\dataLoader.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\decompiler.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\delphine-unpack.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\detection.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\font.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\font.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\fontCharacterTable.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\fontCharacterTable.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\function.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\function.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\gfxModule.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\gfxModule.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\linker.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\linker.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\mainDraw.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\mainDraw.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\menu.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\menu.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\mouse.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\mouse.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\object.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\object.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\overlay.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\overlay.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\perso.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\perso.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\polys.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\polys.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\saveload.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\saveload.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\script.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\script.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\stack.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\stack.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\stringSupport.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\stringSupport.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\various.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\various.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\vars.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\vars.h" + > + </File> + <File + RelativePath="..\..\engines\cruise\volume.cpp" + > + </File> + <File + RelativePath="..\..\engines\cruise\volume.h" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/dists/msvc8/gob.vcproj b/dists/msvc8/gob.vcproj index 09646cd753..5def46a7e2 100644 --- a/dists/msvc8/gob.vcproj +++ b/dists/msvc8/gob.vcproj @@ -91,6 +91,7 @@ IntermediateDirectory="gob_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -123,7 +124,7 @@ ForceConformanceInForLoopScope="true" UsePrecompiledHeader="0" WarningLevel="4" - WarnAsError="true" + WarnAsError="false" DebugInformationFormat="0" /> <Tool @@ -160,14 +161,6 @@ </References> <Files> <File - RelativePath="..\..\engines\gob\anim.cpp" - > - </File> - <File - RelativePath="..\..\engines\gob\anim.h" - > - </File> - <File RelativePath="..\..\engines\gob\cdrom.cpp" > </File> @@ -264,6 +257,18 @@ > </File> <File + RelativePath="..\..\engines\gob\goblin_v3.cpp" + > + </File> + <File + RelativePath="..\..\engines\gob\imd.cpp" + > + </File> + <File + RelativePath="..\..\engines\gob\imd.h" + > + </File> + <File RelativePath="..\..\engines\gob\init.cpp" > </File> @@ -280,6 +285,10 @@ > </File> <File + RelativePath="..\..\engines\gob\init_v3.cpp" + > + </File> + <File RelativePath="..\..\engines\gob\inter.cpp" > </File> @@ -300,6 +309,10 @@ > </File> <File + RelativePath="..\..\engines\gob\inter_v3.cpp" + > + </File> + <File RelativePath="..\..\engines\gob\map.cpp" > </File> @@ -340,14 +353,6 @@ > </File> <File - RelativePath="..\..\engines\gob\pack.cpp" - > - </File> - <File - RelativePath="..\..\engines\gob\pack.h" - > - </File> - <File RelativePath="..\..\engines\gob\palanim.cpp" > </File> @@ -372,35 +377,43 @@ > </File> <File - RelativePath="..\..\engines\gob\scenery.cpp" + RelativePath="..\..\engines\gob\saveload.cpp" > </File> <File - RelativePath="..\..\engines\gob\scenery.h" + RelativePath="..\..\engines\gob\saveload.h" > </File> <File - RelativePath="..\..\engines\gob\scenery_v1.cpp" + RelativePath="..\..\engines\gob\saveload_v2.cpp" > </File> <File - RelativePath="..\..\engines\gob\scenery_v2.cpp" + RelativePath="..\..\engines\gob\saveload_v3.cpp" > </File> <File - RelativePath="..\..\engines\gob\sound.cpp" + RelativePath="..\..\engines\gob\scenery.cpp" > </File> <File - RelativePath="..\..\engines\gob\sound.h" + RelativePath="..\..\engines\gob\scenery.h" + > + </File> + <File + RelativePath="..\..\engines\gob\scenery_v1.cpp" > </File> <File - RelativePath="..\..\engines\gob\timer.cpp" + RelativePath="..\..\engines\gob\scenery_v2.cpp" > </File> <File - RelativePath="..\..\engines\gob\timer.h" + RelativePath="..\..\engines\gob\sound.cpp" + > + </File> + <File + RelativePath="..\..\engines\gob\sound.h" > </File> <File diff --git a/dists/msvc8/kyra.vcproj b/dists/msvc8/kyra.vcproj index 1634a4f432..0c32b1ee8a 100644 --- a/dists/msvc8/kyra.vcproj +++ b/dists/msvc8/kyra.vcproj @@ -91,6 +91,7 @@ IntermediateDirectory="kyra_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -176,6 +177,10 @@ > </File> <File + RelativePath="..\..\engines\kyra\detection.cpp" + > + </File> + <File RelativePath="..\..\engines\kyra\gui.cpp" > </File> @@ -192,23 +197,27 @@ > </File> <File - RelativePath="..\..\engines\kyra\kyra2.cpp" + RelativePath="..\..\engines\kyra\kyra_v1.cpp" + > + </File> + <File + RelativePath="..\..\engines\kyra\kyra_v1.h" > </File> <File - RelativePath="..\..\engines\kyra\kyra2.h" + RelativePath="..\..\engines\kyra\kyra_v2.cpp" > </File> <File - RelativePath="..\..\engines\kyra\kyra3.cpp" + RelativePath="..\..\engines\kyra\kyra_v2.h" > </File> <File - RelativePath="..\..\engines\kyra\kyra3.h" + RelativePath="..\..\engines\kyra\kyra_v3.cpp" > </File> <File - RelativePath="..\..\engines\kyra\plugin.cpp" + RelativePath="..\..\engines\kyra\kyra_v3.h" > </File> <File diff --git a/dists/msvc8/lure.vcproj b/dists/msvc8/lure.vcproj index 3668736547..74f03c39c9 100644 --- a/dists/msvc8/lure.vcproj +++ b/dists/msvc8/lure.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="lure" ProjectGUID="{1A1CA028-61B5-4A6C-A918-F5D8721AB1AC}" + RootNamespace="lure" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="lure_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -199,6 +201,10 @@ > </File> <File + RelativePath="..\..\engines\lure\detection.cpp" + > + </File> + <File RelativePath="..\..\engines\lure\disk.cpp" > </File> @@ -330,14 +336,6 @@ RelativePath="..\..\engines\lure\surface.h" > </File> - <File - RelativePath="..\..\engines\lure\system.cpp" - > - </File> - <File - RelativePath="..\..\engines\lure\system.h" - > - </File> </Files> <Globals> </Globals> diff --git a/dists/msvc8/parallaction.vcproj b/dists/msvc8/parallaction.vcproj index 1a66d05325..c3f04c0e58 100644 --- a/dists/msvc8/parallaction.vcproj +++ b/dists/msvc8/parallaction.vcproj @@ -185,6 +185,10 @@ > </File> <File + RelativePath="..\..\engines\parallaction\debug.h" + > + </File> + <File RelativePath="..\..\engines\parallaction\defs.h" > </File> @@ -205,6 +209,10 @@ > </File> <File + RelativePath="..\..\engines\parallaction\font.cpp" + > + </File> + <File RelativePath="..\..\engines\parallaction\graphics.cpp" > </File> @@ -237,31 +245,31 @@ > </File> <File - RelativePath="..\..\engines\parallaction\music.cpp" + RelativePath="..\..\engines\parallaction\parallaction.cpp" > </File> <File - RelativePath="..\..\engines\parallaction\music.h" + RelativePath="..\..\engines\parallaction\parallaction.h" > </File> <File - RelativePath="..\..\engines\parallaction\parallaction.cpp" + RelativePath="..\..\engines\parallaction\parser.cpp" > </File> <File - RelativePath="..\..\engines\parallaction\parallaction.h" + RelativePath="..\..\engines\parallaction\parser.h" > </File> <File - RelativePath="..\..\engines\parallaction\parser.cpp" + RelativePath="..\..\engines\parallaction\saveload.cpp" > </File> <File - RelativePath="..\..\engines\parallaction\parser.h" + RelativePath="..\..\engines\parallaction\sound.cpp" > </File> <File - RelativePath="..\..\engines\parallaction\saveload.cpp" + RelativePath="..\..\engines\parallaction\sound.h" > </File> <File @@ -273,6 +281,10 @@ > </File> <File + RelativePath="..\..\engines\parallaction\walk.h" + > + </File> + <File RelativePath="..\..\engines\parallaction\zone.cpp" > </File> diff --git a/dists/msvc8/queen.vcproj b/dists/msvc8/queen.vcproj index 14194d60e2..8bd9f12237 100644 --- a/dists/msvc8/queen.vcproj +++ b/dists/msvc8/queen.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="queen" ProjectGUID="{6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7}" + RootNamespace="queen" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="queen_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" diff --git a/dists/msvc8/saga.vcproj b/dists/msvc8/saga.vcproj index 1951c4dfd7..7f31f781a6 100644 --- a/dists/msvc8/saga.vcproj +++ b/dists/msvc8/saga.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="saga" ProjectGUID="{676DB4C5-9A3E-4EE1-8483-EBB79DC0700E}" + RootNamespace="saga" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="saga_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -183,6 +185,18 @@ > </File> <File + RelativePath="..\..\engines\saga\detection.cpp" + > + </File> + <File + RelativePath="..\..\engines\saga\detection_tables.h" + > + </File> + <File + RelativePath="..\..\engines\saga\displayinfo.h" + > + </File> + <File RelativePath="..\..\engines\saga\events.cpp" > </File> @@ -203,10 +217,6 @@ > </File> <File - RelativePath="..\..\engines\saga\game.cpp" - > - </File> - <File RelativePath="..\..\engines\saga\gfx.cpp" > </File> @@ -299,10 +309,6 @@ > </File> <File - RelativePath="..\..\engines\saga\resnames.h" - > - </File> - <File RelativePath="..\..\engines\saga\rscfile.cpp" > </File> @@ -319,6 +325,10 @@ > </File> <File + RelativePath="..\..\engines\saga\sagaresnames.h" + > + </File> + <File RelativePath="..\..\engines\saga\saveload.cpp" > </File> diff --git a/dists/msvc8/scumm.vcproj b/dists/msvc8/scumm.vcproj index cec931fa29..324b5173df 100644 --- a/dists/msvc8/scumm.vcproj +++ b/dists/msvc8/scumm.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="scumm" ProjectGUID="{B6AFD548-63D2-40CD-A652-E87095AFCBAF}" + RootNamespace="scumm" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="scumm_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -528,6 +530,18 @@ > </File> <File + RelativePath="..\..\engines\scumm\detection.cpp" + > + </File> + <File + RelativePath="..\..\engines\scumm\detection.h" + > + </File> + <File + RelativePath="..\..\engines\scumm\detection_tables.h" + > + </File> + <File RelativePath="..\..\engines\scumm\dialogs.cpp" > </File> @@ -648,14 +662,6 @@ > </File> <File - RelativePath="..\..\engines\scumm\plugin.cpp" - > - </File> - <File - RelativePath="..\..\engines\scumm\plugin.h" - > - </File> - <File RelativePath="..\..\engines\scumm\resource.cpp" > </File> diff --git a/dists/msvc8/scummvm.sln b/dists/msvc8/scummvm.sln index 73e47aa25c..3f36ba78e9 100644 --- a/dists/msvc8/scummvm.sln +++ b/dists/msvc8/scummvm.sln @@ -4,17 +4,19 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scummvm", "scummvm.vcproj", ProjectSection(ProjectDependencies) = postProject {6CC3E421-779D-4E80-8100-520886A0F9FF} = {6CC3E421-779D-4E80-8100-520886A0F9FF} {1A1CA028-61B5-4A6C-A918-F5D8721AB1AC} = {1A1CA028-61B5-4A6C-A918-F5D8721AB1AC} - {C8AAE83E-198B-4ECA-A877-166827953979} = {C8AAE83E-198B-4ECA-A877-166827953979} - {B6AFD548-63D2-40CD-A652-E87095AFCBAF} = {B6AFD548-63D2-40CD-A652-E87095AFCBAF} - {1CA4AC50-5426-433A-8B5E-FFE39568098E} = {1CA4AC50-5426-433A-8B5E-FFE39568098E} - {D4986356-D0BB-4981-924A-854157BDF11F} = {D4986356-D0BB-4981-924A-854157BDF11F} - {B5527758-2F51-4CCD-AAE1-B0E28654BD6A} = {B5527758-2F51-4CCD-AAE1-B0E28654BD6A} - {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7} = {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7} - {F5F57066-CDF4-4F80-B9E7-7F4D21850D6E} = {F5F57066-CDF4-4F80-B9E7-7F4D21850D6E} - {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA} = {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA} - {976D947A-A45F-4437-991E-412F695C64C7} = {976D947A-A45F-4437-991E-412F695C64C7} - {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC} = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC} + {0068957B-E2E1-4988-8C87-D541D84DAF20} = {0068957B-E2E1-4988-8C87-D541D84DAF20} + {8863B00B-059A-471E-876D-A955ECEFD0D2} = {8863B00B-059A-471E-876D-A955ECEFD0D2} {676DB4C5-9A3E-4EE1-8483-EBB79DC0700E} = {676DB4C5-9A3E-4EE1-8483-EBB79DC0700E} + {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC} = {9D9A98A0-F88F-4CA2-B8FF-462470EBE3EC} + {976D947A-A45F-4437-991E-412F695C64C7} = {976D947A-A45F-4437-991E-412F695C64C7} + {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA} = {E0EC9C72-A33E-49DA-B1DC-BB44B9799BFA} + {F5F57066-CDF4-4F80-B9E7-7F4D21850D6E} = {F5F57066-CDF4-4F80-B9E7-7F4D21850D6E} + {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7} = {6A55AF61-7CA1-49E0-9385-59C1FE9D4DB7} + {B5527758-2F51-4CCD-AAE1-B0E28654BD6A} = {B5527758-2F51-4CCD-AAE1-B0E28654BD6A} + {D4986356-D0BB-4981-924A-854157BDF11F} = {D4986356-D0BB-4981-924A-854157BDF11F} + {1CA4AC50-5426-433A-8B5E-FFE39568098E} = {1CA4AC50-5426-433A-8B5E-FFE39568098E} + {B6AFD548-63D2-40CD-A652-E87095AFCBAF} = {B6AFD548-63D2-40CD-A652-E87095AFCBAF} + {C8AAE83E-198B-4ECA-A877-166827953979} = {C8AAE83E-198B-4ECA-A877-166827953979} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sword2", "sword2.vcproj", "{6CC3E421-779D-4E80-8100-520886A0F9FF}" @@ -45,6 +47,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "touche", "touche.vcproj", " EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "parallaction", "parallaction.vcproj", "{0068957B-E2E1-4988-8C87-D541D84DAF20}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cruise", "cruise.vcproj", "{8863B00B-059A-471E-876D-A955ECEFD0D2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -111,6 +115,10 @@ Global {0068957B-E2E1-4988-8C87-D541D84DAF20}.Debug|Win32.Build.0 = Debug|Win32 {0068957B-E2E1-4988-8C87-D541D84DAF20}.Release|Win32.ActiveCfg = Release|Win32 {0068957B-E2E1-4988-8C87-D541D84DAF20}.Release|Win32.Build.0 = Release|Win32 + {8863B00B-059A-471E-876D-A955ECEFD0D2}.Debug|Win32.ActiveCfg = Debug|Win32 + {8863B00B-059A-471E-876D-A955ECEFD0D2}.Debug|Win32.Build.0 = Debug|Win32 + {8863B00B-059A-471E-876D-A955ECEFD0D2}.Release|Win32.ActiveCfg = Release|Win32 + {8863B00B-059A-471E-876D-A955ECEFD0D2}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/dists/msvc8/scummvm.vcproj b/dists/msvc8/scummvm.vcproj index eace1d08a5..5edbdff265 100644 --- a/dists/msvc8/scummvm.vcproj +++ b/dists/msvc8/scummvm.vcproj @@ -68,7 +68,7 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib sword1_debug/sword1.lib sword2_debug/sword2.lib lure_debug/lure.lib cine_debug/cine.lib kyra_debug/kyra.lib gob_debug/gob.lib queen_debug/queen.lib saga_debug/saga.lib agi_debug/agi.lib scumm_debug/scumm.lib agos_debug/agos.lib sky_debug/sky.lib parallaction_debug/parallaction.lib" + AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib sword1_debug/sword1.lib sword2_debug/sword2.lib lure_debug/lure.lib cine_debug/cine.lib cruise_debug/cruise.lib kyra_debug/kyra.lib gob_debug/gob.lib queen_debug/queen.lib saga_debug/saga.lib agi_debug/agi.lib scumm_debug/scumm.lib agos_debug/agos.lib sky_debug/sky.lib parallaction_debug/parallaction.lib" OutputFile="$(OutDir)/scummvm.exe" LinkIncremental="2" IgnoreDefaultLibraryNames="libc.lib;libcmt.lib" @@ -108,6 +108,7 @@ IntermediateDirectory="scummvm_Release" ConfigurationType="1" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" @@ -156,15 +157,16 @@ /> <Tool Name="VCLinkerTool" - AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib saga_release/saga.lib agi_release/agi.lib sword1_release/sword1.lib sword2_release/sword2.lib lure_release/lure.lib cine_release/cine.lib kyra_release/kyra.lib gob_release/gob.lib queen_release/queen.lib scumm_release/scumm.lib agos_release/agos.lib sky_release/sky.lib parallaction_release/parallaction.lib" + AdditionalDependencies="winmm.lib sdl.lib zlib.lib libmad.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib libmpeg2.lib saga_release/saga.lib agi_release/agi.lib sword1_release/sword1.lib sword2_release/sword2.lib lure_release/lure.lib cine_release/cine.lib cruise_release/cruise.lib kyra_release/kyra.lib gob_release/gob.lib queen_release/queen.lib scumm_release/scumm.lib agos_release/agos.lib sky_release/sky.lib parallaction_release/parallaction.lib" OutputFile="$(OutDir)/scummvm.exe" LinkIncremental="1" SuppressStartupBanner="true" IgnoreDefaultLibraryNames="libc.lib" GenerateDebugInformation="false" - SubSystem="2" + SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" + EntryPointSymbol="WinMainCRTStartup" TargetMachine="1" /> <Tool @@ -280,6 +282,10 @@ > </File> <File + RelativePath="..\..\common\events.h" + > + </File> + <File RelativePath="..\..\common\file.cpp" > </File> @@ -290,24 +296,6 @@ <File RelativePath="..\..\common\fs.cpp" > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)\$(InputName)1.obj" - XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - ObjectFile="$(IntDir)\$(InputName)1.obj" - XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" - /> - </FileConfiguration> </File> <File RelativePath="..\..\common\fs.h" @@ -330,6 +318,10 @@ > </File> <File + RelativePath="..\..\common\iff_container.h" + > + </File> + <File RelativePath="..\..\common\list.h" > </File> @@ -350,6 +342,10 @@ > </File> <File + RelativePath="..\..\common\noncopyable.h" + > + </File> + <File RelativePath="..\..\common\pack-end.h" > </File> @@ -438,6 +434,14 @@ > </File> <File + RelativePath="..\..\sound\aiff.cpp" + > + </File> + <File + RelativePath="..\..\sound\aiff.h" + > + </File> + <File RelativePath="..\..\sound\audiocd.cpp" > </File> @@ -470,6 +474,32 @@ > </File> <File + RelativePath="..\..\sound\iff.cpp" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\sound\iff.h" + > + </File> + <File RelativePath="..\..\sound\mididrv.cpp" > </File> @@ -750,6 +780,14 @@ RelativePath="..\..\sound\mods\rjp1.h" > </File> + <File + RelativePath="..\..\sound\mods\soundfx.cpp" + > + </File> + <File + RelativePath="..\..\sound\mods\soundfx.h" + > + </File> </Filter> </Filter> <Filter @@ -868,6 +906,22 @@ > </File> </Filter> + <Filter + Name="events" + > + <Filter + Name="default" + > + <File + RelativePath="..\..\backends\events\default\default-events.cpp" + > + </File> + <File + RelativePath="..\..\backends\events\default\default-events.h" + > + </File> + </Filter> + </Filter> </Filter> <Filter Name="gui" @@ -1113,11 +1167,11 @@ > </File> <File - RelativePath="..\..\graphics\ilbm.cpp" + RelativePath="..\..\graphics\iff.cpp" > </File> <File - RelativePath="..\..\graphics\ilbm.h" + RelativePath="..\..\graphics\iff.h" > </File> <File diff --git a/dists/msvc8/sky.vcproj b/dists/msvc8/sky.vcproj index 58f8116639..58547b5026 100644 --- a/dists/msvc8/sky.vcproj +++ b/dists/msvc8/sky.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="sky" ProjectGUID="{B5527758-2F51-4CCD-AAE1-B0E28654BD6A}" + RootNamespace="sky" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="sky_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" diff --git a/dists/msvc8/sword1.vcproj b/dists/msvc8/sword1.vcproj index 57be2596e9..6fd50e4efc 100644 --- a/dists/msvc8/sword1.vcproj +++ b/dists/msvc8/sword1.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="sword1" ProjectGUID="{C8AAE83E-198B-4ECA-A877-166827953979}" + RootNamespace="sword1" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="sword1_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" diff --git a/dists/msvc8/sword2.vcproj b/dists/msvc8/sword2.vcproj index 38def46c26..4a2437b1ff 100644 --- a/dists/msvc8/sword2.vcproj +++ b/dists/msvc8/sword2.vcproj @@ -4,6 +4,7 @@ Version="8,00" Name="sword2" ProjectGUID="{6CC3E421-779D-4E80-8100-520886A0F9FF}" + RootNamespace="sword2" Keyword="Win32Proj" > <Platforms> @@ -90,6 +91,7 @@ IntermediateDirectory="sword2_Release" ConfigurationType="4" CharacterSet="2" + WholeProgramOptimization="1" > <Tool Name="VCPreBuildEventTool" diff --git a/dists/msvc8/touche.vcproj b/dists/msvc8/touche.vcproj index c60983264d..4bbe7dee0d 100644 --- a/dists/msvc8/touche.vcproj +++ b/dists/msvc8/touche.vcproj @@ -161,6 +161,10 @@ </References> <Files> <File + RelativePath="..\..\engines\touche\detection.cpp" + > + </File> + <File RelativePath="..\..\engines\touche\graphics.cpp" > </File> @@ -181,10 +185,6 @@ > </File> <File - RelativePath="..\..\engines\touche\plugin.cpp" - > - </File> - <File RelativePath="..\..\engines\touche\resource.cpp" > </File> diff --git a/dists/scummvm.desktop b/dists/scummvm.desktop index 5a0f88b355..c4679ad90a 100644 --- a/dists/scummvm.desktop +++ b/dists/scummvm.desktop @@ -1,9 +1,13 @@ [Desktop Entry] Encoding=UTF-8 Name=ScummVM -Name[pl]=ScummVM Comment=Interpreter for several adventure games Comment[pl]=Interpreter graficznych gier przygodowych +Comment[sv]=Tolk f旦r flera 辰ventyrsspel +Comment[he]=廚廨廩 廖廚廨 廩廡 廨廚廬廡廬 +Comment[de]=Interpreter f端r diverse Abenteuerspiele +Comment[es]=Int辿rprete para varias aventuras gr叩ficas +Comment[ca]=Int竪rpret per diverses aventures grfiques Exec=scummvm Icon=scummvm.xpm Terminal=false diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index 626ba8f7fe..5e3dc23e6a 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -26,7 +26,7 @@ #include "common/events.h" #include "common/file.h" -#include "common/fs.h" +//#include "common/fs.h" #include "common/savefile.h" #include "common/config-manager.h" @@ -419,6 +419,15 @@ int AgiEngine::agiInit() { if (ec == errOK) ec = _loader->loadResource(rLOGIC, 0); + + if (ConfMan.hasKey("save_slot")) { + char saveNameBuffer[256]; + + snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot")); + + loadGame(saveNameBuffer, false); // Do not check game id + } + return ec; } diff --git a/engines/agi/agi.h b/engines/agi/agi.h index 5409f3e938..a1f979a28b 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -112,6 +112,26 @@ enum AgiGameFeatures { GF_FANMADE = (1 << 6) }; +enum AgiGameID { + GID_AGIDEMO, + GID_BC, + GID_DDP, + GID_GOLDRUSH, + GID_KQ1, + GID_KQ2, + GID_KQ3, + GID_KQ4, + GID_LSL1, + GID_MH1, + GID_MH2, + GID_MIXEDUP, + GID_PQ1, + GID_SQ1, + GID_SQ2, + GID_XMASCARD, + GID_FANMADE // TODO: Should this be extended to include all fanmade games? +}; + struct AGIGameDescription; enum { @@ -507,6 +527,7 @@ public: } const AGIGameDescription *_gameDescription; + uint32 getGameID() const; uint32 getFeatures() const; uint16 getVersion() const; Common::Platform getPlatform() const; @@ -543,7 +564,7 @@ public: int saveGame(const char *fileName, const char *saveName); int saveGameDialog(); int saveGameSimple(); - int loadGame(const char *fileName); + int loadGame(const char *fileName, bool checkId = true); int loadGameDialog(); int loadGameSimple(); diff --git a/engines/agi/agi_v3.cpp b/engines/agi/agi_v3.cpp index 4729058484..7b295f1663 100644 --- a/engines/agi/agi_v3.cpp +++ b/engines/agi/agi_v3.cpp @@ -62,6 +62,7 @@ int AgiLoader_v3::detectGame() { f.toLowercase(); if (f.hasSuffix("vol.0")) { + memset(_vm->_game.name, 0, 8); strncpy(_vm->_game.name, f.c_str(), f.size() > 5 ? f.size() - 5 : f.size()); debugC(3, kDebugLevelMain, "game.name = %s", _vm->_game.name); _intVersion = 0x3149; // setup for 3.002.149 diff --git a/engines/agi/checks.cpp b/engines/agi/checks.cpp index d77afce0d3..d721d844e2 100644 --- a/engines/agi/checks.cpp +++ b/engines/agi/checks.cpp @@ -74,21 +74,21 @@ int AgiEngine::checkCollision(VtEntry *v) { continue; /* Same y, return error! */ - if (v->yPos == u->yPos) - goto return_1; + if (v->yPos == u->yPos) { + debugC(4, kDebugLevelSprites, "check returns 1 (object %d)", v->entry); + return 1; + } /* Crossed the baseline, return error! */ if ((v->yPos > u->yPos && v->yPos2 < u->yPos2) || (v->yPos < u->yPos && v->yPos2 > u->yPos2)) { - goto return_1; + debugC(4, kDebugLevelSprites, "check returns 1 (object %d)", v->entry); + return 1; } } return 0; - return_1: - debugC(4, kDebugLevelSprites, "check returns 1 (object %d)", v->entry); - return 1; } int AgiEngine::checkPriority(VtEntry *v) { @@ -104,8 +104,15 @@ int AgiEngine::checkPriority(VtEntry *v) { water = 0; pass = 1; - if (v->priority == 0x0f) - goto check_ego; + if (v->priority == 0x0f) { + // Check ego + if (v->entry == 0) { + setflag(fEgoTouchedP2, trigger ? true : false); + setflag(fEgoWater, water ? true : false); + } + + return pass; + } water = 1; @@ -147,7 +154,7 @@ int AgiEngine::checkPriority(VtEntry *v) { pass = 0; } -check_ego: + // Check ego if (v->entry == 0) { setflag(fEgoTouchedP2, trigger ? true : false); setflag(fEgoWater, water ? true : false); @@ -206,7 +213,7 @@ void AgiEngine::updatePosition() { x = 0; border = 4; } else if (x <= 0 && agiGetRelease() == 0x3086) { /* KQ4 */ - x = 0; /* See bug #590462 */ + x = 0; /* See Sarien bug #590462 */ border = 4; } else if (v->entry == 0 && x == 0 && v->flags & ADJ_EGO_XY) { /* Extra test to walk west clicking the mouse */ diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index 85599a236d..6e485eb92a 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -252,7 +252,7 @@ process_key: goto process_key; } - /* commented out to close bug #438872 + /* commented out to close Sarien bug #438872 * if (key) game.keypress = key; */ } diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp index 9bdf2dba3e..a6e5549ff4 100644 --- a/engines/agi/detection.cpp +++ b/engines/agi/detection.cpp @@ -35,11 +35,16 @@ namespace Agi { struct AGIGameDescription { Common::ADGameDescription desc; + int gameID; int gameType; uint32 features; uint16 version; }; +uint32 AgiEngine::getGameID() const { + return _gameDescription->gameID; +} + uint32 AgiEngine::getFeatures() const { return _gameDescription->features; } @@ -86,7 +91,7 @@ static const PlainGameDescriptor agiGames[] = { namespace Agi { -#define FANMADE_ILFV(id, name,md5,lang,features,ver) { \ +#define FANMADE_ILVF(id,name,md5,lang,ver,features) { \ { \ id, \ name, \ @@ -95,19 +100,22 @@ namespace Agi { Common::kPlatformPC, \ Common::ADGF_NO_FLAGS \ }, \ + GID_FANMADE, \ GType_V2, \ - features, \ + (GF_FANMADE|features), \ ver, \ } -#define FANMADE_LV(name,md5,lang,ver) FANMADE_ILFV("agi-fanmade",name,md5,lang,GF_FANMADE,ver) -#define FANMADE_LFV(name,md5,lang,ver, features) FANMADE_ILFV("agi-fanmade",name,md5,lang,(GF_FANMADE|features),ver) -#define FANMADE_V(name,md5,ver) FANMADE_LV(name,md5,Common::EN_ANY,ver) -#define FANMADE_F(name,md5,features) FANMADE_ILFV("agi-fanmade",name,md5,Common::EN_ANY,(GF_FANMADE|features),0x2917) -#define FANMADE_L(name,md5,lang) FANMADE_LV(name,md5,lang,0x2917) -#define FANMADE_LF(name,md5,lang,features) FANMADE_ILFV("agi-fanmade",name,md5,lang,(GF_FANMADE|features),0x2917) -#define FANMADE_I(id,name,md5) FANMADE_ILFV(id,name,md5,Common::EN_ANY,GF_FANMADE,0x2917) -#define FANMADE_IF(id,name,md5,features) FANMADE_ILFV(id,name,md5,Common::EN_ANY,(GF_FANMADE|features),0x2917) -#define FANMADE(name,md5) FANMADE_LV(name,md5,Common::EN_ANY,0x2917) +#define FANMADE_LVF(name,md5,lang,ver,features) FANMADE_ILVF("agi-fanmade",name,md5,lang,ver,features) + +#define FANMADE_LF(name,md5,lang,features) FANMADE_LVF(name,md5,lang,0x2917,features) +#define FANMADE_IF(id,name,md5,features) FANMADE_ILVF(id,name,md5,Common::EN_ANY,0x2917,features) + +#define FANMADE_V(name,md5,ver) FANMADE_LVF(name,md5,Common::EN_ANY,ver,0) +#define FANMADE_F(name,md5,features) FANMADE_LF(name,md5,Common::EN_ANY,features) +#define FANMADE_L(name,md5,lang) FANMADE_LF(name,md5,lang,0) +#define FANMADE_I(id,name,md5) FANMADE_IF(id,name,md5,0) + +#define FANMADE(name,md5) FANMADE_F(name,md5,0) static const AGIGameDescription gameDescriptions[] = { @@ -122,6 +130,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_AGIDEMO, GType_V2, 0, 0x2440, @@ -138,6 +147,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_AGIDEMO, GType_V2, 0, 0x2917, @@ -154,6 +164,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_AGIDEMO, GType_V2, 0, 0x2917, @@ -170,6 +181,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_AGIDEMO, GType_V2, 0, 0x2917, @@ -186,6 +198,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_AGIDEMO, GType_V2, 0, 0x2917, @@ -202,6 +215,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_AGIDEMO, GType_V3, 0, 0x3149, @@ -218,6 +232,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_BC, GType_V2, 0, 0x2440, @@ -234,6 +249,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_BC, GType_V3, 0, 0x3149, @@ -250,6 +266,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_BC, GType_V2, 0, 0x2440, @@ -266,6 +283,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_BC, GType_V3, 0, 0x3149, @@ -284,6 +302,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_DDP, GType_V2, 0, 0x2272, @@ -300,6 +319,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_DDP, GType_V2, 0, 0x2272, @@ -316,6 +336,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_DDP, GType_V2, 0, 0x2272, @@ -332,6 +353,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_GOLDRUSH, GType_V3, 0, 0x3149, @@ -348,6 +370,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_GOLDRUSH, GType_V3, 0, 0x3149, @@ -364,6 +387,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_GOLDRUSH, GType_V3, 0, 0x3149, @@ -380,6 +404,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_GOLDRUSH, GType_V3, 0, 0x3149, @@ -396,6 +421,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_GOLDRUSH, GType_V3, 0, 0x3149, @@ -416,6 +442,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_GOLDRUSH, GType_V3, GF_MACGOLDRUSH, 0x3149, @@ -432,6 +459,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_KQ1, GType_V2, 0, 0x2440, @@ -448,6 +476,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_KQ1, GType_V2, 0, 0x2272, @@ -464,6 +493,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_KQ1, GType_V2, 0, 0x2272, @@ -480,6 +510,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_KQ1, GType_V2, 0, 0x2440, @@ -496,6 +527,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ1, GType_V2, 0, 0x2917, @@ -512,6 +544,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_KQ2, GType_V2, 0, 0x2917, @@ -528,6 +561,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_KQ2, GType_V2, 0, 0x2440, @@ -544,6 +578,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_KQ2, GType_V2, 0, 0x2440, @@ -560,6 +595,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ2, GType_V2, 0, 0x2440, // XXX: any major differences from 2.411 to 2.440? @@ -576,6 +612,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ2, GType_V2, 0, 0x2917, @@ -592,6 +629,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2440, @@ -608,6 +646,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2272, @@ -624,6 +663,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2440, @@ -640,6 +680,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2917, @@ -656,6 +697,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V3, 0, 0x3086, @@ -672,6 +714,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2272, @@ -688,6 +731,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2440, @@ -704,6 +748,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2440, @@ -720,6 +765,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ3, GType_V2, 0, 0x2936, @@ -736,6 +782,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ4, GType_V3, 0, 0x3086, @@ -752,6 +799,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_KQ4, GType_V3, 0, 0x3086, @@ -768,6 +816,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ4, GType_V3, 0, 0x3086, @@ -784,6 +833,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ4, GType_V3, 0, 0x3086, @@ -800,6 +850,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_KQ4, GType_V3, 0, 0x3149, @@ -816,6 +867,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_LSL1, GType_V2, 0, 0x2440, @@ -832,6 +884,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_LSL1, GType_V2, 0, 0x2440, @@ -848,6 +901,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_LSL1, GType_V2, 0, 0x2440, @@ -864,6 +918,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_LSL1, GType_V2, 0, 0x2440, @@ -880,6 +935,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_LSL1, GType_V2, 0, 0x2440, @@ -896,6 +952,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_MH1, GType_V3, 0, 0x3149, @@ -912,6 +969,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_MH1, GType_V3, 0, 0x3149, @@ -928,6 +986,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_MH1, GType_V3, 0, 0x3149, @@ -945,6 +1004,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_MH1, GType_V3, 0, 0x3149, @@ -961,6 +1021,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_MH1, GType_V3, 0, 0x3149, @@ -977,6 +1038,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_MH1, GType_V3, 0, 0x3149, @@ -993,6 +1055,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_MH2, GType_V3, 0, 0x3086, @@ -1009,6 +1072,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_MH2, GType_V3, 0, 0x3149, @@ -1025,6 +1089,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_MH2, GType_V3, 0, 0x3149, @@ -1041,6 +1106,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_MIXEDUP, GType_V3, 0, 0x3086, @@ -1057,6 +1123,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_MIXEDUP, GType_V2, 0, 0x2917, @@ -1073,6 +1140,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_MIXEDUP, GType_V2, 0, 0x2917, @@ -1090,6 +1158,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_MIXEDUP, GType_V2, 0, 0x2917, @@ -1107,6 +1176,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2917, @@ -1123,6 +1193,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2440, @@ -1139,6 +1210,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2917, @@ -1155,6 +1227,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V3, 0, 0x3149, @@ -1171,6 +1244,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2917, @@ -1187,6 +1261,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2917, @@ -1203,6 +1278,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2440, @@ -1219,6 +1295,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_PQ1, GType_V2, 0, 0x2917, @@ -1235,6 +1312,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAtariST, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2440, @@ -1251,6 +1329,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2272, @@ -1267,6 +1346,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2440, @@ -1283,6 +1363,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2440, @@ -1299,6 +1380,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2917, @@ -1315,6 +1397,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2089, @@ -1331,6 +1414,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2272, @@ -1347,6 +1431,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ1, GType_V2, 0, 0x2440, @@ -1364,6 +1449,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2936, @@ -1380,6 +1466,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformApple2GS, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2936, @@ -1400,6 +1487,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformAmiga, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2936, @@ -1416,6 +1504,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformMacintosh, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2936, @@ -1433,6 +1522,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2917, @@ -1449,6 +1539,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2917, @@ -1465,6 +1556,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2917, @@ -1481,6 +1573,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_SQ2, GType_V2, 0, 0x2936, @@ -1497,6 +1590,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_XMASCARD, GType_V2, 0, 0x2272, @@ -1586,6 +1680,7 @@ static const AGIGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, + GID_FANMADE, GType_V2, GF_AGDS, 0x2440, @@ -1608,8 +1703,8 @@ static const AGIGameDescription gameDescriptions[] = { FANMADE("Jiggy Jiggy Uh! Uh!", "bc331588a71e7a1c8840f6cc9b9487e4"), FANMADE("Jimmy In: The Alien Attack (v0.1)", "a4e9db0564a494728de7873684a4307c"), FANMADE("Joe McMuffin In \"What's Cooking, Doc\" (v1.0)", "8a3de7e61a99cb605fa6d233dd91c8e1"), - FANMADE_LFV("Jolimie, le Village Maudit (v0.5)", "21818501636b3cb8ad5de5c1a66de5c2", Common::FR_FRA, GF_AGIMOUSE|GF_AGIPAL, 0x2936), - FANMADE_LFV("Jolimie, le Village Maudit (v1.1)", "68d7aef1161bb5972fe03efdf29ccb7f", Common::FR_FRA, GF_AGIMOUSE|GF_AGIPAL, 0x2936), + FANMADE_LVF("Jolimie, le Village Maudit (v0.5)", "21818501636b3cb8ad5de5c1a66de5c2", Common::FR_FRA, GF_AGIMOUSE|GF_AGIPAL, 0x2936), + FANMADE_LVF("Jolimie, le Village Maudit (v1.1)", "68d7aef1161bb5972fe03efdf29ccb7f", Common::FR_FRA, GF_AGIMOUSE|GF_AGIPAL, 0x2936), FANMADE("Journey Of Chef", "aa0a0b5a6364801ae65fdb96d6741df5"), FANMADE("Jukebox (v1.0)", "c4b9c5528cc67f6ba777033830de7751"), FANMADE("Justin Quest (v1.0 in development)", "103050989da7e0ffdc1c5e1793a4e1ec"), @@ -1675,7 +1770,8 @@ static const AGIGameDescription gameDescriptions[] = { FANMADE("SQ2Eye (v0.486)", "3fd86436e93456770dbdd4593eded70a"), FANMADE("Save Santa (v1.0)", "4644f6beb5802081772f14be56ae196c"), FANMADE("Save Santa (v1.3)", "f8afdb6efc5af5e7c0228b44633066af"), - FANMADE("Schiller", "ade39dea968c959cfebe1cf935d653e9"), + FANMADE("Schiller (preview 1)", "ade39dea968c959cfebe1cf935d653e9"), + FANMADE("Schiller (preview 2)", "62cd1f8fc758bf6b4aa334e553624cef"), FANMADE_IF("serguei1", "(v1.0)", "b86725f067e456e10cdbdf5f58e01dec", GF_AGIMOUSE|GF_AGIPAL), FANMADE_IF("serguei1", "v1.1 2002 Sep 5", "91975c1fb4b13b0f9a8e9ff74731030d", GF_AGIMOUSE|GF_AGIPAL), FANMADE_IF("serguei1", "v1.1 2003 Apr 10", "91975c1fb4b13b0f9a8e9ff74731030d", GF_AGIMOUSE|GF_AGIPAL), @@ -1723,9 +1819,116 @@ static const AGIGameDescription gameDescriptions[] = { FANMADE("Voodoo Girl - Queen of the Darned (v1.2 2002 Mar 29)", "11d0417b7b886f963d0b36789dac4c8f"), FANMADE("Wizaro (v0.1)", "abeec1eda6eaf8dbc52443ea97ff140c"), - { AD_TABLE_END_MARKER, 0, 0, 0 } + { AD_TABLE_END_MARKER, 0, 0, 0, 0 } +}; + +static const AGIGameDescription fallbackDescs[] = { + { + { + "agi-fanmade", + "Unknown v2 Game", + AD_ENTRY1(0, 0), + Common::UNK_LANG, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GID_FANMADE, + GType_V2, + GF_FANMADE, + 0x2917, + }, + { + { + "agi-fanmade", + "Unknown v2 AGIPAL Game", + AD_ENTRY1(0, 0), + Common::UNK_LANG, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GID_FANMADE, + GType_V2, + GF_FANMADE | GF_AGIPAL, + 0x2917, + }, + { + { + "agi-fanmade", + "Unknown v3 Game", + AD_ENTRY1(0, 0), + Common::UNK_LANG, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GID_FANMADE, + GType_V3, + GF_FANMADE, + 0x3149, + }, }; +Common::ADGameDescList fallbackDetector(const FSList *fslist) { + Common::String tstr; + typedef Common::HashMap<Common::String, int32, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> IntMap; + IntMap allFiles; + Common::ADGameDescList matched; + int matchedNum = -1; + + // TODO: + // WinAGI produces *.wag file with interpreter version, game name + // and other parameters. Add support for this once specs are known + + + // First grab all filenames + for (FSList::const_iterator file = fslist->begin(); file != fslist->end(); ++file) { + if (file->isDirectory()) continue; + tstr = file->name(); + tstr.toLowercase(); + + allFiles[tstr] = true; + } + + // Now check for v2 + if (allFiles.contains("logdir") && allFiles.contains("object") && + allFiles.contains("picdir") && allFiles.contains("snddir") && + allFiles.contains("viewdir") && allFiles.contains("vol.0") && + allFiles.contains("words.tok")) { + matchedNum = 0; + + // Check if it is AGIPAL + if (allFiles.contains("pal.101")) + matchedNum = 1; + } else { // Try v3 + char name[8]; + + for (IntMap::const_iterator f = allFiles.begin(); f != allFiles.end(); ++f) { + debug(" --> %s", f->_key.c_str()); + if (f->_key.hasSuffix("vol.0")) { + memset(name, 0, 8); + strncpy(name, f->_key.c_str(), f->_key.size() > 5 ? f->_key.size() - 5 : f->_key.size()); + debug("YEAH! (%s)", name); + + if (allFiles.contains("object") && allFiles.contains("words.tok") && + allFiles.contains(Common::String(name) + "dir")) { + matchedNum = 2; + break; + } + } + } + } + + if (matchedNum != -1) { + matched.push_back(&fallbackDescs[matchedNum].desc); + + printf("Your game version has been detected using fallback matching as a\n"); + printf("variant of %s (%s).\n", fallbackDescs[matchedNum].desc.gameid, fallbackDescs[matchedNum].desc.extra); + printf("If this is an original and unmodified version or new made Fanmade game,\n"); + printf("please report any, information previously printed by ScummVM to the team.\n"); + } + + return matched; +} + } static const Common::ADParams detectionParams = { @@ -1744,7 +1947,7 @@ static const Common::ADParams detectionParams = { // List of files for file-based fallback detection (optional) 0, // Fallback callback - 0, + Agi::fallbackDetector, // Flags Common::kADFlagAugmentPreferredTarget }; diff --git a/engines/agi/inv.cpp b/engines/agi/inv.cpp index d5e3f5beb9..f8014a2bc9 100644 --- a/engines/agi/inv.cpp +++ b/engines/agi/inv.cpp @@ -91,18 +91,21 @@ int AgiEngine::showItems() { void AgiEngine::selectItems(int n) { int fsel = 0; + bool exit_select = false; - for (;;) { + while (!exit_select) { if (n > 0) printItem(fsel, STATUS_BG, STATUS_FG); switch (waitAnyKey()) { case KEY_ENTER: setvar(vSelItem, _intobj[fsel]); - goto exit_select; + exit_select = true; + break; case KEY_ESCAPE: setvar(vSelItem, 0xff); - goto exit_select; + exit_select = true; + break; case KEY_UP: if (fsel >= 2) fsel -= 2; @@ -127,19 +130,20 @@ void AgiEngine::selectItems(int n) { showItems(); printItem(fsel, STATUS_BG, STATUS_FG); _gfx->doUpdate(); - goto exit_select; + exit_select = true; } break; } default: break; } - - showItems(); - _gfx->doUpdate(); + + if (!exit_select) { + showItems(); + _gfx->doUpdate(); + } } -exit_select: debugC(6, kDebugLevelInventory, "selected: %d", fsel); } diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp index e4a025f2b9..5cfcf1dba5 100644 --- a/engines/agi/keyboard.cpp +++ b/engines/agi/keyboard.cpp @@ -92,6 +92,7 @@ int AgiEngine::doPollKeyboard() { /* If a key is ready, rip it */ if (_gfx->keypress()) { key = _gfx->getKey(); + debugC(3, kDebugLevelInput, "key %02x pressed", key); } @@ -102,10 +103,14 @@ int AgiEngine::handleController(int key) { VtEntry *v = &_game.viewTable[0]; int i; - /* The Black Cauldron needs KEY_ESCAPE to use menus */ - if (key == 0 /*|| key == KEY_ESCAPE */ ) + /* AGI 3.149 games and The Black Cauldron need KEY_ESCAPE to use menus */ + if (key == 0 || (key == KEY_ESCAPE && agiGetRelease() != 0x3149 && getGameID() != GID_BC) ) return false; + if ((getGameID() == GID_MH1 || getGameID() == GID_MH2) && (key == KEY_ENTER) && + (_game.inputMode == INPUT_NONE)) + key = 0x20; // Set Enter key to Space in Manhunter when there's no text input + debugC(3, kDebugLevelInput, "key = %04x", key); for (i = 0; i < MAX_DIRS; i++) { diff --git a/engines/agi/logic.cpp b/engines/agi/logic.cpp index 21a560427e..04052df682 100644 --- a/engines/agi/logic.cpp +++ b/engines/agi/logic.cpp @@ -83,8 +83,7 @@ int AgiEngine::decodeLogic(int n) { _game.dirLogic[n].flags |= RES_LOADED; } else { /* unload data - * blah DF YA WANKER!!@!@# frag. i'm so dumb. not every logic - * has text + * Note that not every logic has text */ free(_game.logics[n].data); ec = errNotEnoughMemory; diff --git a/engines/agi/motion.cpp b/engines/agi/motion.cpp index 864953a81f..3c88c01054 100644 --- a/engines/agi/motion.cpp +++ b/engines/agi/motion.cpp @@ -110,7 +110,7 @@ void AgiEngine::motionFollowEgo(VtEntry *v) { while ((v->direction = _rnd->getRandomNumber(8)) == 0) { } - d = (abs(egoY - objY) + abs(egoX - objX)) / 2; + d = (ABS(egoY - objY) + ABS(egoX - objX)) / 2; if (d < v->stepSize) { v->parm3 = v->stepSize; diff --git a/engines/agi/op_cmd.cpp b/engines/agi/op_cmd.cpp index f9017da320..ef09b319fa 100644 --- a/engines/agi/op_cmd.cpp +++ b/engines/agi/op_cmd.cpp @@ -238,6 +238,24 @@ cmd(get_priority) { cmd(set_priority) { vt.flags |= FIXED_PRIORITY; vt.priority = p1; + + // WORKAROUND: this fixes bug #1712585 in KQ4 (dwarf sprite priority) + // For this scene, ego (Rosella) hasn't got a fixed priority till script 54 + // explicitly sets priority 8 for her, so that she can walk back to the table + // without being drawn over the other dwarfs + // It seems that in this scene, ego's priority is set to 8, but the priority of + // the last dwarf with the soup bowls (view 152) is also set to 8, which causes + // the dwarf to be drawn behind ego + // With this workaround, when the game scripts set the priority of view 152 + // (seventh dwarf with soup bowls), ego's priority is set to 7 + // The game script itself sets priotity 8 for ego before she starts walking, + // and then releases the fixed priority set on ego after ego is seated + // Therefore, this workaround only affects that specific part of this scene + // Ego is set to object 19 by script 54 + if (g_agi->getGameID() == GID_KQ4 && vt.currentView == 152) { + game.viewTable[19].flags |= FIXED_PRIORITY; + game.viewTable[19].priority = 7; + } } cmd(set_priority_f) { @@ -571,6 +589,21 @@ cmd(draw_pic) { g_sprites->blitBoth(); game.pictureShown = 0; debugC(6, kDebugLevelScripts, "--- end of draw pic %d ---", _v[p0]); + + // WORKAROUND for a script bug which exists in SQ1, logic scripts + // 20 and 110. Flag 103 is not reset correctly, which leads to erroneous + // behavior from view 46 (the spider droid). View 46 is supposed to + // follow ego and explode when it comes in contact with him. However, as + // flag 103 is not reset correctly, when the player goes down the path + // and back up, the spider is always at the base of the path (since it + // can't go up) and kills the player when he goes down at ground level + // (although the spider droid sprite itself seems to be correctly positioned). + // With this workaround, when the player goes back to picture 20 (1 screen + // above the ground), flag 103 is reset, thereby fixing this issue. Note + // that this is a script bug and occurs in the original interpreter as well. + // Fixes bug #1658514: AGI: SQ1 (2.2 DOS ENG) bizzare exploding roger + if (g_agi->getGameID() == GID_SQ1 && _v[p0] == 20) + g_agi->setflag(103, false); } cmd(show_pic) { @@ -652,7 +685,18 @@ cmd(draw) { g_sprites->eraseUpdSprites(); vt.flags |= DRAWN; - if (g_agi->agiGetRelease() <= 0x2440) /* See bug #546562 */ + // WORKAROUND: This fixes a bug with AGI Fanmade game Space Trek. + // The original workaround checked if AGI version was <= 2.440, which could + // cause regressions with some AGI games. The original workaround no longer + // works for Space Trek in ScummVM, as all fanmade games are set to use + // AGI version 2.917, but it applies to all other games where AGI version is + // <= 2.440, which was not the original purpose of this workaround. It is + // assumed that this bug is caused by AGI Studio, so this applies to all + // fanmade games only. + // TODO: Investigate this further and check if any other fanmade AGI + // games are affected. If yes, then it'd be best to set this for Space + // Trek only + if (g_agi->getFeatures() & GF_FANMADE) /* See Sarien bug #546562 */ vt.flags |= ANIMATED; g_sprites->blitUpdSprites(); @@ -1014,7 +1058,7 @@ cmd(distance) { y1 = v0->yPos; x2 = v1->xPos + v1->xSize / 2; y2 = v1->yPos; - d = abs(x1 - x2) + abs(y1 - y2); + d = ABS(x1 - x2) + ABS(y1 - y2); if (d > 0xfe) d = 0xfe; } else { @@ -1045,7 +1089,7 @@ cmd(get_string) { col = p3; /* Workaround for SQLC bug. - * See bug #792125 for details + * See Sarien bug #792125 for details */ if (row > 24) row = 24; @@ -1166,7 +1210,7 @@ cmd(echo_line) { cmd(clear_lines) { uint8 l; - /* Residence 44 calls clear.lines(24,0,0), see bug #558423 */ + /* Residence 44 calls clear.lines(24,0,0), see Sarien bug #558423 */ l = p1 ? p1 : p0; g_agi->clearLines(p0, l, p2); @@ -1227,14 +1271,23 @@ cmd(mouse_posn) { cmd(shake_screen) { int i; - /* AGIPAL uses shake.screen values between 101 and 109 to - * set the palette. - */ - if ((g_agi->getFeatures() & GF_AGIPAL) && p0 >= 101 && p0 < 110) { - g_gfx->setAGIPal(p0); - return; - } else - g_gfx->shakeStart(); + // AGIPAL uses shake.screen values between 101 and 109 to + // set the palette. + if (p0 >= 101 && p0 < 110) { + if (g_agi->getFeatures() & GF_AGIPAL) { + g_gfx->setAGIPal(p0); + return; + } else { + warning("It looks like GF_AGIPAL flag is missing"); + } + } + + // Disables input while shaking to prevent bug + // #1678230: AGI: Entering text while screen is shaking + int originalValue = game.inputEnabled; + game.inputEnabled = 0; + + g_gfx->shakeStart(); g_sprites->commitBoth(); /* Fixes SQ1 demo */ for (i = 4 * p0; i; i--) { @@ -1243,6 +1296,9 @@ cmd(shake_screen) { g_agi->mainCycle(); } g_gfx->shakeEnd(); + + //Sets input back to what it was + game.inputEnabled = originalValue; } static void (*agiCommand[183])(uint8 *) = { diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp index 43624a1801..3ee56e5786 100644 --- a/engines/agi/op_test.cpp +++ b/engines/agi/op_test.cpp @@ -229,8 +229,9 @@ int AgiEngine::testIfCode(int lognum) { uint8 orTest = false; uint16 lastIp = ip; uint8 p[16] = { 0 }; + bool end_test = false; - while (retval && !game.quitProgNow) { + while (retval && !game.quitProgNow && !end_test) { if (_debug.enabled && (_debug.logic0 || lognum)) debugConsole(lognum, lTEST_MODE, NULL); @@ -240,7 +241,8 @@ int AgiEngine::testIfCode(int lognum) { switch (op) { case 0xFF: /* END IF, TEST true */ - goto end_test; + end_test = true; + break; case 0xFD: notTest = !notTest; continue; @@ -251,7 +253,7 @@ int AgiEngine::testIfCode(int lognum) { if (orTest) { ec = false; retval = false; - goto end_test; + end_test = true; } orTest = true; @@ -259,7 +261,8 @@ int AgiEngine::testIfCode(int lognum) { case 0x00: /* return true? */ - goto end_test; + end_test = true; + break; case 0x01: ec = testEqual(p[0], p[1]); if (p[0] == 11) @@ -333,62 +336,63 @@ int AgiEngine::testIfCode(int lognum) { break; default: ec = false; - goto end_test; + end_test = true; } - if (op <= 0x12) - ip += logicNamesTest[op].numArgs; - - /* exchange ec value */ - if (notTest) - ec = !ec; - - /* not is only enabled for 1 test command */ - notTest = false; - - if (orTest && ec) { - /* a true inside an OR statement passes - * ENTIRE statement scan for end of OR - */ - - /* CM: test for opcode < 0xfc changed from 'op' to - * '*(code+ip)', to avoid problem with the 0xfd (NOT) - * opcode byte. Changed a bad ip += ... ip++ construct. - * This should fix the crash with Larry's logic.0 code: - * - * if ((isset(4) || - * !isset(2) || - * v30 == 2 || - * v30 == 1)) { - * goto Label1; - * } - * - * The bytecode is: - * ff fc 07 04 fd 07 02 01 1e 02 01 1e 01 fc ff - */ - - /* find end of OR */ - while (*(code + ip) != 0xFC) { - if (*(code + ip) == 0x0E) { /* said */ + if (!end_test) { + if (op <= 0x12) + ip += logicNamesTest[op].numArgs; + + /* exchange ec value */ + if (notTest) + ec = !ec; + + /* not is only enabled for 1 test command */ + notTest = false; + + if (orTest && ec) { + /* a true inside an OR statement passes + * ENTIRE statement scan for end of OR + */ + + /* CM: test for opcode < 0xfc changed from 'op' to + * '*(code+ip)', to avoid problem with the 0xfd (NOT) + * opcode byte. Changed a bad ip += ... ip++ construct. + * This should fix the crash with Larry's logic.0 code: + * + * if ((isset(4) || + * !isset(2) || + * v30 == 2 || + * v30 == 1)) { + * goto Label1; + * } + * + * The bytecode is: + * ff fc 07 04 fd 07 02 01 1e 02 01 1e 01 fc ff + */ + + /* find end of OR */ + while (*(code + ip) != 0xFC) { + if (*(code + ip) == 0x0E) { /* said */ + ip++; + /* cover count + ^words */ + ip += 1 + ((*(code + ip)) * 2); + continue; + } + + if (*(code + ip) < 0xFC) + ip += logicNamesTest[*(code + ip)].numArgs; ip++; - /* cover count + ^words */ - ip += 1 + ((*(code + ip)) * 2); - continue; } - - if (*(code + ip) < 0xFC) - ip += logicNamesTest[*(code + ip)].numArgs; ip++; - } - ip++; - orTest = false; - retval = true; - } else { - retval = orTest ? retval || ec : retval && ec; + orTest = false; + retval = true; + } else { + retval = orTest ? retval || ec : retval && ec; + } } } - end_test: /* if false, scan for end of IP? */ if (retval) diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp index 4f25b58cc5..94701baa32 100644 --- a/engines/agi/saveload.cpp +++ b/engines/agi/saveload.cpp @@ -215,7 +215,7 @@ int AgiEngine::saveGame(const char *fileName, const char *description) { return errOK; } -int AgiEngine::loadGame(const char *fileName) { +int AgiEngine::loadGame(const char *fileName, bool checkId) { char description[31], saveVersion, loadId[8]; int i, vtEntries = MAX_VIEWTABLE; uint8 t; @@ -251,7 +251,7 @@ int AgiEngine::loadGame(const char *fileName) { _game.state = in->readByte(); in->read(loadId, 8); - if (strcmp(loadId, _game.id)) { + if (strcmp(loadId, _game.id) && checkId) { delete in; warning("This save seems to be from a different AGI game (save from %s, running %s), not loaded", loadId, _game.id); return errBadFileOpen; diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp index 8a67f2e60e..f2b4b24148 100644 --- a/engines/agi/sprite.cpp +++ b/engines/agi/sprite.cpp @@ -90,7 +90,7 @@ void SpritesMgr::blitPixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, /* CM: priority 15 overrides control lines and is ignored when * tracking effective priority. This tweak is needed to fix - * bug #451768, and should not affect Sierra games because + * Sarien bug #451768, and should not affect Sierra games because * sprites shouldn't have priority 15 (like the AGI Mouse * demo "mouse pointer") * @@ -120,7 +120,7 @@ void SpritesMgr::blitPixel(uint8 *p, uint8 *end, uint8 col, int spr, int width, *hidden = false; /* Except if our priority is 15, which should never happen - * (fixes bug #451768) + * (fixes Sarien bug #451768) * * Update: breaks other games, can't be used * @@ -136,7 +136,7 @@ int SpritesMgr::blitCel(int x, int y, int spr, ViewCel *c) { int i, j, t, m, col; int hidden = true; - /* Fixes bug #477841 (crash in PQ1 map C4 when y == -2) */ + /* Fixes Sarien bug #477841 (crash in PQ1 map C4 when y == -2) */ if (y < 0) y = 0; if (x < 0) @@ -247,7 +247,7 @@ void SpritesMgr::objsRestoreArea(Sprite *s) { * Condition to determine whether a sprite will be in the 'updating' list. */ bool SpritesMgr::testUpdating(VtEntry *v, AgiEngine *agi) { - /* Sanity check (see bug #779302) */ + /* Sanity check (see Sarien bug #779302) */ if (~agi->_game.dirView[v->currentView].flags & RES_LOADED) return false; @@ -258,7 +258,7 @@ bool SpritesMgr::testUpdating(VtEntry *v, AgiEngine *agi) { * Condition to determine whether a sprite will be in the 'non-updating' list. */ bool SpritesMgr::testNotUpdating(VtEntry *v, AgiEngine *vm) { - /* Sanity check (see bug #779302) */ + /* Sanity check (see Sarien bug #779302) */ if (~vm->_game.dirView[v->currentView].flags & RES_LOADED) return false; @@ -580,7 +580,7 @@ void SpritesMgr::addToPic(int view, int loop, int cel, int x, int y, int pri, in /* * Was hardcoded to 8, changed to pri_table[y] to fix Gold - * Rush (see bug #587558) + * Rush (see Sarien bug #587558) */ if (pri == 0) pri = _vm->_game.priTable[y]; @@ -618,10 +618,12 @@ void SpritesMgr::addToPic(int view, int loop, int cel, int x, int y, int pri, in /* add rectangle around object, don't clobber control * info in priority data. The box extends to the end of * its priority band! - * - * SQ1 needs +1 (see bug #810331) */ - y3 = (y2 / 12) * 12 + 1; + y3 = (y2 / 12) * 12; + + // SQ1 needs +1 (see Sarien bug #810331) + if (_vm->getGameID() == GID_SQ1) + y3++; // don't let box extend below y. if (y3 > y2) y3 = y2; diff --git a/engines/agi/view.cpp b/engines/agi/view.cpp index ea3f2be9bd..808f227f6e 100644 --- a/engines/agi/view.cpp +++ b/engines/agi/view.cpp @@ -41,8 +41,16 @@ void AgiEngine::lSetCel(VtEntry *v, int n) { if (currentVl->numCels == 0) return; - if (!(v->flags & UPDATE) - && (agiGetRelease() >= 0x3000)) + // WORKAROUND: This is a very nasty hack to fix a bug in the KQ4 introduction + // In its original form, it caused a lot of regressions, including KQ4 bugs and crashes + // Refer to Sarien bug #588899 for the original issue + // Modifying this workaround to only work for a specific view in the KQ4 intro fixes several + // ScummVM bugs. Refer to bugs #1660486, #1660169, #1660192, #1660162 and #1660354 + // FIXME: Remove this workaround and investigate the reason for the erroneous actor behavior + // in the KQ4 introduction + // It seems there's either a bug with KQ4's logic script 120 (the intro script) + // or flag 64 is not set correctly, which causes the erroneous behavior from the actors + if (getGameID() == GID_KQ4 && !(v->flags & UPDATE) && (v->currentView == 172)) return; currentVc = ¤tVl->cel[n]; @@ -68,9 +76,6 @@ void AgiEngine::lSetLoop(VtEntry *v, int n) { if (v->currentCel >= v->numCels) v->currentCel = 0; - if (!(v->flags & UPDATE) && (agiGetRelease() >= 0x3000)) - return; - v->loopData = &_game.views[v->currentView].loop[n]; } @@ -211,7 +216,7 @@ void AgiEngine::unloadView(int n) { if (~_game.dirView[n].flags & RES_LOADED) return; - /* Rebuild sprite list, see bug #779302 */ + /* Rebuild sprite list, see Sarien bug #779302 */ _sprites->eraseBoth(); _sprites->blitBoth(); _sprites->commitBoth(); @@ -270,6 +275,33 @@ void AgiEngine::setLoop(VtEntry *v, int n) { * @param n number of AGI view resource */ void AgiEngine::setView(VtEntry *v, int n) { + + uint16 viewFlags = 0; + + // When setting a view to the view table, if there's already another view set in that + // view table entry and it's still drawn, erase the existing view before setting the new one + // Fixes bug #1658643: AGI: SQ1 (2.2 DOS ENG) Graphic error, ego leaves behind copy + // Update: Apparently, this makes ego dissapear at times, e.g. when textboxes are shown + // Therefore, it's limited to view 118 in SQ1 (Roger climbing the ladder) + // Fixes bug #1715284: Roger sometimes disappears + if (v->viewData != NULL) { + if (v->currentView == 118 && v->flags & DRAWN && getGameID() == GID_SQ1) { + viewFlags = v->flags; // Store the flags for the view + _sprites->eraseUpdSprites(); + if (v->flags & UPDATE) { + v->flags &= ~DRAWN; + } else { + _sprites->eraseNonupdSprites(); + v->flags &= ~DRAWN; + _sprites->blitNonupdSprites(); + } + _sprites->blitUpdSprites(); + + _sprites->commitBlock(v->xPos, v->yPos - v->ySize + 1, v->xPos + v->xSize - 1, v->yPos); + v->flags = viewFlags; // Restore the view's flags + } + } + v->viewData = &_game.views[n]; v->currentView = n; v->numLoops = v->viewData->numLoops; diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp index 90e7e8aa78..b50242d32c 100644 --- a/engines/agos/agos.cpp +++ b/engines/agos/agos.cpp @@ -25,7 +25,7 @@ #include "common/config-manager.h" #include "common/file.h" -#include "common/fs.h" +//#include "common/fs.h" #include "common/system.h" #include "agos/debugger.h" @@ -72,6 +72,35 @@ static const GameSpecificSettings puzzlepack_settings = { }; #endif + +AGOSEngine_PuzzlePack::AGOSEngine_PuzzlePack(OSystem *system) + : AGOSEngine_Feeble(system) { +} + +AGOSEngine_Feeble::AGOSEngine_Feeble(OSystem *system) + : AGOSEngine_Simon2(system) { +} + +AGOSEngine_Simon2::AGOSEngine_Simon2(OSystem *system) + : AGOSEngine_Simon1(system) { +} + +AGOSEngine_Simon1::AGOSEngine_Simon1(OSystem *system) + : AGOSEngine_Waxworks(system) { +} + +AGOSEngine_Waxworks::AGOSEngine_Waxworks(OSystem *system) + : AGOSEngine_Elvira2(system) { +} + +AGOSEngine_Elvira2::AGOSEngine_Elvira2(OSystem *system) + : AGOSEngine_Elvira1(system) { +} + +AGOSEngine_Elvira1::AGOSEngine_Elvira1(OSystem *system) + : AGOSEngine(system) { +} + AGOSEngine::AGOSEngine(OSystem *syst) : Engine(syst) { _vcPtr = 0; @@ -83,6 +112,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _keyPressed = 0; _gameFile = 0; + _opcode = 0; _itemMemSize = 0; _tableMemSize = 0; @@ -162,6 +192,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _beardLoaded = 0; _litBoxFlag = 0; _mortalFlag = 0; + _displayScreen = false; _updateScreen = false; _syncFlag2 = 0; _inCallBack = 0; @@ -169,13 +200,14 @@ AGOSEngine::AGOSEngine(OSystem *syst) _copyPartialMode = 0; _fastMode = 0; _useBackGround = 0; + + _backFlag = 0; _debugMode = 0; _startMainScript = false; _continousMainScript = false; _startVgaScript = false; _continousVgaScript = false; - _drawImagesDebug = false; _dumpImages = false; _copyProtection = false; @@ -261,6 +293,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _leftButtonDown = 0; _rightButtonDown = 0; + _clickOnly = 0; _noRightClick = false; _leftButton = 0; @@ -282,8 +315,6 @@ AGOSEngine::AGOSEngine(OSystem *syst) _fastFadeCount = 0; _fastFadeInFlag = 0; _fastFadeOutFlag = 0; - _unkPalFlag = 0; - _usePaletteDelay = 0; _exitCutscene = 0; _paletteFlag = 0; _bottomPalette = 0; @@ -296,6 +327,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _showPreposition = 0; _showMessageFlag = 0; + _copyScnFlag = 0; _vgaSpriteChanged = 0; _block = 0; @@ -315,7 +347,15 @@ AGOSEngine::AGOSEngine(OSystem *syst) _timer5 = 0; _timer4 = 0; - _frameRate = 0; + _iconToggleCount = 0; + _voiceCount = 0; + + _lastTickCount = 0; + _thisTickCount = 0; + _startSecondCount = 0; + _tSecondCount = 0; + + _frameCount = 0; _zoneNumber = 0; @@ -341,6 +381,11 @@ AGOSEngine::AGOSEngine(OSystem *syst) _nextVgaTimerToProcess = 0; + _opcode177Var1 = 1; + _opcode177Var2 = 0; + _opcode178Var1 = 1; + _opcode178Var2 = 0; + _classLine = 0; _classMask = 0; _classMode1 = 0; @@ -356,6 +401,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _boxLineCount = 0; _boxCR = 0; memset(_boxBuffer, 0, sizeof(_boxBuffer)); + _boxBufferPtr = _boxBuffer; _linePtrs[0] = 0; _linePtrs[1] = 0; @@ -428,6 +474,7 @@ AGOSEngine::AGOSEngine(OSystem *syst) _saveLoadSlot = 0; memset(_saveLoadName, 0, sizeof(_saveLoadName)); + _saveGameNameLen = 0; _saveLoadRowCurPos = 0; _numSaveGameRows = 0; _saveDialogFlag = false; @@ -446,6 +493,17 @@ AGOSEngine::AGOSEngine(OSystem *syst) _backBuf = 0; _scaleBuf = 0; + _window3Flag = 0; + _window4Flag = 0; + _window6Flag = 0; + _window4BackScn = 0; + _window6BackScn = 0; + + _moveXMin = 0; + _moveYMin = 0; + _moveXMax = 0; + _moveYMax = 0; + _vc10BasePtrOld = 0; memcpy (_hebrewCharWidths, "\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32); @@ -531,9 +589,22 @@ int AGOSEngine::init() { // allocate buffers _backGroundBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); _frontBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); - _backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); - if (getGameType() == GType_FF || getGameType() == GType_PP) + + if (getGameType() == GType_FF || getGameType() == GType_PP) { + _backBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); _scaleBuf = (byte *)calloc(_screenWidth * _screenHeight, 1); + } + + if (getGameType() == GType_SIMON2) { + _window4BackScn = (byte *)calloc(_screenWidth * _screenHeight, 1); + } else if (getGameType() == GType_SIMON1) { + _window4BackScn = (byte *)calloc(_screenWidth * 134, 1); + } else if (getGameType() == GType_WW || getGameType() == GType_ELVIRA2) { + _window4BackScn = (byte *)calloc(224 * 127, 1); + } else if (getGameType() == GType_ELVIRA1) { + _window4BackScn = (byte *)calloc(224 * 127, 1); + _window6BackScn = (byte *)calloc(48 * 80, 1); + } setupGame(); @@ -605,135 +676,161 @@ static const uint16 initialVideoWindows_Common[20] = { 3, 3, 14, 127, }; -void AGOSEngine::setupGame() { - if (getGameType() == GType_PP) { - gss = PTR(puzzlepack_settings); - _numVideoOpcodes = 85; +void AGOSEngine_PuzzlePack::setupGame() { + gss = PTR(puzzlepack_settings); + _numVideoOpcodes = 85; #ifndef PALMOS_68K - _vgaMemSize = 7500000; + _vgaMemSize = 7500000; #else - _vgaMemSize = gVars->memory[kMemSimon2Games]; + _vgaMemSize = gVars->memory[kMemSimon2Games]; #endif - _itemMemSize = 20000; - _tableMemSize = 200000; - _frameRate = 1; - _vgaBaseDelay = 5; - _numBitArray1 = 128; - _numItemStore = 10; - _numTextBoxes = 40; - _numVars = 2048; - } else if (getGameType() == GType_FF) { - gss = PTR(feeblefiles_settings); - _numVideoOpcodes = 85; + _itemMemSize = 20000; + _tableMemSize = 200000; + _frameCount = 1; + _vgaBaseDelay = 5; + _numBitArray1 = 128; + _numItemStore = 10; + _numTextBoxes = 40; + _numVars = 2048; + + AGOSEngine::setupGame(); +} + +void AGOSEngine_Feeble::setupGame() { + gss = PTR(feeblefiles_settings); + _numVideoOpcodes = 85; #ifndef PALMOS_68K - _vgaMemSize = 7500000; + _vgaMemSize = 7500000; #else - _vgaMemSize = gVars->memory[kMemSimon2Games]; + _vgaMemSize = gVars->memory[kMemSimon2Games]; #endif - _itemMemSize = 20000; - _tableMemSize = 200000; - _frameRate = 1; - _vgaBaseDelay = 5; - _numBitArray1 = 16; - _numBitArray2 = 16; - _numBitArray3 = 16; - _numItemStore = 10; - _numTextBoxes = 40; - _numVars = 255; - } else if (getGameType() == GType_SIMON2) { - gss = PTR(simon2_settings); - _tableIndexBase = 1580 / 4; - _textIndexBase = 1500 / 4; - _numVideoOpcodes = 75; + _itemMemSize = 20000; + _tableMemSize = 200000; + _frameCount = 1; + _vgaBaseDelay = 5; + _numBitArray1 = 16; + _numBitArray2 = 16; + _numBitArray3 = 16; + _numItemStore = 10; + _numTextBoxes = 40; + _numVars = 255; + + AGOSEngine::setupGame(); +} + +void AGOSEngine_Simon2::setupGame() { + gss = PTR(simon2_settings); + _tableIndexBase = 1580 / 4; + _textIndexBase = 1500 / 4; + _numVideoOpcodes = 75; #ifndef PALMOS_68K - _vgaMemSize = 2000000; + _vgaMemSize = 2000000; #else - _vgaMemSize = gVars->memory[kMemSimon2Games]; + _vgaMemSize = gVars->memory[kMemSimon2Games]; #endif - _itemMemSize = 20000; - _tableMemSize = 100000; - // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2 - if ((getGameType() == GType_SIMON2) && _native_mt32) - _musicIndexBase = (1128 + 612) / 4; - else - _musicIndexBase = 1128 / 4; - _soundIndexBase = 1660 / 4; - _frameRate = 1; - _vgaBaseDelay = 1; - _numBitArray1 = 16; - _numBitArray2 = 16; - _numItemStore = 10; - _numTextBoxes = 20; - _numVars = 255; - } else if (getGameType() == GType_SIMON1) { - gss = PTR(simon1_settings); - _tableIndexBase = 1576 / 4; - _textIndexBase = 1460 / 4; - _numVideoOpcodes = 64; + _itemMemSize = 20000; + _tableMemSize = 100000; + // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2 + if ((getGameType() == GType_SIMON2) && _native_mt32) + _musicIndexBase = (1128 + 612) / 4; + else + _musicIndexBase = 1128 / 4; + _soundIndexBase = 1660 / 4; + _frameCount = 1; + _vgaBaseDelay = 1; + _numBitArray1 = 16; + _numBitArray2 = 16; + _numItemStore = 10; + _numTextBoxes = 20; + _numVars = 255; + + AGOSEngine::setupGame(); +} + +void AGOSEngine_Simon1::setupGame() { + gss = PTR(simon1_settings); + _tableIndexBase = 1576 / 4; + _textIndexBase = 1460 / 4; + _numVideoOpcodes = 64; #ifndef PALMOS_68K - _vgaMemSize = 1000000; + _vgaMemSize = 1000000; #else - _vgaMemSize = gVars->memory[kMemSimon1Games]; + _vgaMemSize = gVars->memory[kMemSimon1Games]; #endif - _itemMemSize = 20000; - _tableMemSize = 50000; - _musicIndexBase = 1316 / 4; - _soundIndexBase = 0; - _frameRate = 1; - _vgaBaseDelay = 1; - _numBitArray1 = 16; - _numBitArray2 = 16; - _numItemStore = 10; - _numTextBoxes = 20; - _numVars = 255; - } else if (getGameType() == GType_WW) { - gss = PTR(simon1_settings); - _numVideoOpcodes = 64; + _itemMemSize = 20000; + _tableMemSize = 50000; + _musicIndexBase = 1316 / 4; + _soundIndexBase = 0; + _frameCount = 1; + _vgaBaseDelay = 1; + _numBitArray1 = 16; + _numBitArray2 = 16; + _numItemStore = 10; + _numTextBoxes = 20; + _numVars = 255; + + AGOSEngine::setupGame(); +} + +void AGOSEngine_Waxworks::setupGame() { + gss = PTR(simon1_settings); + _numVideoOpcodes = 64; #ifndef PALMOS_68K - _vgaMemSize = 1000000; + _vgaMemSize = 1000000; #else - _vgaMemSize = gVars->memory[kMemSimon1Games]; + _vgaMemSize = gVars->memory[kMemSimon1Games]; #endif - _itemMemSize = 80000; - _tableMemSize = 50000; - _frameRate = 4; - _vgaBaseDelay = 1; - _numBitArray1 = 16; - _numBitArray2 = 15; - _numItemStore = 50; - _numTextBoxes = 10; - _numVars = 255; - } else if (getGameType() == GType_ELVIRA2) { - gss = PTR(simon1_settings); - _numVideoOpcodes = 60; + _itemMemSize = 80000; + _tableMemSize = 50000; + _frameCount = 4; + _vgaBaseDelay = 1; + _numBitArray1 = 16; + _numBitArray2 = 15; + _numItemStore = 50; + _numTextBoxes = 10; + _numVars = 255; + + AGOSEngine::setupGame(); +} + +void AGOSEngine_Elvira2::setupGame() { + gss = PTR(simon1_settings); + _numVideoOpcodes = 60; #ifndef PALMOS_68K - _vgaMemSize = 1000000; + _vgaMemSize = 1000000; #else - _vgaMemSize = gVars->memory[kMemSimon1Games]; + _vgaMemSize = gVars->memory[kMemSimon1Games]; #endif - _itemMemSize = 64000; - _tableMemSize = 100000; - _frameRate = 4; - _vgaBaseDelay = 1; - _numBitArray1 = 16; - _numBitArray2 = 15; - _numItemStore = 50; - _numVars = 255; - } else if (getGameType() == GType_ELVIRA1) { - gss = PTR(simon1_settings); - _numVideoOpcodes = 57; + _itemMemSize = 64000; + _tableMemSize = 100000; + _frameCount = 4; + _vgaBaseDelay = 1; + _numBitArray1 = 16; + _numBitArray2 = 15; + _numItemStore = 50; + _numVars = 255; + + AGOSEngine::setupGame(); +} + +void AGOSEngine_Elvira1::setupGame() { + gss = PTR(simon1_settings); + _numVideoOpcodes = 57; #ifndef PALMOS_68K - _vgaMemSize = 1000000; + _vgaMemSize = 1000000; #else - _vgaMemSize = gVars->memory[kMemSimon1Games]; + _vgaMemSize = gVars->memory[kMemSimon1Games]; #endif - _itemMemSize = 64000; - _tableMemSize = 256000; - _frameRate = 4; - _vgaBaseDelay = 1; - _numVars = 512; - } + _itemMemSize = 64000; + _tableMemSize = 256000; + _frameCount = 4; + _vgaBaseDelay = 1; + _numVars = 512; + AGOSEngine::setupGame(); +} + +void AGOSEngine::setupGame() { allocItemHeap(); allocTablesHeap(); @@ -794,6 +891,9 @@ AGOSEngine::~AGOSEngine() { free(_backBuf); free(_scaleBuf); + free(_window4BackScn); + free(_window6BackScn); + free(_variableArray); free(_variableArray2); @@ -851,6 +951,11 @@ int AGOSEngine::go() { vc34_setMouseOff(); + if (getGameType() != GType_PP && getGameType() != GType_FF) { + uint16 count = (getGameType() == GType_SIMON2) ? 5 : _frameCount; + addVgaEvent(count, ANIMATE_INT, NULL, 0, 0); + } + if (getGameType() == GType_ELVIRA1 && getPlatform() == Common::kPlatformAtariST && (getFeatures() & GF_DEMO)) { int i; diff --git a/engines/agos/agos.h b/engines/agos/agos.h index 6479ac2ae9..83e46f9723 100644 --- a/engines/agos/agos.h +++ b/engines/agos/agos.h @@ -83,9 +83,9 @@ struct VgaPointersEntry { struct VgaSprite { uint16 id; - uint16 image; + int16 image; uint16 palette; - uint16 x, y; /* actually signed numbers */ + int16 x, y; uint16 flags; uint16 priority; uint16 windowNum, zoneNum; @@ -105,9 +105,21 @@ struct VgaTimerEntry { const byte *script_pointer; uint16 sprite_id; uint16 cur_vga_file; + uint8 type; VgaTimerEntry() { memset(this, 0, sizeof(*this)); } }; +struct AnimTable { + const byte *srcPtr; + int16 x; + int16 y; + uint16 width; + uint16 height; + uint16 window; + uint16 id; + AnimTable() { memset(this, 0, sizeof(*this)); } +}; + enum SIMONGameType { GType_ELVIRA1 = 0, GType_ELVIRA2 = 1, @@ -118,33 +130,38 @@ enum SIMONGameType { GType_PP = 7 }; +enum EventType { + ANIMATE_INT = 1 << 1, + ANIMATE_EVENT = 1 << 2, + SCROLL_EVENT = 1 << 3, + IMAGE_EVENT2 = 1 << 4, + IMAGE_EVENT3 = 1 << 5 +}; + struct AGOSGameDescription; struct GameSpecificSettings; class Debugger; +// This is to help devices with small memory (PDA, smartphones, ...) +// to save a bit of memory used by opcode names in the AGOS engine. + +#ifndef REDUCE_MEMORY_USAGE +# define _OPCODE(ver, x) { &ver::x, #x } +#else +# define _OPCODE(ver, x) { &ver::x, "" } +#endif + class AGOSEngine : public Engine { friend class Debugger; friend class MoviePlayer; GUI::Debugger *getDebugger(); - typedef void (AGOSEngine::*OpcodeProc) (); - - void setupCommonOpcodes(OpcodeProc *op); - - void setupElvira1Opcodes(OpcodeProc *op); - void setupElvira2Opcodes(OpcodeProc *op); - void setupWaxworksOpcodes(OpcodeProc *op); - void setupSimon1Opcodes(OpcodeProc *op); - void setupSimon2Opcodes(OpcodeProc *op); - void setupFeebleOpcodes(OpcodeProc *op); - void setupPuzzleOpcodes(OpcodeProc *op); - - void setupOpcodes(); - OpcodeProc _opcode_table[300]; - int _numOpcodes; +public: + virtual void setupOpcodes(); + int _numOpcodes, _opcode; typedef void (AGOSEngine::*VgaOpcodeProc) (); @@ -152,20 +169,12 @@ class AGOSEngine : public Engine { VgaOpcodeProc _vga_opcode_table[100]; uint _numVideoOpcodes; - void setupCommonVideoOpcodes(VgaOpcodeProc *op); - - void setupElvira1VideoOpcodes(VgaOpcodeProc *op); - void setupElvira2VideoOpcodes(VgaOpcodeProc *op); - void setupWaxworksVideoOpcodes(VgaOpcodeProc *op); - void setupSimon1VideoOpcodes(VgaOpcodeProc *op); - void setupSimon2VideoOpcodes(VgaOpcodeProc *op); - void setupFeebleVideoOpcodes(VgaOpcodeProc *op); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); -public: const AGOSGameDescription *_gameDescription; bool initGame(void); - void setupGame(); + virtual void setupGame(); int getGameId() const; int getGameType() const; @@ -201,13 +210,6 @@ protected: byte _keyPressed; - typedef enum { - FORMAT_NONE, - FORMAT_MP3, - FORMAT_WAV, - FORMAT_VOC - } SoundFormat; - Common::File *_gameFile; byte *_strippedTxtMem; @@ -265,6 +267,7 @@ protected: bool _beardLoaded; bool _litBoxFlag; bool _mortalFlag; + bool _displayScreen; bool _updateScreen; bool _syncFlag2; bool _inCallBack; @@ -273,6 +276,8 @@ protected: bool _fastMode; bool _useBackGround; + bool _backFlag; + uint16 _debugMode; uint16 _language; bool _copyProtection; @@ -281,7 +286,6 @@ protected: bool _continousMainScript; bool _startVgaScript; bool _continousVgaScript; - bool _drawImagesDebug; bool _dumpImages; bool _speech; bool _subtitles; @@ -295,6 +299,7 @@ protected: byte _boxStarHeight; char _boxBuffer[310]; + char *_boxBufferPtr; int _boxLineCount; int _lineCounts[6]; char *_linePtrs[6]; @@ -371,6 +376,7 @@ protected: byte _leftButtonDown; byte _leftButton, _leftButtonCount, _leftButtonOld; byte _rightButtonDown; + bool _clickOnly; bool _noRightClick; Item *_dummyItem1; @@ -382,8 +388,6 @@ protected: uint16 _scrollDownHitArea; bool _fastFadeOutFlag; - bool _unkPalFlag; - bool _usePaletteDelay; byte _paletteFlag; int _bottomPalette; uint _fastFadeCount; @@ -403,7 +407,7 @@ protected: bool _showPreposition; bool _showMessageFlag; - uint _vgaSpriteChanged; + uint _copyScnFlag, _vgaSpriteChanged; byte *_block, *_blockEnd; byte *_vgaMemPtr, *_vgaMemEnd, *_vgaMemBase; @@ -416,7 +420,11 @@ protected: uint16 _syncCount, _timer5, _timer4; - uint16 _frameRate; + int16 _iconToggleCount, _voiceCount; + uint32 _lastTickCount, _thisTickCount; + uint32 _startSecondCount, _tSecondCount; + + uint16 _frameCount; uint16 _zoneNumber; uint16 _vgaWaitFor, _lastVgaWaitFor; @@ -430,6 +438,9 @@ protected: VgaTimerEntry *_nextVgaTimerToProcess; + uint8 _opcode177Var1, _opcode177Var2; + uint8 _opcode178Var1, _opcode178Var2; + Item *_objectArray[50]; Item *_itemStore[50]; @@ -447,7 +458,7 @@ protected: int16 *_variableArrayPtr; WindowBlock *_dummyWindow; - WindowBlock *_windowArray[8]; + WindowBlock *_windowArray[80]; byte _fcsData1[8]; bool _fcsData2[8]; @@ -460,10 +471,11 @@ protected: HitArea _hitAreas[250]; + AnimTable _screenAnim1[60]; VgaPointersEntry _vgaBufferPointers[450]; VgaSprite _vgaSprites[200]; - VgaSleepStruct _waitSyncTable[60]; VgaSleepStruct _waitEndTable[60]; + VgaSleepStruct _waitSyncTable[60]; const uint16 *_pathFindArray[100]; @@ -482,6 +494,15 @@ protected: byte _videoBuf1[32000]; uint16 _videoWindows[128]; + uint16 _window3Flag; + uint16 _window4Flag; + uint16 _window6Flag; + byte *_window4BackScn; + byte *_window6BackScn; + + uint16 _moveXMin, _moveYMin; + uint16 _moveXMax, _moveYMax; + VgaTimerEntry _vgaTimerList[205]; WindowBlock *_windowList; @@ -504,8 +525,9 @@ protected: Debugger *_debugger; - int _saveLoadRowCurPos; - int _numSaveGameRows; + uint _saveGameNameLen; + uint _saveLoadRowCurPos; + uint _numSaveGameRows; bool _saveDialogFlag; bool _saveOrLoad; bool _saveLoadEdit; @@ -549,6 +571,8 @@ protected: void loadSound(uint sound, int pan, int vol, uint type); void loadVoice(uint speechId); + void loadSoundFile(const char *filename); + int getUserFlag(Item *item, int a); int getUserFlag1(Item *item, int a); int getUserItem(Item *item, int n); @@ -589,6 +613,7 @@ protected: bool checkIfToRunSubroutineLine(SubroutineLine *sl, Subroutine *sub); int runScript(); + virtual void executeOpcode(int opcode) = 0; byte getByte(); int getNextWord(); @@ -645,9 +670,9 @@ protected: void defineBox(int id, int x, int y, int width, int height, int flags, int verb, Item *item_ptr); HitArea *findEmptyHitArea(); - void resetVerbs(); - void setVerb(HitArea * ha); - void hitarea_leave(HitArea * ha, bool state = false); + virtual void resetVerbs(); + virtual void setVerb(HitArea * ha); + virtual void hitarea_leave(HitArea * ha, bool state = false); void leaveHitAreaById(uint hitarea_id); void sendSync(uint a); @@ -673,17 +698,7 @@ protected: // Elvira 1 specific Item *getDoorOf(Item *item, uint16 d); Item *getExitOf_e1(Item *item, uint16 d); - void moveDirn_e1(Item *i, uint x); - - // Elvira 2 specific - int changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s); - uint16 getExitState(Item *item, uint16 x, uint16 d); - void setExitState(Item *i, uint16 n, uint16 d, uint16 s); - void setSRExit(Item *i, int n, int d, uint16 s); - void moveDirn_e2(Item *i, uint x); - - // Waxworks specific - void moveDirn_ww(Item *i, uint x); + virtual void moveDirn(Item *i, uint x); int canPlace(Item *x, Item *y); int contains(Item *a, Item *b); @@ -705,34 +720,13 @@ protected: void clearMenuStrip(); void doMenuStrip(uint menuNum); - void checkLinkBox(); - void hyperLinkOn(uint16 x); - void hyperLinkOff(); - void linksUp(); - void linksDown(); - void oracleTextUp(); - void oracleTextDown(); - void listSaveGames(int n); - void saveUserGame(int slot); - void windowBackSpace(WindowBlock *window); - - void oracleLogo(); - void scrollOracle(); - void scrollOracleUp(); - void scrollOracleDown(); - void swapCharacterLogo(); - void mouseOff(); void mouseOn(); - bool loadTablesIntoMem(uint subr_id); - bool loadTablesOldIntoMem(uint subr_id); - bool loadTablesNewIntoMem(uint subr_id); + virtual bool loadTablesIntoMem(uint subr_id); bool loadXTablesIntoMem(uint subr_id); void loadTextIntoMem(uint stringId); - bool loadRoomItems(uint item); - uint loadTextFile(const char *filename, byte *dst); Common::File *openTablesFile(const char *filename); void closeTablesFile(Common::File *in); @@ -750,10 +744,8 @@ protected: void endCutscene(); void runSubroutine101(); - void checkUp(WindowBlock *window); - void checkDown(WindowBlock *window); - void inventoryUp(WindowBlock *window); - void inventoryDown(WindowBlock *window); + virtual void inventoryUp(WindowBlock *window); + virtual void inventoryDown(WindowBlock *window); WindowBlock *openWindow(uint x, uint y, uint w, uint h, uint flags, uint fillColor, uint textColor); uint getWindowNum(WindowBlock *window); @@ -767,30 +759,25 @@ protected: HitArea *findBox(uint hitarea_id); void boxController(uint x, uint y, uint mode); void handleVerbClicked(uint verb); - void clearName(); + virtual void clearName(); void displayName(HitArea * ha); void resetNameWindow(); void displayBoxStars(); - void invertBox_FF(HitArea *ha, bool state); void invertBox(HitArea * ha, byte a, byte b, byte c, byte d); - void handleMouseMoved(); void initMouse(); - void loadMouseImage(); - void drawMousePointer(); - void drawMousePointer_FF(); - void drawMousePart(int image, byte x, byte y); + virtual void handleMouseMoved(); + virtual void drawMousePointer(); - void addArrows(WindowBlock *window); + virtual void addArrows(WindowBlock *window); void removeArrows(WindowBlock *window, uint num); - void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); bool hasIcon(Item *item); uint itemGetIconNumber(Item *item); - uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); - void drawIconArray(uint i, Item *item_ptr, int line, int classMask); - void drawIconArray_FF(uint i, Item *item_ptr, int line, int classMask); - void drawIconArray_Simon(uint i, Item *item_ptr, int line, int classMask); + virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + + virtual void drawIconArray(uint i, Item *item_ptr, int line, int classMask); void removeIconArray(uint num); void loadIconData(); @@ -808,7 +795,7 @@ protected: void loadZone(uint zoneNum); - void animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette, bool vgaScript = false); + void animate(uint16 windowNum, uint16 zoneNum, uint16 vgaSpriteId, int16 x, int16 y, uint16 palette, bool vgaScript = false); void setImage(uint16 vga_res_id, bool vgaScript = false); void setWindowImage(uint16 mode, uint16 vga_res_id); void setWindowImageEx(uint16 mode, uint16 vga_res); @@ -821,26 +808,18 @@ protected: void printVerbOf(uint hitarea_id); void showActionString(const byte *string); - void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width); - void sendInteractText(uint16 num, const char *fmt, ...); - void printInteractText(uint16 num, const char *string); + virtual void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width); void renderStringAmiga(uint vga_sprite_id, uint color, uint width, uint height, const char *txt); void renderString(uint vga_sprite_id, uint color, uint width, uint height, const char *txt); - void boxTextMessage(const char *x); - void boxTextMsg(const char *x); - void printBox(); - uint16 getBoxSize(); - uint16 checkFit(char *Ptr, int width, int lines); - void writeChar(WindowBlock *window, int x, int y, int offs, int val); byte *allocBlock(uint32 size); - void checkNoOverWrite(); + virtual void checkNoOverWrite(); void checkRunningAnims(); - void checkAnims(uint a); - void checkZonePtrs(); + virtual void checkAnims(uint a); + virtual void checkZonePtrs(); void setZoneBuffers(); void runVgaScript(); @@ -966,6 +945,7 @@ public: int getScriptReturn(); // Opcodes, common + void o_invalid(); void o_at(); void o_notAt(); void o_carried(); @@ -1048,6 +1028,7 @@ public: void o_defObj(); void o_here(); void o_doClassIcons(); + void o_playTune(); void o_setAdjNoun(); void o_saveUserGame(); void o_loadUserGame(); @@ -1059,7 +1040,185 @@ public: void o_setDollar(); void o_isBox(); - // Opcodes, Elvira 1 + int16 levelOf(Item *item); + int16 moreText(Item *i); + void lobjFunc(Item *i, const char *f); + uint confirmQuit(); + uint continueOrQuit(); + void printScroll(); + void synchChain(Item *i); + +protected: + bool drawImage_clip(VC10_state *state); + + void drawImage_init(int16 image, uint16 palette, int16 x, int16 y, uint16 flags); + + virtual void drawImage(VC10_state *state); + void drawBackGroundImage(VC10_state *state); + void drawVertImage(VC10_state *state); + + void setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height); + + void horizontalScroll(VC10_state *state); + void verticalScroll(VC10_state *state); + + int vcReadVarOrWord(); + uint vcReadNextWord(); + uint vcReadNextByte(); + uint vcReadVar(uint var); + void vcWriteVar(uint var, int16 value); + void vcSkipNextInstruction(); + + int getScale(int16 y, int16 x); + void checkScrollX(int16 x, int16 xpos); + void checkScrollY(int16 y, int16 ypos); + void centreScroll(); + + void clearVideoWindow(uint windowNum, uint color); + void clearVideoBackGround(uint windowNum, uint color); + + void setPaletteSlot(uint srcOffs, uint dstOffs); + void checkWaitEndTable(); + + void startOverlayAnims(); + void startAnOverlayAnim(); + + bool itemIsSiblingOf(uint16 val); + bool itemIsParentOf(uint16 a, uint16 b); + bool vc_maybe_skip_proc_1(uint16 a, int16 b); + + bool isVgaQueueEmpty(); + void haltAnimation(); + void restartAnimation(); + void addVgaEvent(uint16 num, uint8 type, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum); + void deleteVgaEvent(VgaTimerEntry * vte); + void processVgaEvents(); + void animateEvent(const byte *code_ptr, uint16 curZoneNum, uint16 cur_sprite); + void scrollEvent(); + void drawStuff(const byte *src, uint offs); + void imageEvent2(VgaTimerEntry * vte, uint dx); + void imageEvent3(VgaTimerEntry * vte, uint dx); + + VgaSprite *findCurSprite(); + + bool isSpriteLoaded(uint16 id, uint16 zoneNum); + + void resetWindow(WindowBlock *window); + void freeBox(uint index); + + void sendWindow(uint a); + + void restoreWindow(WindowBlock *window); + void colorWindow(WindowBlock *window); + + void restoreBlock(uint h, uint w, uint y, uint x); + + byte *getFrontBuf(); + byte *getBackBuf(); + byte *getBackGround(); + byte *getScaleBuf(); + + byte *convertImage(VC10_state *state, bool compressed); + + bool decrunchFile(byte *src, byte *dst, uint32 size); + void loadVGABeardFile(uint id); + void loadVGAVideoFile(uint id, uint type); + bool loadVGASoundFile(uint id, uint type); + + int init(); + int go(); + + void openGameFile(); + void readGameFile(void *dst, uint32 offs, uint32 size); + + void dimp_idle(); + void timer_callback(); + virtual void timer_proc1(); + + virtual void animateSprites(); + + void dirtyClips(); + void dirtyBackGround(); + void restoreBackGround(); + void saveBackGround(VgaSprite *vsp); + + void clearSurfaces(uint num_lines); + void displayScreen(); + + void dumpVideoScript(const byte *src, bool one_opcode_only); + void dumpVgaFile(const byte *vga); + void dumpVgaScript(const byte *ptr, uint res, uint sprite_id); + void dumpVgaScriptAlways(const byte *ptr, uint res, uint sprite_id); + void dumpVgaBitmaps(const byte *vga, byte *vga1, int res); + void dumpSingleBitmap(int file, int image, const byte *offs, int w, int h, byte base); + void dumpBitmap(const char *filename, const byte *offs, int w, int h, int flags, const byte *palette, byte base); + + void clearBackFromTop(uint lines); + void fillFrontFromBack(uint x, uint y, uint w, uint h); + void fillBackGroundFromBack(uint lines); + void fillBackFromFront(uint x, uint y, uint w, uint h); + + virtual void doOutput(const byte *src, uint len); + void clsCheck(WindowBlock *window); + + void quickLoadOrSave(); + void shutdown(); + + byte *vc10_uncompressFlip(const byte *src, uint w, uint h); + byte *vc10_flip(const byte *src, uint w, uint h); + + Item *getNextItemPtrStrange(); + + virtual bool loadGame(const char *filename, bool restartMode = false); + virtual bool saveGame(uint slot, const char *caption); + + void openTextWindow(); + void tidyIconArray(uint i); + + virtual void windowNewLine(WindowBlock *window); + void windowDrawChar(WindowBlock *window, uint x, uint y, byte chr); + + void loadMusic(uint music); + void loadModule(uint music); + + void checkTimerCallback(); + void delay(uint delay); + void pause(); + + void waitForMark(uint i); + void scrollScreen(); + + void decodeColumn(byte *dst, const byte *src, int height); + void decodeRow(byte *dst, const byte *src, int width); + void hitarea_stuff_helper_2(); + void fastFadeIn(); + void slowFadeIn(); + + void vcStopAnimation(uint file, uint sprite); + + void disableFileBoxes(); + virtual void listSaveGames(char *dst); + virtual void userGame(bool load); + virtual int userGameGetKey(bool *b, char *buf, uint maxChar); + void userGameBackSpace(WindowBlock *window, int x, byte b = 0); + void fileError(WindowBlock *window, bool save_error); + + int countSaveGames(); + + char *genSaveName(int slot); +}; + +class AGOSEngine_Elvira1 : public AGOSEngine { +public: + AGOSEngine_Elvira1(OSystem *system); + //~AGOSEngine_Elvira1(); + + virtual void setupGame(); + virtual void setupOpcodes(); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); + + virtual void executeOpcode(int opcode); + void oe1_present(); void oe1_notPresent(); void oe1_worn(); @@ -1108,6 +1267,8 @@ public: void oe1_bitSet(); void oe1_bitTest(); void oe1_zoneDisk(); + void oe1_saveUserGame(); + void oe1_loadUserGame(); void oe1_printStats(); void oe1_stopTune(); void oe1_printPlayerDamage(); @@ -1116,19 +1277,30 @@ public: void oe1_printPlayerHit(); void oe1_printMonsterHit(); - int16 levelOf(Item *item); - int16 moreText(Item *i); - void lobjFunc(Item *i, const char *f); - uint confirmQuit(); - uint continueOrQuit(); - void printScroll(); - void synchChain(Item *i); +protected: + typedef void (AGOSEngine_Elvira1::*OpcodeProcElvira1) (); + struct OpcodeEntryElvira1 { + OpcodeProcElvira1 proc; + const char *desc; + }; + + const OpcodeEntryElvira1 *_opcodesElvira1; +}; + +class AGOSEngine_Elvira2 : public AGOSEngine_Elvira1 { +public: + AGOSEngine_Elvira2(OSystem *system); + //~AGOSEngine_Elvira2(); + + virtual void setupGame(); + virtual void setupOpcodes(); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); + + virtual void executeOpcode(int opcode); - // Opcodes, Elvira 2 void oe2_moveDirn(); void oe2_doClass(); void oe2_pObj(); - void oe2_loadGame(); void oe2_drawItem(); void oe2_doTable(); void oe2_pauseGame(); @@ -1167,12 +1339,53 @@ public: void oe2_b2Zero(); void oe2_b2NotZero(); - // Opcodes, Waxworks - void oww_moveDirn(); +protected: + typedef void (AGOSEngine_Elvira2::*OpcodeProcElvira2) (); + struct OpcodeEntryElvira2 { + OpcodeProcElvira2 proc; + const char *desc; + }; + + const OpcodeEntryElvira2 *_opcodesElvira2; + + virtual bool loadGame(const char *filename, bool restartMode = false); + virtual bool saveGame(uint slot, const char *caption); + + virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + + virtual void addArrows(WindowBlock *window); + virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + + virtual void moveDirn(Item *i, uint x); + + int changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s); + uint16 getExitState(Item *item, uint16 x, uint16 d); + void setExitState(Item *i, uint16 n, uint16 d, uint16 s); + void setSRExit(Item *i, int n, int d, uint16 s); +}; + +class AGOSEngine_Waxworks : public AGOSEngine_Elvira2 { +public: + AGOSEngine_Waxworks(OSystem *system); + //~AGOSEngine_Waxworks(); + + virtual void setupGame(); + virtual void setupOpcodes(); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); + + virtual void executeOpcode(int opcode); + + void boxTextMessage(const char *x); + void boxTextMsg(const char *x); + void printBox(); + uint16 getBoxSize(); + uint16 checkFit(char *Ptr, int width, int lines); + void oww_goto(); void oww_addTextBox(); void oww_setShortText(); void oww_setLongText(); + void oww_printLongText(); void oww_whereTo(); void oww_menu(); void oww_textMenu(); @@ -1185,10 +1398,40 @@ public: void oww_lockZones(); void oww_unlockZones(); +protected: + typedef void (AGOSEngine_Waxworks::*OpcodeProcWaxworks) (); + struct OpcodeEntryWaxworks { + OpcodeProcWaxworks proc; + const char *desc; + }; + + const OpcodeEntryWaxworks *_opcodesWaxworks; + + virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + + virtual void addArrows(WindowBlock *window); + virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + + virtual bool loadTablesIntoMem(uint subr_id); + + bool loadRoomItems(uint item); + + virtual void moveDirn(Item *i, uint x); +}; + +class AGOSEngine_Simon1 : public AGOSEngine_Waxworks { +public: + AGOSEngine_Simon1(OSystem *system); + //~AGOSEngine_Simon1(); + + virtual void setupGame(); + virtual void setupOpcodes(); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); + + virtual void executeOpcode(int opcode); + // Opcodes, Simon 1 - void oww_printLongText(); void os1_animate(); - void os1_playTune(); void os1_pauseGame(); void os1_screenTextBox(); void os1_screenTextMsg(); @@ -1205,7 +1448,40 @@ public: void os1_unfreezeZones(); void os1_specialFade(); - // Opcodes, Simon 2 +protected: + typedef void (AGOSEngine_Simon1::*OpcodeProcSimon1) (); + struct OpcodeEntrySimon1 { + OpcodeProcSimon1 proc; + const char *desc; + }; + + const OpcodeEntrySimon1 *_opcodesSimon1; + + virtual void drawImage(VC10_state *state); + void drawMaskedImage(VC10_state *state); + void draw32ColorImage(VC10_state *state); + + virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + + virtual void addArrows(WindowBlock *window); + virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); + + virtual void listSaveGames(char *dst); + virtual void userGame(bool load); + virtual int userGameGetKey(bool *b, char *buf, uint maxChar); +}; + +class AGOSEngine_Simon2 : public AGOSEngine_Simon1 { +public: + AGOSEngine_Simon2(OSystem *system); + //~AGOSEngine_Simon2(); + + virtual void setupGame(); + virtual void setupOpcodes(); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); + + virtual void executeOpcode(int opcode); + void os2_printLongText(); void os2_rescan(); void os2_animate(); @@ -1218,7 +1494,32 @@ public: void os2_clearMarks(); void os2_waitMark(); - // Opcodes, Feeble Files +protected: + typedef void (AGOSEngine_Simon2::*OpcodeProcSimon2) (); + struct OpcodeEntrySimon2 { + OpcodeProcSimon2 proc; + const char *desc; + }; + + const OpcodeEntrySimon2 *_opcodesSimon2; + + virtual void drawIcon(WindowBlock *window, uint icon, uint x, uint y); + + virtual void addArrows(WindowBlock *window); + virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); +}; + +class AGOSEngine_Feeble : public AGOSEngine_Simon2 { +public: + AGOSEngine_Feeble(OSystem *system); + //~AGOSEngine_Feeble(); + + virtual void setupGame(); + virtual void setupOpcodes(); + virtual void setupVideoOpcodes(VgaOpcodeProc *op); + + virtual void executeOpcode(int opcode); + void off_chance(); void off_jumpOut(); void off_addTextBox(); @@ -1253,174 +1554,116 @@ public: void off_b3Zero(); void off_b3NotZero(); - // Opcodes, Puzzle Pack - void opp_iconifyWindow(); - void opp_restoreOopsPosition(); - void opp_loadMouseImage(); - void opp_message(); - void opp_setShortText(); - void opp_loadHiScores(); - void opp_checkHiScores(); - void opp_sync(); - void opp_saveUserGame(); - void opp_loadUserGame(); - void opp_saveOopsPosition(); - void opp_resetGameTime(); - void opp_resetPVCount(); - void opp_setPathValues(); - void opp_restartClock(); - protected: - bool drawImages_clip(VC10_state *state); + typedef void (AGOSEngine_Feeble::*OpcodeProcFeeble) (); + struct OpcodeEntryFeeble { + OpcodeProcFeeble proc; + const char *desc; + }; - void drawImages(VC10_state *state); - void drawImages_Amiga(VC10_state *state); - void drawImages_Simon(VC10_state *state); - void drawImages_Feeble(VC10_state *state); + const OpcodeEntryFeeble *_opcodesFeeble; + virtual void drawImage(VC10_state *state); void scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY); - void horizontalScroll(VC10_state *state); - void verticalScroll(VC10_state *state); - - int vcReadVarOrWord(); - uint vcReadNextWord(); - uint vcReadNextByte(); - uint vcReadVar(uint var); - void vcWriteVar(uint var, int16 value); - void vcSkipNextInstruction(); - - int getScale(int16 y, int16 x); - void checkScrollX(int16 x, int16 xpos); - void checkScrollY(int16 y, int16 ypos); - void centreScroll(); - - void clearWindow(uint windowNum, uint color); - void setPaletteSlot(uint srcOffs, uint dstOffs); - void checkWaitEndTable(); - - void startOverlayAnims(); - void startAnOverlayAnim(); - - bool itemIsSiblingOf(uint16 val); - bool itemIsParentOf(uint16 a, uint16 b); - bool vc_maybe_skip_proc_1(uint16 a, int16 b); - - bool isVgaQueueEmpty(); - void haltAnimation(); - void restartAnimation(); - void addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum); - void deleteVgaEvent(VgaTimerEntry * vte); - void processVgaEvents(); - void animateEvent(const byte *code_ptr, uint16 curZoneNum, uint16 cur_sprite); - void scrollEvent(); - - VgaSprite *findCurSprite(); - - bool isSpriteLoaded(uint16 id, uint16 zoneNum); - - void resetWindow(WindowBlock *window); - void freeBox(uint index); - - void windowPutChar(uint a); - - void restoreWindow(WindowBlock *window); - void colorWindow(WindowBlock *window); - - void restoreBlock(uint h, uint w, uint y, uint x); - byte *getFrontBuf(); - byte *getBackBuf(); - byte *getBackGround(); - byte *getScaleBuf(); - - byte *convertImage(VC10_state *state, bool compressed); + void drawMousePart(int image, byte x, byte y); + virtual void drawMousePointer(); - bool decrunchFile(byte *src, byte *dst, uint32 size); - void loadVGABeardFile(uint id); - void loadVGAVideoFile(uint id, uint type); - bool loadVGASoundFile(uint id, uint type); + virtual void animateSprites(); + void animateSpritesByY(); - int init(); - int go(); + void oracleLogo(); + void swapCharacterLogo(); + virtual void timer_proc1(); - void openGameFile(); - void readGameFile(void *dst, uint32 offs, uint32 size); + virtual void addArrows(WindowBlock *window); + virtual uint setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr); - void timer_callback(); - void timer_proc1(); + virtual void resetVerbs(); + virtual void setVerb(HitArea * ha); + virtual void hitarea_leave(HitArea * ha, bool state = false); + void invertBox(HitArea *ha, bool state); - void animateSprites(); - void animateSpritesDebug(); - void animateSpritesByY(); + virtual void windowNewLine(WindowBlock *window); - void clearSurfaces(uint num_lines); - void updateScreen(); + virtual void clearName(); - void dumpVideoScript(const byte *src, bool one_opcode_only); - void dumpVgaFile(const byte *vga); - void dumpVgaScript(const byte *ptr, uint res, uint sprite_id); - void dumpVgaScriptAlways(const byte *ptr, uint res, uint sprite_id); - void dumpVgaBitmaps(const byte *vga, byte *vga1, int res); - void dumpSingleBitmap(int file, int image, const byte *offs, int w, int h, byte base); - void dumpBitmap(const char *filename, const byte *offs, int w, int h, int flags, const byte *palette, byte base); + virtual void drawIconArray(uint i, Item *item_ptr, int line, int classMask); - void clearBackFromTop(uint lines); - void fillFrontFromBack(uint x, uint y, uint w, uint h); - void fillBackGroundFromBack(uint lines); - void fillBackFromFront(uint x, uint y, uint w, uint h); + virtual void doOutput(const byte *src, uint len); - void print_char_helper_1(const byte *src, uint len); - void clsCheck(WindowBlock *window); + virtual void printScreenText(uint vga_sprite_id, uint color, const char *string_ptr, int16 x, int16 y, int16 width); - void quickLoadOrSave(); - void shutdown(); + void printInteractText(uint16 num, const char *string); + void sendInteractText(uint16 num, const char *fmt, ...); - byte *vc10_uncompressFlip(const byte *src, uint w, uint h); - byte *vc10_flip(const byte *src, uint w, uint h); + void checkLinkBox(); + void hyperLinkOn(uint16 x); + void hyperLinkOff(); + void linksUp(); + void linksDown(); - Item *getNextItemPtrStrange(); + void checkUp(WindowBlock *window); + void checkDown(WindowBlock *window); + virtual void inventoryUp(WindowBlock *window); + virtual void inventoryDown(WindowBlock *window); - bool loadGame_e1(const char *filename, bool restartMode = false); - bool saveGame_e1(const char *filename); + void oracleTextUp(); + void oracleTextDown(); + void scrollOracle(); + void scrollOracleUp(); + void scrollOracleDown(); - bool loadGame(const char *filename, bool restartMode = false); - bool saveGame(uint slot, const char *caption); + void listSaveGames(int n); + void saveUserGame(int slot); + void windowBackSpace(WindowBlock *window); - void openTextWindow(); - void tidyIconArray(uint i); + virtual void checkNoOverWrite(); + virtual void checkAnims(uint a); + virtual void checkZonePtrs(); +}; - void windowNewLine(WindowBlock *window); - void windowDrawChar(WindowBlock *window, uint x, uint y, byte chr); +class AGOSEngine_PuzzlePack : public AGOSEngine_Feeble { +public: + AGOSEngine_PuzzlePack(OSystem *system); + //~AGOSEngine_PuzzlePack(); - void loadMusic(uint music); - void loadModule(uint music); + virtual void setupGame(); + virtual void setupOpcodes(); - void checkTimerCallback(); - void delay(uint delay); - void pause(); + virtual void executeOpcode(int opcode); - void waitForMark(uint i); - void scrollScreen(); + void opp_iconifyWindow(); + void opp_restoreOopsPosition(); + void opp_loadMouseImage(); + void opp_message(); + void opp_setShortText(); + void opp_loadHiScores(); + void opp_checkHiScores(); + void opp_sync(); + void opp_saveUserGame(); + void opp_loadUserGame(); + void opp_saveOopsPosition(); + void opp_resetGameTime(); + void opp_resetPVCount(); + void opp_setPathValues(); + void opp_restartClock(); - void decodeColumn(byte *dst, const byte *src, int height); - void decodeRow(byte *dst, const byte *src, int width); - void hitarea_stuff_helper_2(); - void fastFadeIn(); - void slowFadeIn(); +protected: + typedef void (AGOSEngine_PuzzlePack::*OpcodeProcPuzzlePack) (); + struct OpcodeEntryPuzzlePack { + OpcodeProcPuzzlePack proc; + const char *desc; + }; - void vcStopAnimation(uint file, uint sprite); + const OpcodeEntryPuzzlePack *_opcodesPuzzlePack; - void userGame(bool load); - void disableFileBoxes(); - int userGameGetKey(bool *b, char *buf); - void userGameBackSpace(WindowBlock *window, int x, byte b = 0); - void listSaveGames(char *buf); - void fileError(WindowBlock *window, bool save_error); + virtual void handleMouseMoved(); + virtual void drawMousePointer(); - int countSaveGames(); - int displaySaveGameList(int curpos, bool load, char *dst); + virtual void resetVerbs(); - char *genSaveName(int slot); + void loadMouseImage(); }; } // End of namespace AGOS diff --git a/engines/agos/charset.cpp b/engines/agos/charset.cpp index 4b318a3784..c43bea640e 100644 --- a/engines/agos/charset.cpp +++ b/engines/agos/charset.cpp @@ -28,47 +28,52 @@ namespace AGOS { -void AGOSEngine::print_char_helper_1(const byte *src, uint len) { - uint idx; - +void AGOSEngine_Feeble::doOutput(const byte *src, uint len) { if (_textWindow == NULL) return; while (len-- != 0) { - if (getGameType() == GType_FF || getGameType() == GType_PP) { - if (getBitFlag(93)) { + if (getBitFlag(93)) { + if (_curWindow == 3) { + if ((_newLines >= _textWindow->scrollY) && (_newLines < (_textWindow->scrollY + 3))) + sendWindow(*src); + if (*src == '\n') // Do two top lines of text only + _newLines++; + src++; + } + } else { + if (getBitFlag(94)) { if (_curWindow == 3) { - if ((_newLines >= _textWindow->scrollY) && (_newLines < (_textWindow->scrollY + 3))) - windowPutChar(*src); - if (*src == '\n') // Do two top lines of text only + if (_newLines == (_textWindow->scrollY + 7)) + sendWindow(*src); + if (*src == '\n') // Do two top lines of text only _newLines++; src++; } } else { - if (getBitFlag(94)) { - if (_curWindow == 3) { - if (_newLines == (_textWindow->scrollY + 7)) - windowPutChar(*src); - if (*src == '\n') // Do two top lines of text only - _newLines++; - src++; - } - } else { - if (getBitFlag(92)) - delay(50); - windowPutChar(*src++); - } - } - } else { - if (*src != 12 && _textWindow->iconPtr != NULL && - _fcsData1[idx = getWindowNum(_textWindow)] != 2) { - - _fcsData1[idx] = 2; - _fcsData2[idx] = 1; + if (getBitFlag(92)) + delay(50); + sendWindow(*src++); } + } + } +} + +void AGOSEngine::doOutput(const byte *src, uint len) { + uint idx; + + if (_textWindow == NULL) + return; + + while (len-- != 0) { + if (*src != 12 && _textWindow->iconPtr != NULL && + _fcsData1[idx = getWindowNum(_textWindow)] != 2) { - windowPutChar(*src++); + _fcsData1[idx] = 2; + _fcsData2[idx] = 1; } + + sendWindow(*src++); } } @@ -529,7 +534,7 @@ void AGOSEngine::justifyOutPut(byte chr) { _numLettersToPrint = 0; _printCharCurPos = 0; _printCharPixelCount = 0; - print_char_helper_1(&chr, 1); + doOutput(&chr, 1); clsCheck(_textWindow); } else if (chr == 0 || chr == ' ' || chr == 10) { bool fit; @@ -546,13 +551,13 @@ void AGOSEngine::justifyOutPut(byte chr) { if (fit) { _printCharCurPos += _printCharPixelCount; - print_char_helper_1(_lettersToPrintBuf, _numLettersToPrint); + doOutput(_lettersToPrintBuf, _numLettersToPrint); if (_printCharCurPos == _printCharMaxPos) { _printCharCurPos = 0; } else { if (chr) - print_char_helper_1(&chr, 1); + doOutput(&chr, 1); if (chr == 10) _printCharCurPos = 0; else if (chr != 0) @@ -561,13 +566,13 @@ void AGOSEngine::justifyOutPut(byte chr) { } else { const byte newline_character = 10; _printCharCurPos = _printCharPixelCount; - print_char_helper_1(&newline_character, 1); - print_char_helper_1(_lettersToPrintBuf, _numLettersToPrint); + doOutput(&newline_character, 1); + doOutput(_lettersToPrintBuf, _numLettersToPrint); if (chr == ' ') { - print_char_helper_1(&chr, 1); + doOutput(&chr, 1); _printCharCurPos += (getGameType() == GType_FF || getGameType() == GType_PP) ? feebleFontSize[chr - 32] : 1; } else { - print_char_helper_1(&chr, 1); + doOutput(&chr, 1); _printCharCurPos = 0; } } @@ -666,35 +671,30 @@ void AGOSEngine::windowPutChar(WindowBlock *window, byte c, byte b) { } } -void AGOSEngine::windowNewLine(WindowBlock *window) { - if (getGameType() == GType_FF) { - if (_noOracleScroll == 0) { - if (window->height < window->textRow + 30) { - if (!getBitFlag(94)) { - _noOracleScroll = 1; - if (getBitFlag(92)) { - _noOracleScroll = 0; - checkLinkBox(); - scrollOracle(); - linksUp(); - window->scrollY++; - _oracleMaxScrollY++; - } else { - _oracleMaxScrollY++; - checkLinkBox(); - } +void AGOSEngine_Feeble::windowNewLine(WindowBlock *window) { + if (_noOracleScroll == 0) { + if (window->height < window->textRow + 30) { + if (!getBitFlag(94)) { + _noOracleScroll = 1; + if (getBitFlag(92)) { + _noOracleScroll = 0; + checkLinkBox(); + scrollOracle(); + linksUp(); + window->scrollY++; + _oracleMaxScrollY++; + } else { + _oracleMaxScrollY++; + checkLinkBox(); } - } else { - window->textRow += 15; - checkLinkBox(); } } else { - _oracleMaxScrollY++; + window->textRow += 15; checkLinkBox(); } } else { - if (window->textRow != window->height) - window->textRow++; + _oracleMaxScrollY++; + checkLinkBox(); } window->textColumn = 0; @@ -702,6 +702,19 @@ void AGOSEngine::windowNewLine(WindowBlock *window) { window->textLength = 0; } +void AGOSEngine::windowNewLine(WindowBlock *window) { + window->textColumn = 0; + window->textColumnOffset = 0; + window->textLength = 0; + + if (window->textRow == window->height) { + // TODO + debug(0, "Window Scroll"); + } else { + window->textRow++; + } +} + #ifdef PALMOS_68K static const byte *czech_windowFont; static const byte *russian_windowFont; diff --git a/engines/agos/cursor.cpp b/engines/agos/cursor.cpp index 33471f2e43..b6c7a52c24 100644 --- a/engines/agos/cursor.cpp +++ b/engines/agos/cursor.cpp @@ -300,7 +300,7 @@ static const byte _mouseOffs[29 * 32] = { 0,0,10,7,10,6,10,5,10,4,10,3,10,4,10,5,10,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; -void AGOSEngine::handleMouseMoved() { +void AGOSEngine_PuzzlePack::handleMouseMoved() { uint x; if (getGameId() != GID_DIMP && _mouseHideCount) { @@ -311,6 +311,38 @@ void AGOSEngine::handleMouseMoved() { CursorMan.showMouse(true); _mouse = _eventMan->getMousePos(); + x = 0; + if (_lastHitArea3 == 0 && _leftButtonDown != 0) { + _verbHitArea = 300; + _leftButtonDown = 0; + x = 1; + } + + if (_rightButtonDown != 0) { + _verbHitArea = (getGameId() == GID_DIMP) ? 301 : 300; + _rightButtonDown = 0; + x = 1; + } + + boxController(_mouse.x, _mouse.y, x); + _lastHitArea3 = _lastHitArea; + if (x == 1 && _lastHitArea == NULL) + _lastHitArea3 = (HitArea *) -1; + + drawMousePointer(); +} + +void AGOSEngine::handleMouseMoved() { + uint x; + + if (_mouseHideCount) { + CursorMan.showMouse(false); + return; + } + + CursorMan.showMouse(true); + _mouse = _eventMan->getMousePos(); + if (_defaultVerb) { uint id = 101; if (_mouse.y >= 136) @@ -386,8 +418,6 @@ void AGOSEngine::handleMouseMoved() { } } - // FIXME: The value of _mouseOld is *never* changed and hence - // always equal to (0,0). This seems like a bug. if (_mouse != _mouseOld) _needHitAreaRecalc++; @@ -416,14 +446,8 @@ void AGOSEngine::handleMouseMoved() { x = 0; if (_lastHitArea3 == 0 && _leftButtonDown != 0) { - if (getGameType() == GType_PP) - _verbHitArea = 300; _leftButtonDown = 0; x = 1; - } else if (getGameType() == GType_PP && _rightButtonDown != 0) { - _verbHitArea = 300; - _rightButtonDown = 0; - x = 1; } else { if (_litBoxFlag == 0 && _needHitAreaRecalc == 0) goto get_out; @@ -436,10 +460,9 @@ boxstuff: _lastHitArea3 = (HitArea *) -1; get_out: - if (getGameType() == GType_FF) - drawMousePointer_FF(); - else - drawMousePointer(); + + _mouseOld = _mouse; + drawMousePointer(); _needHitAreaRecalc = 0; _litBoxFlag = 0; @@ -497,7 +520,7 @@ void AGOSEngine::initMouse() { } } -void AGOSEngine::loadMouseImage() { +void AGOSEngine_PuzzlePack::loadMouseImage() { loadZone(_variableArray[500]); VgaPointersEntry *vpe = &_vgaBufferPointers[_variableArray[500]]; @@ -505,47 +528,41 @@ void AGOSEngine::loadMouseImage() { memcpy(_mouseData, src, _maxCursorWidth * _maxCursorHeight); } -void AGOSEngine::drawMousePointer() { - if (getGameType() == GType_PP && getGameId() != GID_DIMP) { - CursorMan.replaceCursor(_mouseData, _maxCursorWidth, _maxCursorHeight, 37, 48, 0); - } else if (getGameType() == GType_SIMON2) { - CursorMan.replaceCursor(_simon2_cursors[_mouseCursor], 16, 16, 7, 7); - } else if (getGameType() == GType_SIMON1) { - CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); +void AGOSEngine_PuzzlePack::drawMousePointer() { + if (getGameId() == GID_DIMP) { + AGOSEngine::drawMousePointer(); } else { - const uint16 *src; - int i, j; + CursorMan.replaceCursor(_mouseData, _maxCursorWidth, _maxCursorHeight, 37, 48, 0); + } +} - const uint8 color = (getGameType() == GType_ELVIRA1) ? 15: 65; - memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); +void AGOSEngine_Feeble::drawMousePart(int image, byte x, byte y) { + VgaPointersEntry *vpe = &_vgaBufferPointers[7]; + byte *src; + int width, height; - uint cursor = _mouseCursor; - if (getGameType() == GType_ELVIRA1 && cursor == 2) - cursor = 3; + byte *dst = _mouseData + y * _maxCursorWidth + x; - if (_dragFlag != 0) - cursor = 2; + src = vpe->vgaFile2 + image * 8; + width = READ_LE_UINT16(src + 6); + height = READ_LE_UINT16(src + 4); - src = _common_cursors[cursor]; + src = vpe->vgaFile2 + READ_LE_UINT32(src); - for (i = 0; i < 16; i++) { - for (j = 0; j < 16; j++) { - if (src[0] & (1 << (15 - (j % 16)))) { - if (src[1] & (1 << (15 - (j % 16)))) { - _mouseData[16 * i + j] = color; - } else { - _mouseData[16 * i + j] = 0; - } - } - } - src += 2; - } + assert(width + x <= _maxCursorWidth); + assert(height + y <= _maxCursorWidth); - CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); + for (int h = 0; h < height; h++) { + for (int w = 0; w < width; w++) { + if (src[w] != 0) + dst[w] = src[w]; + } + src += width; + dst += _maxCursorWidth; } } -void AGOSEngine::drawMousePointer_FF() { +void AGOSEngine_Feeble::drawMousePointer() { uint cursor; int image, offs; @@ -602,29 +619,41 @@ void AGOSEngine::drawMousePointer_FF() { } } -void AGOSEngine::drawMousePart(int image, byte x, byte y) { - VgaPointersEntry *vpe = &_vgaBufferPointers[7]; - byte *src; - int width, height; +void AGOSEngine::drawMousePointer() { + if (getGameType() == GType_SIMON2) { + CursorMan.replaceCursor(_simon2_cursors[_mouseCursor], 16, 16, 7, 7); + } else if (getGameType() == GType_SIMON1) { + CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); + } else { + const uint16 *src; + int i, j; - byte *dst = _mouseData + y * _maxCursorWidth + x; + const uint8 color = (getGameType() == GType_ELVIRA1) ? 15: 65; + memset(_mouseData, 0xFF, _maxCursorWidth * _maxCursorHeight); - src = vpe->vgaFile2 + image * 8; - width = READ_LE_UINT16(src + 6); - height = READ_LE_UINT16(src + 4); + uint cursor = _mouseCursor; + if (getGameType() == GType_ELVIRA1 && cursor == 2) + cursor = 3; - src = vpe->vgaFile2 + READ_LE_UINT32(src); + if (_dragFlag != 0) + cursor = 2; - assert(width + x <= _maxCursorWidth); - assert(height + y <= _maxCursorWidth); + src = _common_cursors[cursor]; - for (int h = 0; h < height; h++) { - for (int w = 0; w < width; w++) { - if (src[w] != 0) - dst[w] = src[w]; + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + if (src[0] & (1 << (15 - (j % 16)))) { + if (src[1] & (1 << (15 - (j % 16)))) { + _mouseData[16 * i + j] = color; + } else { + _mouseData[16 * i + j] = 0; + } + } + } + src += 2; } - src += width; - dst += _maxCursorWidth; + + CursorMan.replaceCursor(_mouseData, 16, 16, 0, 0, 0xFF); } } diff --git a/engines/agos/debug.cpp b/engines/agos/debug.cpp index 34529ccbd8..507f0ae9e6 100644 --- a/engines/agos/debug.cpp +++ b/engines/agos/debug.cpp @@ -435,7 +435,7 @@ void AGOSEngine::dumpBitmap(const char *filename, const byte *offs, int w, int h VC10_state state; state.depack_cont = -0x80; - state.depack_src = offs; + state.srcPtr = offs; state.dh = h; state.y_skip = 0; diff --git a/engines/agos/game.cpp b/engines/agos/detection.cpp index e0e60c43a2..e814625607 100644 --- a/engines/agos/game.cpp +++ b/engines/agos/detection.cpp @@ -1,6 +1,6 @@ /* ScummVM - Scumm Interpreter * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,6 +26,7 @@ #include "base/plugins.h" #include "common/advancedDetector.h" +#include "common/config-manager.h" #include "agos/agos.h" @@ -75,11 +76,7 @@ static const PlainGameDescriptor simonGames[] = { {0, 0} }; -namespace AGOS { - -#include "agosgame.cpp" - -} +#include "agos/detection_tables.h" static const Common::ADParams detectionParams = { // Pointer to ADGameDescription or its superset structure @@ -102,8 +99,54 @@ static const Common::ADParams detectionParams = { Common::kADFlagAugmentPreferredTarget }; -ADVANCED_DETECTOR_DEFINE_PLUGIN(AGOS, AGOS::AGOSEngine, detectionParams); +GameList Engine_AGOS_gameIDList() { + return GameList(simonGames); +} + +GameDescriptor Engine_AGOS_findGameID(const char *gameid) { + return Common::AdvancedDetector::findGameID(gameid, detectionParams); +} +GameList Engine_AGOS_detectGames(const FSList &fslist) { + return Common::AdvancedDetector::detectAllGames(fslist, detectionParams); +} + +PluginError Engine_AGOS_create(OSystem *syst, Engine **engine) { + assert(engine); + const char *gameid = ConfMan.get("gameid").c_str(); + + //const AGOSGameDescription gd = (const AGOSGameDescription *)Common::AdvancedDetector::detectBestMatchingGame(detectionParams); + //if (gd == 0) { + // return kNoGameDataFoundError; + //} + + if (!scumm_stricmp("elvira1", gameid)) { + *engine = new AGOS::AGOSEngine_Elvira1(syst); + } else if (!scumm_stricmp("elvira2", gameid)) { + *engine = new AGOS::AGOSEngine_Elvira2(syst); + } else if (!scumm_stricmp("waxworks", gameid)) { + *engine = new AGOS::AGOSEngine_Waxworks(syst); + } else if (!scumm_stricmp("simon1", gameid)) { + *engine = new AGOS::AGOSEngine_Simon1(syst); + } else if (!scumm_stricmp("simon2", gameid)) { + *engine = new AGOS::AGOSEngine_Simon2(syst); + } else if (!scumm_stricmp("feeble", gameid)) { + *engine = new AGOS::AGOSEngine_Feeble(syst); + } else if (!scumm_stricmp("dimp", gameid)) { + *engine = new AGOS::AGOSEngine_PuzzlePack(syst); + } else if (!scumm_stricmp("jumble", gameid)) { + *engine = new AGOS::AGOSEngine_PuzzlePack(syst); + } else if (!scumm_stricmp("puzzle", gameid)) { + *engine = new AGOS::AGOSEngine_PuzzlePack(syst); + } else if (!scumm_stricmp("swampy", gameid)) { + *engine = new AGOS::AGOSEngine_PuzzlePack(syst); + } else { + error("AGOS engine created with invalid gameid"); + } + + return kNoError; +} + REGISTER_PLUGIN(AGOS, "AGOS", "AGOS (C) Adventure Soft"); namespace AGOS { diff --git a/engines/agos/agosgame.cpp b/engines/agos/detection_tables.h index 3e64f3e323..b858cf3d5d 100644 --- a/engines/agos/agosgame.cpp +++ b/engines/agos/detection_tables.h @@ -1,3 +1,28 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +namespace AGOS { + static const AGOSGameDescription gameDescriptions[] = { // Elvira 1 - English Amiga Floppy Demo { @@ -621,7 +646,7 @@ static const AGOSGameDescription gameDescriptions[] = { GType_SIMON1, GID_SIMON1AMIGA, - GF_32COLOR | GF_CRUNCHED | GF_CRUNCHED_GAMEPC | GF_OLD_BUNDLE | GF_PLANAR | GF_DEMO + GF_32COLOR | GF_CRUNCHED | GF_CRUNCHED_GAMEPC | GF_OLD_BUNDLE | GF_PLANAR }, // Simon the Sorcerer 1 - English Amiga AGA Floppy @@ -1018,6 +1043,30 @@ static const AGOSGameDescription gameDescriptions[] = { GF_TALKIE }, + // Simon the Sorcerer 1 - English DOS CD with Russian patch + { + { + "simon1", + "CD", + + { + { "gamepc", GAME_BASEFILE, "3fac46064f69e5298f4f027f204c5aab", -1}, + { "icon.dat", GAME_ICONFILE, "22107c24dfb31b66ac503c28a6e20b19", -1}, + { "simon.gme", GAME_GMEFILE, "91321f0d806f8d9fef71a00e58581427", -1}, + { "stripped.txt", GAME_STRFILE, "ef51ac74c946881ae4d7ca66cc7a0d1e", -1}, + { "tbllist", GAME_TBLFILE, "d198a80de2c59e4a0cd24b98814849e8", -1}, + { NULL, 0, NULL, 0} + }, + Common::RU_RUS, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + + GType_SIMON1, + GID_SIMON1TALKIE, + GF_TALKIE + }, + // Simon the Sorcerer 1 - French DOS CD { { @@ -1187,30 +1236,6 @@ static const AGOSGameDescription gameDescriptions[] = { GF_TALKIE }, - // Simon the Sorcerer 1 - English Windows CD with Russian patch - { - { - "simon1", - "CD", - - { - { "gamepc", GAME_BASEFILE, "4536a706412b36d628f12142bfa97af0", -1}, - { "icon.dat", GAME_ICONFILE, "22107c24dfb31b66ac503c28a6e20b19", -1}, - { "simon.gme", GAME_GMEFILE, "b1b18d0731b64c0738c5cc4a2ee792fc", -1}, - { "stripped.txt", GAME_STRFILE, "a27e87a9ba21212d769804b3df47bfb2", -1}, - { "tbllist", GAME_TBLFILE, "d198a80de2c59e4a0cd24b98814849e8", -1}, - { NULL, 0, NULL, 0} - }, - Common::RU_RUS, - Common::kPlatformWindows, - Common::ADGF_NO_FLAGS - }, - - GType_SIMON1, - GID_SIMON1TALKIE, - GF_TALKIE - }, - // Simon the Sorcerer 1 - German Windows CD { { @@ -2083,3 +2108,5 @@ static const AGOSGameDescription gameDescriptions[] = { }, { AD_TABLE_END_MARKER, 0, 0, 0 } }; + +} // End of namespace AGOS diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp index 4b548d64ba..5b5b42cbbb 100644 --- a/engines/agos/draw.cpp +++ b/engines/agos/draw.cpp @@ -31,6 +31,9 @@ namespace AGOS { byte *AGOSEngine::getFrontBuf() { + if (getGameType() != GType_PP && getGameType() != GType_FF) + _updateScreen = true; + _dxSurfacePitch = _screenWidth; return _frontBuf; } @@ -50,30 +53,91 @@ byte *AGOSEngine::getScaleBuf() { return _scaleBuf; } -void AGOSEngine::animateSprites() { +void AGOSEngine_Feeble::animateSpritesByY() { + VgaSprite *vsp; + VgaPointersEntry *vpe; + int16 spriteTable[180][2]; + + byte *src; + int height, slot, y; + uint i, numSprites = 0; + + vsp = _vgaSprites; + while (vsp->id) { + if (vsp->flags & kDFScaled) { + y = vsp->y; + } else if (vsp->flags & kDFMasked) { + vpe = &_vgaBufferPointers[vsp->zoneNum]; + src = vpe->vgaFile2 + vsp->image * 8; + height = READ_LE_UINT16(src + 4) & 0x7FFF; + y = vsp->y + height; + } else { + y = vsp->priority; + } + + spriteTable[numSprites][0] = y; + spriteTable[numSprites][1] = numSprites; + numSprites++; + vsp++; + } + + while (1) { + y = spriteTable[0][0]; + slot = spriteTable[0][1]; + + for (i = 0; i < numSprites; i++) { + if (y >= spriteTable[i][0]) { + y = spriteTable[i][0]; + slot = spriteTable[i][1]; + } + } + + if (y == 9999) + break; + + for (i = 0; i < numSprites; i++) { + if (slot == spriteTable[i][1]) { + spriteTable[i][0] = 9999; + break; + } + } + + vsp = &_vgaSprites[slot]; + + vsp->windowNum &= 0x7FFF; + + vpe = &_vgaBufferPointers[vsp->zoneNum]; + _curVgaFile1 = vpe->vgaFile1; + _curVgaFile2 = vpe->vgaFile2; + _curSfxFile = vpe->sfxFile; + _windowNum = vsp->windowNum; + _vgaCurSpriteId = vsp->id; + _vgaCurSpritePriority = vsp->priority; + + drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); + } + + _displayScreen = true; +} + +void AGOSEngine_Feeble::animateSprites() { VgaSprite *vsp; VgaPointersEntry *vpe; - const byte *vc_ptr_org = _vcPtr; - uint16 params[5]; // parameters to vc10 if (_paletteFlag == 2) _paletteFlag = 1; - if (getGameType() == GType_FF && _scrollCount) { + if (_scrollCount) { scrollEvent(); } - if (getGameType() == GType_SIMON2 && _scrollFlag) { - scrollScreen(); - } - if (getGameType() == GType_FF && getBitFlag(84)) { + if (getBitFlag(84)) { animateSpritesByY(); return; } vsp = _vgaSprites; - - while (vsp->id != 0) { + while (vsp->id) { vsp->windowNum &= 0x7FFF; vpe = &_vgaBufferPointers[vsp->zoneNum]; @@ -84,47 +148,66 @@ void AGOSEngine::animateSprites() { _vgaCurSpriteId = vsp->id; _vgaCurSpritePriority = vsp->priority; - params[0] = readUint16Wrapper(&vsp->image); - if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { - params[1] = readUint16Wrapper(&vsp->x); - params[2] = readUint16Wrapper(&vsp->y); - params[3] = READ_BE_UINT16(&vsp->flags); - } else { - params[1] = readUint16Wrapper(&vsp->palette); - params[2] = readUint16Wrapper(&vsp->x); - params[3] = readUint16Wrapper(&vsp->y); - - if (getGameType() == GType_SIMON1) { - params[4] = READ_BE_UINT16(&vsp->flags); - } else { - *(byte *)(¶ms[4]) = (byte)vsp->flags; - } - } - - _vcPtr = (const byte *)params; - vc10_draw(); - + drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); vsp++; } - if (_drawImagesDebug) - memset(_backBuf, 0, _screenWidth * _screenHeight); - - _updateScreen = true; - _vcPtr = vc_ptr_org; + _displayScreen = true; } -void AGOSEngine::animateSpritesDebug() { +void AGOSEngine::animateSprites() { VgaSprite *vsp; VgaPointersEntry *vpe; - const byte *vc_ptr_org = _vcPtr; - uint16 params[5]; // parameters to vc10_draw + + if (_copyScnFlag) { + _copyScnFlag--; + _vgaSpriteChanged++; + } + + if ((getGameType() == GType_ELVIRA1 && !_variableArray[293] || + getGameType() == GType_ELVIRA2 && !_variableArray[71]) && + _wallOn) { + + VC10_state state; + state.srcPtr = getBackGround() + 504; + state.height = 127; + state.width = 14; + state.y = 0; + state.x = 0; + state.palette = 0; + state.paletteMod = 0; + state.flags = kDFNonTrans; + + _windowNum = 4; + + _backFlag = 1; + drawImage(&state); + _backFlag = 0; + + _vgaSpriteChanged++; + } + + if (!_scrollFlag && !_vgaSpriteChanged) { + return; + } + + _vgaSpriteChanged = 0; if (_paletteFlag == 2) _paletteFlag = 1; + if (getGameType() == GType_SIMON2 && _scrollFlag) { + scrollScreen(); + } + + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + dirtyClips(); + } + + restoreBackGround(); + vsp = _vgaSprites; - while (vsp->id != 0) { + while (vsp->id) { vsp->windowNum &= 0x7FFF; vpe = &_vgaBufferPointers[vsp->zoneNum]; @@ -133,111 +216,182 @@ void AGOSEngine::animateSpritesDebug() { _curSfxFile = vpe->sfxFile; _windowNum = vsp->windowNum; _vgaCurSpriteId = vsp->id; + _vgaCurSpritePriority = vsp->priority; - if (vsp->image) - printf("id:%5d image:%3d base-color:%3d x:%3d y:%3d flags:%x\n", - vsp->id, vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); - params[0] = readUint16Wrapper(&vsp->image); - if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { - params[1] = readUint16Wrapper(&vsp->x); - params[2] = readUint16Wrapper(&vsp->y); - params[3] = READ_BE_UINT16(&vsp->flags); - } else { - params[1] = readUint16Wrapper(&vsp->palette); - params[2] = readUint16Wrapper(&vsp->x); - params[3] = readUint16Wrapper(&vsp->y); - - if (getGameType() == GType_SIMON1) { - params[4] = READ_BE_UINT16(&vsp->flags); - } else { - *(byte *)(¶ms[4]) = (byte)vsp->flags; + saveBackGround(vsp); + + drawImage_init(vsp->image, vsp->palette, vsp->x, vsp->y, vsp->flags); + vsp++; + } + + if (getGameType() == GType_ELVIRA1 && _variableArray[293]) { + debug(0, "Using special wall"); + + uint8 color, h, len; + byte *dst = _window4BackScn; + + color = (_variableArray[293] & 1) ? 13 : 15; + _wallOn = 2; + + h = 127; + while (h) { + len = 112; + while (len--) { + *dst++ = color; + dst++; } - } - _vcPtr = (const byte *)params; - vc10_draw(); + h--; + if (h == 0) + break; - vsp++; + len = 112; + while (len--) { + dst++; + *dst++ = color; + } + h--; + } + + _window4Flag = 1; + setMoveRect(0, 224, 0, 127); + } else if (getGameType() == GType_ELVIRA2 && _variableArray[71] & 2) { + debug(0, "Using special wall"); + + uint8 color, h, len; + byte *dst = _window4BackScn; + + color = 1; + _wallOn = 2; + + h = 43; + while (h) { + len = 56; + while (len--) { + *dst++ = color; + dst += 3; + } + + h--; + if (h == 0) + break; + + dst += 448; + + len = 56; + while (len--) { + dst += 2; + *dst++ = color; + dst++; + } + dst += 448; + h--; + } + + _window4Flag = 1; + setMoveRect(0, 224, 0, 127); } - _updateScreen = true; - _vcPtr = vc_ptr_org; + if (_window6Flag == 1) + _window6Flag++; + + if (_window4Flag == 1) + _window4Flag++; + + _displayScreen = true; } -void AGOSEngine::animateSpritesByY() { - VgaSprite *vsp; - VgaPointersEntry *vpe; - const byte *vc_ptr_org = _vcPtr; - uint16 params[5]; // parameters to vc10 - int16 spriteTable[180][2]; - - byte *src; - int height, slot, y; - uint i, numSprites = 0; +void AGOSEngine::dirtyClips() { + // TODO +} - vsp = _vgaSprites; - while (vsp->id != 0) { - if (vsp->flags & kDFScaled) { - y = vsp->y; - } else if (vsp->flags & kDFMasked) { - vpe = &_vgaBufferPointers[vsp->zoneNum]; - src = vpe->vgaFile2 + vsp->image * 8; - height = READ_LE_UINT16(src + 4) & 0x7FFF; - y = vsp->y + height; - } else { - y = vsp->priority; - } +void AGOSEngine::restoreBackGround() { + AnimTable *animTable; + uint images = 0; - spriteTable[numSprites][0] = y; - spriteTable[numSprites][1] = numSprites; - numSprites++; - vsp++; + animTable = _screenAnim1; + while (animTable->srcPtr) { + animTable++; + images++; } - while (1) { - y = spriteTable[0][0]; - slot = spriteTable[0][1]; + while (images--) { + animTable--; - for (i = 0; i < numSprites; i++) { - if (y >= spriteTable[i][0]) { - y = spriteTable[i][0]; - slot = spriteTable[i][1]; - } + if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && + !(animTable->window & 0x8000)) { + //continue; } - if (y == 9999) - break; + animTable->window &= 0x7FFF; + _windowNum = animTable->window; + + VC10_state state; + state.srcPtr = animTable->srcPtr; + state.height = state.draw_height = animTable->height; + state.width = state.draw_width = animTable->width; + state.y = animTable->y; + state.x = animTable->x; + state.palette = 0; + state.paletteMod = 0; + state.flags = kDFNonTrans; + + _backFlag = 1; + drawImage(&state); + + //if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2) { + animTable->srcPtr = 0; + //} + } + _backFlag = 0; - for (i = 0; i < numSprites; i++) { - if (slot == spriteTable[i][1]) { - spriteTable[i][0] = 9999; - break; + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + AnimTable *animTableTmp; + + animTable = animTableTmp = _screenAnim1; + while (animTable->srcPtr) { + if (!(animTable->window & 8000)) { + memcpy(animTableTmp, animTable, sizeof(AnimTable)); + animTableTmp++; } + animTable++; } + animTableTmp->srcPtr = 0; + } +} - vsp = &_vgaSprites[slot]; - vsp->windowNum &= 0x7FFF; +void AGOSEngine::saveBackGround(VgaSprite *vsp) { + if ((vsp->flags & kDFSkipStoreBG) || !vsp->image) + return; - vpe = &_vgaBufferPointers[vsp->zoneNum]; - _curVgaFile1 = vpe->vgaFile1; - _curVgaFile2 = vpe->vgaFile2; - _curSfxFile = vpe->sfxFile; - _windowNum = vsp->windowNum; - _vgaCurSpriteId = vsp->id; - _vgaCurSpritePriority = vsp->priority; + AnimTable *animTable = _screenAnim1; + + while (animTable->srcPtr) + animTable++; - params[0] = readUint16Wrapper(&vsp->image); - params[1] = readUint16Wrapper(&vsp->palette); - params[2] = readUint16Wrapper(&vsp->x); - params[3] = readUint16Wrapper(&vsp->y); - *(byte *)(¶ms[4]) = (byte)vsp->flags; + const byte *ptr = _curVgaFile2 + vsp->image * 8; + int16 x = vsp->x - _scrollX; + int16 y = vsp->y - _scrollY; - _vcPtr = (const byte *)params; - vc10_draw(); + if (_window3Flag == 1) { + animTable->srcPtr = (const byte *)_window4BackScn; + } else { + uint xoffs = (_videoWindows[vsp->windowNum * 4 + 0] * 2 + x) * 8; + uint yoffs = (_videoWindows[vsp->windowNum * 4 + 1] + y); + animTable->srcPtr = getBackGround() + xoffs + yoffs * _screenWidth; + } + + animTable->x = x; + animTable->y = y; + + animTable->width = READ_BE_UINT16(ptr + 6) / 16; + if (vsp->flags & 40) { + animTable->width++; } - _updateScreen = true; - _vcPtr = vc_ptr_org; + animTable->height = ptr[5]; + animTable->window = vsp->windowNum; + animTable->id = vsp->id; } void AGOSEngine::displayBoxStars() { @@ -247,21 +401,19 @@ void AGOSEngine::displayBoxStars() { byte *dst; uint b, color; - _lockWord |= 0x8000; + o_haltAnimation(); if (getGameType() == GType_SIMON2) color = 236; else color = 225; - uint limit = (getGameType() == GType_SIMON2) ? 200 : 134; + uint curHeight = (getGameType() == GType_SIMON2) ? _boxStarHeight : 134; for (int i = 0; i < 5; i++) { ha = _hitAreas; count = ARRAYSIZE(_hitAreas); - animateSprites(); - do { if (ha->id != 0 && ha->flags & kBFBoxInUse && !(ha->flags & kBFBoxDead)) { @@ -279,7 +431,7 @@ void AGOSEngine::displayBoxStars() { continue; } - if (ha->y >= limit || ((getGameType() == GType_SIMON2) && ha->y >= _boxStarHeight)) + if (ha->y >= curHeight) continue; y_ = (ha->height / 2) - 4 + ha->y; @@ -289,7 +441,7 @@ void AGOSEngine::displayBoxStars() { if (x_ >= 311) continue; - dst = getBackBuf(); + dst = getFrontBuf(); dst += (((_dxSurfacePitch / 4) * y_) * 4) + x_; @@ -328,21 +480,29 @@ void AGOSEngine::displayBoxStars() { } } while (ha++, --count); - updateScreen(); delay(100); - animateSprites(); - updateScreen(); + + setMoveRect(0, 0, 320, curHeight); + _window4Flag = 2; + + displayScreen(); delay(100); } - _lockWord &= ~0x8000; + o_restartAnimation(); } void AGOSEngine::scrollScreen() { - byte *dst = getFrontBuf(); + byte *dst; const byte *src; uint x, y; + if (getGameType() == GType_SIMON2) { + dst = getBackGround(); + } else { + dst = getFrontBuf(); + } + if (_scrollXMax == 0) { uint screenSize = 8 * _screenWidth; if (_scrollFlag < 0) { @@ -390,8 +550,16 @@ void AGOSEngine::scrollScreen() { _scrollX += _scrollFlag; vcWriteVar(251, _scrollX); - memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight); - memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth); + if (getGameType() == GType_SIMON2) { + memcpy(_window4BackScn, _backGroundBuf, _scrollHeight * _screenWidth); + } else { + memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight); + memcpy(_backGroundBuf, _backBuf, _scrollHeight * _screenWidth); + } + + setMoveRect(0, 0, 320, _scrollHeight); + + _window4Flag = 1; } _scrollFlag = 0; @@ -440,7 +608,21 @@ void AGOSEngine::fillBackGroundFromBack(uint lines) { memcpy(_backGroundBuf, _backBuf, lines * _screenWidth); } -void AGOSEngine::updateScreen() { +void AGOSEngine::setMoveRect(uint16 x, uint16 y, uint16 width, uint16 height) { + if (x < _moveXMin) + _moveXMin = x; + + if (y < _moveYMin) + _moveYMin = y; + + if (width > _moveXMax) + _moveXMax = width; + + if (height > _moveYMax) + _moveYMax = height; +} + +void AGOSEngine::displayScreen() { if (_fastFadeInFlag == 0 && _paletteFlag == 1) { _paletteFlag = 0; if (memcmp(_displayPalette, _currentPalette, 1024)) { @@ -449,21 +631,68 @@ void AGOSEngine::updateScreen() { } } - _system->copyRectToScreen(_backBuf, _screenWidth, 0, 0, _screenWidth, _screenHeight); - _system->updateScreen(); + if (getGameType() == GType_PP || getGameType() == GType_FF) { + _system->copyRectToScreen(getBackBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); - if (getGameId() != GID_DIMP) - memcpy(_backBuf, _frontBuf, _screenWidth * _screenHeight); + if (getGameId() != GID_DIMP) + memcpy(getBackBuf(), getFrontBuf(), _screenWidth * _screenHeight); + } else { + if (_window4Flag == 2) { + _window4Flag = 0; + + uint16 srcWidth, width, height; + byte *dst = getFrontBuf(); + + const byte *src = _window4BackScn; + if (_window3Flag == 1) { + src = getBackGround(); + } + + dst += (_moveYMin + _videoWindows[17]) * _screenWidth; + dst += (_videoWindows[16] * 16) + _moveXMin; + + src += (_videoWindows[18] * 16 * _moveYMin); + src += _moveXMin; + + srcWidth = _videoWindows[18] * 16; + + width = _moveXMax - _moveXMin; + height = _moveYMax - _moveYMin; + + for (; height > 0; height--) { + memcpy(dst, src, width); + dst += _screenWidth; + src += srcWidth; + } + + _moveXMin = 0xFFFF; + _moveYMin = 0xFFFF; + _moveXMax = 0; + _moveYMax = 0; + } + + if (_window6Flag == 2) { + _window6Flag = 0; + + byte *src = _window6BackScn; + byte *dst = getFrontBuf() + 16320; + for (int i = 0; i < 80; i++) { + memcpy(dst, src, 48); + dst += _screenWidth; + src += 48; + } + } + + _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); + } if (getGameType() == GType_FF && _scrollFlag) { scrollScreen(); } if (_fastFadeInFlag) { - if (getGameType() == GType_SIMON1 && _usePaletteDelay) { - delay(100); - _usePaletteDelay = false; - } fastFadeIn(); } } diff --git a/engines/agos/event.cpp b/engines/agos/event.cpp index 93ab997e64..9fc8cb72e5 100644 --- a/engines/agos/event.cpp +++ b/engines/agos/event.cpp @@ -42,6 +42,10 @@ void AGOSEngine::addTimeEvent(uint timeout, uint subroutine_id) { time(&cur_time); + if (getGameId() == GID_DIMP) { + timeout /= 2; + } + te->time = cur_time + timeout - _gameStoppedClock; if (getGameType() == GType_FF && _clockStopped) te->time -= ((uint32)time(NULL) - _clockStopped); @@ -123,6 +127,7 @@ void AGOSEngine::killAllTimers() { next = cur->next; delTimeEvent(cur); } + _clickOnly = 0; } bool AGOSEngine::kickoffTimeEvents() { @@ -164,32 +169,34 @@ bool AGOSEngine::isVgaQueueEmpty() { } void AGOSEngine::haltAnimation() { - VgaTimerEntry *vte = _vgaTimerList; + if (_lockWord & 0x10) + return; _lockWord |= 0x10; - while (vte->delay) { - vte->delay += 10; + if (_displayScreen) { + displayScreen(); + _displayScreen = false; } } void AGOSEngine::restartAnimation() { + if (!(_lockWord & 0x10)) + return; + + _window4Flag = 2; + + setMoveRect(0, 0, 224, 127); + displayScreen(); + _lockWord &= ~0x10; + + // Check picture queue } -void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum) { +void AGOSEngine::addVgaEvent(uint16 num, uint8 type, const byte *code_ptr, uint16 cur_sprite, uint16 curZoneNum) { VgaTimerEntry *vte; - // When Simon talks to the Golum about stew in French version of - // Simon the Sorcerer 1 the code_ptr is at wrong location for - // sprite 200. This was a bug in the original game, which - // caused several glitches in this scene. - // We work around the problem by correcting the code_ptr for sprite - // 200 in this scene, if it is wrong. - if (getGameType() == GType_SIMON1 && _language == Common::FR_FRA && - (code_ptr - _vgaBufferPointers[curZoneNum].vgaFile1 == 4) && (cur_sprite == 200) && (curZoneNum == 2)) - code_ptr += 0x66; - _lockWord |= 1; for (vte = _vgaTimerList; vte->delay; vte++) { @@ -199,6 +206,7 @@ void AGOSEngine::addVgaEvent(uint16 num, const byte *code_ptr, uint16 cur_sprite vte->script_pointer = code_ptr; vte->sprite_id = cur_sprite; vte->cur_vga_file = curZoneNum; + vte->type = type; _lockWord &= ~1; } @@ -230,15 +238,35 @@ void AGOSEngine::processVgaEvents() { uint16 cur_sprite = vte->sprite_id; const byte *script_ptr = vte->script_pointer; - _nextVgaTimerToProcess = vte + 1; - deleteVgaEvent(vte); - - if (getGameType() == GType_SIMON2 && script_ptr == NULL) { - scrollEvent(); - } else { + switch (vte->type) { + case ANIMATE_INT: + vte->delay = (getGameType() == GType_SIMON2) ? 5 : _frameCount; + animateSprites(); + vte++; + break; + case ANIMATE_EVENT: + _nextVgaTimerToProcess = vte + 1; + deleteVgaEvent(vte); animateEvent(script_ptr, curZoneNum, cur_sprite); + vte = _nextVgaTimerToProcess; + break; + case SCROLL_EVENT: + _nextVgaTimerToProcess = vte + 1; + deleteVgaEvent(vte); + scrollEvent(); + vte = _nextVgaTimerToProcess; + break; + case IMAGE_EVENT2: + imageEvent2(vte, curZoneNum); + vte = _nextVgaTimerToProcess; + break; + case IMAGE_EVENT3: + imageEvent3(vte, curZoneNum); + vte = _nextVgaTimerToProcess; + break; + default: + error("processVgaEvents: Unknown event type %d", vte->type); } - vte = _nextVgaTimerToProcess; } else { vte++; } @@ -294,7 +322,96 @@ void AGOSEngine::scrollEvent() { } } - addVgaEvent(6, NULL, 0, 0); /* scroll event */ + addVgaEvent(6, SCROLL_EVENT, NULL, 0, 0); + } +} + +static const byte _image1[32] = { + 0x3A, 0x37, 0x3B, 0x37, + 0x3A, 0x3E, 0x3F, 0x3E, + 0x37, 0x3F, 0x31, 0x3F, + 0x37, 0x3F, 0x31, 0x3F, + 0x3A, 0x3E, 0x3F, 0x3E, + 0x3A, 0x37, 0x3B, 0x37, +}; + +static const byte _image2[32] = { + 0x3A, 0x3A, 0x3B, 0x3A, + 0x3A, 0x37, 0x3E, 0x37, + 0x3A, 0x37, 0x3E, 0x37, + 0x3A, 0x37, 0x3E, 0x37, + 0x3A, 0x37, 0x3E, 0x37, + 0x3A, 0x3A, 0x3B, 0x3A, +}; + +static const byte _image3[32] = { + 0x3A, 0x32, 0x3B, 0x32, + 0x3A, 0x39, 0x3F, 0x39, + 0x32, 0x3F, 0x31, 0x3F, + 0x32, 0x3F, 0x31, 0x3F, + 0x3A, 0x39, 0x3F, 0x39, + 0x3A, 0x32, 0x3B, 0x32, +}; + +static const byte _image4[32] = { + 0x3A, 0x3A, 0x3B, 0x3A, + 0x3A, 0x32, 0x39, 0x32, + 0x3A, 0x32, 0x38, 0x32, + 0x3A, 0x32, 0x38, 0x32, + 0x3A, 0x32, 0x39, 0x32, + 0x3A, 0x3A, 0x3B, 0x3A, +}; + +void AGOSEngine::drawStuff(const byte *src, uint offs) { + byte *dst = getFrontBuf() + offs; + + for (uint y = 0; y < 6; y++) { + memcpy(dst, src, 4); + src += 4; + dst += _screenWidth; + } +} + +void AGOSEngine::imageEvent2(VgaTimerEntry * vte, uint dx) { + // Draws damage indicator gauge + _nextVgaTimerToProcess = vte + 1; + + if (!_opcode177Var1) { + drawStuff(_image1, 43204 + _opcode177Var2 * 4); + _opcode177Var2++; + if (_opcode177Var2 == dx) { + _opcode177Var1 = 1; + vte->delay = 16 - dx; + } else { + vte->delay = 1; + } + } else if (_opcode177Var2) { + _opcode177Var2--; + drawStuff(_image2, 43204 + _opcode177Var2 * 4); + vte->delay = 3; + } else { + deleteVgaEvent(vte); + } +} + +void AGOSEngine::imageEvent3(VgaTimerEntry * vte, uint dx) { + _nextVgaTimerToProcess = vte + 1; + + if (!_opcode178Var1) { + drawStuff(_image3, 43475 + _opcode178Var2 * 4); + _opcode178Var2++; + if (_opcode178Var2 >= 10 || _opcode178Var2 == dx) { + _opcode178Var1 = 1; + vte->delay = 16 - dx; + } else { + vte->delay = 1; + } + } else if (_opcode178Var2) { + _opcode178Var2--; + drawStuff(_image4, 43475 + _opcode178Var2 * 4); + vte->delay = 3; + } else { + deleteVgaEvent(vte); } } @@ -344,7 +461,7 @@ void AGOSEngine::delay(uint amount) { if (_saveLoadSlot == 0) _saveLoadSlot = 10; - sprintf(_saveLoadName, "Quicksave %d", _saveLoadSlot); + sprintf(_saveLoadName, "Quick %d", _saveLoadSlot); _saveLoadType = (event.kbd.flags == Common::KBD_ALT) ? 1 : 2; // We should only allow a load or save when it was possible in original @@ -423,15 +540,30 @@ void AGOSEngine::delay(uint amount) { } void AGOSEngine::timer_callback() { - if (_timer5 != 0) { + // FIXME: _timer5 is never set + if (_timer5) { _syncFlag2 = true; _timer5--; } else { - timer_proc1(); + if (getGameId() == GID_DIMP) { + _thisTickCount = _system->getMillis(); + if (_thisTickCount < _lastTickCount) + _lastTickCount = 0; + + if ((_thisTickCount - _lastTickCount) <= 35) + return; + + _lastTickCount = _thisTickCount; + + timer_proc1(); + dimp_idle(); + } else { + timer_proc1(); + } } } -void AGOSEngine::timer_proc1() { +void AGOSEngine_Feeble::timer_proc1() { _timer4++; if (_lockWord & 0x80E9 || _lockWord & 2) @@ -442,65 +574,32 @@ void AGOSEngine::timer_proc1() { _lockWord |= 2; if (!(_lockWord & 0x10)) { - if (getGameType() == GType_PP) { - _syncFlag2 ^= 1; - if (!_syncFlag2) { - processVgaEvents(); - } else { - if (_scrollCount == 0) { - _lockWord &= ~2; - return; - } - } - } else if (getGameType() == GType_FF) { - _syncFlag2 ^= 1; - if (!_syncFlag2) { - processVgaEvents(); - } else { - // Double speed on Oracle - if (getBitFlag(99)) { - processVgaEvents(); - } else if (_scrollCount == 0) { - _lockWord &= ~2; - return; - } - } - } else { - processVgaEvents(); + _syncFlag2 ^= 1; + if (!_syncFlag2) { processVgaEvents(); - _syncFlag2 ^= 1; - _cepeFlag ^= 1; - if (!_cepeFlag) + } else { + // Double speed on Oracle + if (getGameType() == GType_FF && getBitFlag(99)) { processVgaEvents(); - - if (_mouseHideCount != 0 && _syncFlag2) { + } else if (_scrollCount == 0) { _lockWord &= ~2; return; } } - } - if (getGameType() == GType_FF) - _moviePlay->nextFrame(); - - animateSprites(); - if (_drawImagesDebug) - animateSpritesDebug(); + if (getGameType() == GType_FF) { + _moviePlay->nextFrame(); + } - if (_copyPartialMode == 1) { - fillBackFromFront(80, 46, 208 - 80, 94 - 46); - } + animateSprites(); + } if (_copyPartialMode == 2) { - if (getGameType() == GType_FF || getGameType() == GType_PP) { - fillFrontFromBack(0, 0, _screenWidth, _screenHeight); - } else { - fillFrontFromBack(176, 61, _screenWidth - 176, 134 - 61); - } + fillFrontFromBack(0, 0, _screenWidth, _screenHeight); _copyPartialMode = 0; } - if (_updateScreen) { + if (_displayScreen) { if (getGameType() == GType_FF) { if (!getBitFlag(78)) { oracleLogo(); @@ -510,11 +609,128 @@ void AGOSEngine::timer_proc1() { } } handleMouseMoved(); - updateScreen(); + displayScreen(); + _displayScreen = false; + } + + _lockWord &= ~2; +} + +void AGOSEngine::timer_proc1() { + _timer4++; + + if (_lockWord & 0x80E9 || _lockWord & 2) + return; + + _syncCount++; + + _lockWord |= 2; + + handleMouseMoved(); + + if (!(_lockWord & 0x10)) { + processVgaEvents(); + processVgaEvents(); + _cepeFlag ^= 1; + if (!_cepeFlag) + processVgaEvents(); + } + + if (_updateScreen) { + _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); + _updateScreen = false; } + if (_displayScreen) { + displayScreen(); + _displayScreen = false; + } + _lockWord &= ~2; } +void AGOSEngine::dimp_idle() { + int z, n; + + _iconToggleCount++; + if (_iconToggleCount == 30) { + if ((_variableArray[110] < 3) || (_variableArray[111] < 3) || (_variableArray[112] < 3)) { + _voiceCount++; + if (_voiceCount == 50) { + if (!getBitFlag(14) && !getBitFlag(11) && !getBitFlag(13)) { + loadSoundFile("Whistle.WAV"); + z = 0; + while (z == 0) { + n = _rnd.getRandomNumber(2); + switch (n) { + case(0): + if (_variableArray[110] > 2) + break; + n = _rnd.getRandomNumber(6); + switch(n) { + case(0): loadSoundFile("And01.wav");break; + case(1): loadSoundFile("And02.wav");break; + case(2): loadSoundFile("And03.wav");break; + case(3): loadSoundFile("And04.wav");break; + case(4): loadSoundFile("And05.wav");break; + case(5): loadSoundFile("And06.wav");break; + case(6): loadSoundFile("And07.wav");break; + } + z = 1; + break; + case(1): + if (_variableArray[111] > 2) + break; + n = _rnd.getRandomNumber(6); + switch(n) { + case(0): loadSoundFile("And08.wav");break; + case(1): loadSoundFile("And09.wav");break; + case(2): loadSoundFile("And0a.wav");break; + case(3): loadSoundFile("And0b.wav");break; + case(4): loadSoundFile("And0c.wav");break; + case(5): loadSoundFile("And0d.wav");break; + case(6): loadSoundFile("And0e.wav");break; + } + z = 1; + break; + case(2): + if (_variableArray[112] > 2) + break; + n = _rnd.getRandomNumber(4); + switch(n) { + case(0): loadSoundFile("And0f.wav");break; + case(1): loadSoundFile("And0g.wav");break; + case(2): loadSoundFile("And0h.wav");break; + case(3): loadSoundFile("And0i.wav");break; + case(4): loadSoundFile("And0j.wav");break; + } + z = 1; + break; + } + } + } + _voiceCount = 0; + } + } else { + _voiceCount = 48; + } + _iconToggleCount = 0; + } + + if (_variableArray[121] == 0) { + _variableArray[121]++; + _startSecondCount = _lastTickCount; + } + if (((_lastTickCount - _startSecondCount) / 1000) != _tSecondCount) { + if (_startSecondCount != 0) { + uint32 x = (_variableArray[123] * 65536) + _variableArray[122] + ((_lastTickCount - _startSecondCount) / 1000) - _tSecondCount; + _variableArray[122] = (uint16)(x % 65536); + _variableArray[123] = (uint16)(x / 65536); + _tSecondCount = (_lastTickCount - _startSecondCount) / 1000; + } + } +} + } // End of namespace AGOS diff --git a/engines/agos/gfx.cpp b/engines/agos/gfx.cpp index 211005385e..68c405ba8c 100644 --- a/engines/agos/gfx.cpp +++ b/engines/agos/gfx.cpp @@ -31,7 +31,7 @@ namespace AGOS { byte *vc10_depackColumn(VC10_state * vs) { int8 a = vs->depack_cont; - const byte *src = vs->depack_src; + const byte *src = vs->srcPtr; byte *dst = vs->depack_dest; uint16 dh = vs->dh; byte color; @@ -66,7 +66,7 @@ byte *vc10_depackColumn(VC10_state * vs) { } get_out:; - vs->depack_src = src; + vs->srcPtr = src; vs->depack_cont = a; return vs->depack_dest + vs->y_skip; } @@ -166,7 +166,7 @@ void AGOSEngine::decodeRow(byte *dst, const byte *src, int width) { } } -bool AGOSEngine::drawImages_clip(VC10_state *state) { +bool AGOSEngine::drawImage_clip(VC10_state *state) { const uint16 *vlut; uint maxWidth, maxHeight; int cur; @@ -215,16 +215,78 @@ bool AGOSEngine::drawImages_clip(VC10_state *state) { } while (--cur); } - assert(state->draw_width != 0 && state->draw_height != 0); - if (getGameType() != GType_FF && getGameType() != GType_PP) { state->draw_width *= 4; } - return 1; + return (state->draw_width != 0 && state->draw_height != 0); +} + +void AGOSEngine_Feeble::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) { + Common::Rect srcRect, dstRect; + float factor, xscale; + + srcRect.left = 0; + srcRect.top = 0; + srcRect.right = w; + srcRect.bottom = h; + + if (scrollY > _baseY) + factor = 1 + ((scrollY - _baseY) * _scale); + else + factor = 1 - ((_baseY - scrollY) * _scale); + + xscale = ((w * factor) / 2); + + dstRect.left = (int16)(x - xscale); + if (dstRect.left > _screenWidth - 1) + return; + dstRect.top = (int16)(y - (h * factor)); + if (dstRect.top > _screenHeight - 1) + return; + + dstRect.right = (int16)(x + xscale); + dstRect.bottom = y; + + _feebleRect = dstRect; + + _variableArray[20] = _feebleRect.top; + _variableArray[21] = _feebleRect.left; + _variableArray[22] = _feebleRect.bottom; + _variableArray[23] = _feebleRect.right; + + debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom); + + // Unlike normal rectangles in ScummVM, it seems that in the case of + // the destination rectangle the bottom and right coordinates are + // considered to be inside the rectangle. For the source rectangle, + // I believe that they are not. + + int scaledW = dstRect.width() + 1; + int scaledH = dstRect.height() + 1; + + byte *src = getScaleBuf(); + byte *dst = getBackBuf(); + + dst += _dxSurfacePitch * dstRect.top + dstRect.left; + + for (int dstY = 0; dstY < scaledH; dstY++) { + if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) { + int srcY = (dstY * h) / scaledH; + byte *srcPtr = src + _dxSurfacePitch * srcY; + byte *dstPtr = dst + _dxSurfacePitch * dstY; + for (int dstX = 0; dstX < scaledW; dstX++) { + if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) { + int srcX = (dstX * w) / scaledW; + if (srcPtr[srcX]) + dstPtr[dstX] = srcPtr[srcX]; + } + } + } + } } -void AGOSEngine::drawImages_Feeble(VC10_state *state) { +void AGOSEngine_Feeble::drawImage(VC10_state *state) { if (state->flags & kDFCompressed) { if (state->flags & kDFScaled) { state->surf_addr = getScaleBuf(); @@ -293,7 +355,7 @@ void AGOSEngine::drawImages_Feeble(VC10_state *state) { scaleClip(_scaleHeight, _scaleWidth, _scaleY, _scaleX, _scaleY + _scrollY); } } else { - if (drawImages_clip(state) == 0) + if (!drawImage_clip(state)) return; state->surf_addr += state->x + state->y * state->surf_pitch; @@ -359,7 +421,7 @@ void AGOSEngine::drawImages_Feeble(VC10_state *state) { } } } else { - if (drawImages_clip(state) == 0) + if (!drawImage_clip(state)) return; state->surf_addr += state->x + state->y * state->surf_pitch; @@ -368,7 +430,7 @@ void AGOSEngine::drawImages_Feeble(VC10_state *state) { byte *dst; uint count; - src = state->depack_src + state->width * state->y_skip; + src = state->srcPtr + state->width * state->y_skip; dst = state->surf_addr; do { for (count = 0; count != state->draw_width; count++) { @@ -387,27 +449,36 @@ void AGOSEngine::drawImages_Feeble(VC10_state *state) { } } -void AGOSEngine::drawImages_Simon(VC10_state *state) { - const uint16 *vlut = &_videoWindows[_windowNum * 4]; - - if (drawImages_clip(state) == 0) - return; - - uint xoffs, yoffs; - if (getGameType() == GType_SIMON1 && (_subroutine == 2923 || _subroutine == 2926)) { - // Allow one section of Simon the Sorcerer 1 introduction to be displayed - // in lower half of screen - xoffs = state->x * 8; - yoffs = state->y; - } else { - xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; - yoffs = (vlut[1] - _videoWindows[17] + state->y); +void AGOSEngine_Simon1::drawMaskedImage(VC10_state *state) { + if (getGameType() == GType_SIMON1 && (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10)) { + state->surf2_addr += _videoWindows[17] * 320; } - state->surf2_addr += xoffs + yoffs * state->surf_pitch; - state->surf_addr += xoffs + yoffs * state->surf2_pitch; + if (getFeatures() & GF_32COLOR) { + const byte *mask = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8); + byte *src = state->surf2_addr; + byte *dst = state->surf_addr; - if (state->flags & kDFMasked) { + state->draw_width *= 2; + + uint h = state->draw_height; + do { + for (uint i = 0; i != state->draw_width; i++) { + if (getGameType() == GType_SIMON1 && getBitFlag(88)) { + /* transparency */ + if (mask[i] && (dst[i] & 16)) + dst[i] = src[i]; + } else { + /* no transparency */ + if (mask[i]) + dst[i] = src[i]; + } + } + dst += state->surf_pitch; + src += state->surf2_pitch; + mask += state->width * 16; + } while (--h); + } else if (state->flags & kDFCompressed) { byte *mask, *src, *dst; byte h; uint w; @@ -426,210 +497,122 @@ void AGOSEngine::drawImages_Simon(VC10_state *state) { h = state->draw_height; do { - if ((getGameType() == GType_SIMON1) && getBitFlag(88)) { + if (getGameType() == GType_SIMON1 && getBitFlag(88)) { /* transparency */ - if (mask[0] & 0xF0) { - if ((dst[0] & 0x0F0) == 0x20) - dst[0] = src[0]; - } - if (mask[0] & 0x0F) { - if ((dst[1] & 0x0F0) == 0x20) - dst[1] = src[1]; - } - } else { + if ((mask[0] & 0xF0) && (dst[0] & 0x0F0) == 0x20) + dst[0] = src[0]; + if ((mask[0] & 0x0F) && (dst[1] & 0x0F0) == 0x20) + dst[1] = src[1]; + } else { /* no transparency */ - if (mask[0] & 0xF0) - dst[0] = src[0]; - if (mask[0] & 0x0F) - dst[1] = src[1]; + if (mask[0] & 0xF0) + dst[0] = src[0]; + if (mask[0] & 0x0F) + dst[1] = src[1]; } mask++; dst += state->surf_pitch; src += state->surf2_pitch; } while (--h); } while (++w != state->draw_width); - } else if ((((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0)) { - const byte *src; - byte *dst; - uint h, i; - - if (state->flags & kDFCompressed) { - byte *dstPtr = state->surf_addr; - src = state->depack_src; - /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE - * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh - */ - - do { - uint count = state->draw_width / 4; - - dst = dstPtr; - do { - uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]); - byte color; - - color = (byte)((bits >> (32 - 5)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[0] = color; - color = (byte)((bits >> (32 - 10)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[1] = color; - color = (byte)((bits >> (32 - 15)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[2] = color; - color = (byte)((bits >> (32 - 20)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[3] = color; - color = (byte)((bits >> (32 - 25)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[4] = color; - color = (byte)((bits >> (32 - 30)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[5] = color; - - bits = (bits << 8) | src[4]; - - color = (byte)((bits >> (40 - 35)) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[6] = color; - color = (byte)((bits) & 31); - if ((state->flags & kDFNonTrans) || color) - dst[7] = color; - - dst += 8; - src += 5; - } while (--count); - dstPtr += _screenWidth; - } while (--state->draw_height); - } else { - src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8); - dst = state->surf_addr; - - state->draw_width *= 2; - - h = state->draw_height; - do { - for (i = 0; i != state->draw_width; i++) - if ((state->flags & kDFNonTrans) || src[i]) - dst[i] = src[i]; - dst += _screenWidth; - src += state->width * 16; - } while (--h); - } } else { - if (getGameType() == GType_SIMON2 && state->flags & kDFUseFrontBuf && getBitFlag(171)) { - state->surf_addr = state->surf2_addr; - state->surf_pitch = state->surf2_pitch; - } - - if (state->flags & kDFCompressed) { - uint w, h; - byte *src, *dst, *dstPtr; - - state->x_skip *= 4; /* reached */ - - state->dl = state->width; - state->dh = state->height; - - vc10_skip_cols(state); - - dstPtr = state->surf_addr; - if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */ - dstPtr += vcReadVar(252); - } - w = 0; - do { - byte color; - - src = vc10_depackColumn(state); - dst = dstPtr; + const byte *src, *mask; + byte *dst; + uint count; - h = 0; - do { - color = (*src / 16); - if ((state->flags & kDFNonTrans) || color != 0) - dst[0] = color | state->palette; - color = (*src & 15); - if ((state->flags & kDFNonTrans) || color != 0) - dst[1] = color | state->palette; - dst += _screenWidth; - src++; - } while (++h != state->draw_height); - dstPtr += 2; - } while (++w != state->draw_width); - } else { - const byte *src; - byte *dst; - uint count; + mask = state->srcPtr + (state->width * state->y_skip) * 8; + src = state->surf2_addr; + dst = state->surf_addr; - src = state->depack_src + (state->width * state->y_skip) * 8; - dst = state->surf_addr; - state->x_skip *= 4; + state->x_skip *= 4; - do { - for (count = 0; count != state->draw_width; count++) { - byte color; - color = (src[count + state->x_skip] / 16); - if ((state->flags & kDFNonTrans) || color) - dst[count * 2] = color | state->palette; - color = (src[count + state->x_skip] & 15); - if ((state->flags & kDFNonTrans) || color) - dst[count * 2 + 1] = color | state->palette; + do { + for (count = 0; count != state->draw_width; count++) { + if (getGameType() == GType_SIMON1 && getBitFlag(88)) { + /* transparency */ + if (mask[count + state->x_skip] & 0xF0) + if ((dst[count * 2] & 0xF0) == 0x20) + dst[count * 2] = src[count * 2]; + if (mask[count + state->x_skip] & 0x0F) + if ((dst[count * 2 + 1] & 0x0F) == 0x20) + dst[count * 2 + 1] = src[count * 2 + 1]; + } else { + /* no transparency */ + if (mask[count + state->x_skip] & 0xF0) + dst[count * 2] = src[count * 2]; + if (mask[count + state->x_skip] & 0x0F) + dst[count * 2 + 1] = src[count * 2 + 1]; } - dst += _screenWidth; - src += state->width * 8; - } while (--state->draw_height); - } + } + src += _screenWidth; + dst += _screenWidth; + mask += state->width * 8; + } while (--state->draw_height); } } -void AGOSEngine::drawImages_Amiga(VC10_state *state) { - uint8 *dst; +void AGOSEngine_Simon1::draw32ColorImage(VC10_state *state) { const byte *src; - const uint16 *vlut = &_videoWindows[_windowNum * 4]; + byte *dst; + uint h, i; - if (drawImages_clip(state) == 0) - return; + if (state->flags & kDFCompressed) { + byte *dstPtr = state->surf_addr; + src = state->srcPtr; + /* AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE + * aaaaabbb bbcccccd ddddeeee efffffgg ggghhhhh + */ - uint xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; - uint yoffs = (vlut[1] - _videoWindows[17] + state->y); + do { + uint count = state->draw_width / 4; - state->surf2_addr += xoffs + yoffs * state->surf_pitch; - state->surf_addr += xoffs + yoffs * state->surf2_pitch; + dst = dstPtr; + do { + uint32 bits = (src[0] << 24) | (src[1] << 16) | (src[2] << 8) | (src[3]); + byte color; - if (state->flags & kDFMasked) { - const byte *mask = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8); - src = state->surf2_addr; - dst = state->surf_addr; + color = (byte)((bits >> (32 - 5)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[0] = color; + color = (byte)((bits >> (32 - 10)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[1] = color; + color = (byte)((bits >> (32 - 15)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[2] = color; + color = (byte)((bits >> (32 - 20)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[3] = color; + color = (byte)((bits >> (32 - 25)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[4] = color; + color = (byte)((bits >> (32 - 30)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[5] = color; - state->draw_width *= 2; + bits = (bits << 8) | src[4]; - uint h = state->draw_height; - do { - for (uint i = 0; i != state->draw_width; i++) { - if ((getGameType() == GType_SIMON1) && getBitFlag(88)) { - /* transparency */ - if (mask[i] & 1 && (dst[i] & 1) == 0x20) - dst[i] = src[i]; - } else { - /* no transparency */ - if (mask[i] & 1) - dst[i] = src[i]; - } - } - dst += state->surf_pitch; - src += state->surf2_pitch; - mask += state->width * 16; - } while (--h); + color = (byte)((bits >> (40 - 35)) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[6] = color; + color = (byte)((bits) & 31); + if ((state->flags & kDFNonTrans) || color) + dst[7] = color; + + dst += 8; + src += 5; + } while (--count); + dstPtr += _screenWidth; + } while (--state->draw_height); } else { - src = state->depack_src + (state->width * state->y_skip * 16) + (state->x_skip * 8); + src = state->srcPtr + (state->width * state->y_skip * 16) + (state->x_skip * 8); dst = state->surf_addr; state->draw_width *= 2; - uint h = state->draw_height; + h = state->draw_height; do { - for (uint i = 0; i != state->draw_width; i++) + for (i = 0; i != state->draw_width; i++) if ((state->flags & kDFNonTrans) || src[i]) dst[i] = src[i]; dst += _screenWidth; @@ -638,53 +621,129 @@ void AGOSEngine::drawImages_Amiga(VC10_state *state) { } } -void AGOSEngine::drawImages(VC10_state *state) { +void AGOSEngine_Simon1::drawImage(VC10_state *state) { const uint16 *vlut = &_videoWindows[_windowNum * 4]; - if (drawImages_clip(state) == 0) + if (!drawImage_clip(state)) return; - uint xoffs, yoffs; - if (getGameType() == GType_ELVIRA1) { - //if (_windowNum != 2 && _windowNum != 3 && _windowNum != 6) { - // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; - // yoffs = (vlut[1] - _videoWindows[17] + state->y); - //} else { - xoffs = (vlut[0] * 2 + state->x) * 8; - yoffs = vlut[1] + state->y; - //} - } else if (getGameType() == GType_ELVIRA2) { - //if (_windowNum == 4 || _windowNum >= 10) { - // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; - // yoffs = (vlut[1] - _videoWindows[17] + state->y); - //} else { + if (getFeatures() & GF_32COLOR) + state->palette = 0xC0; + + uint16 xoffs = 0, yoffs = 0; + if (getGameType() == GType_SIMON2) { + state->surf2_addr = getBackGround(); + state->surf2_pitch = _screenWidth; + + state->surf_addr = _window4BackScn; + state->surf_pitch = _screenWidth; + + xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; + yoffs = (vlut[1] - _videoWindows[17] + state->y); + + uint xmax = (xoffs + state->draw_width * 2); + uint ymax = (yoffs + state->draw_height); + setMoveRect(xoffs, yoffs, xmax, ymax); + + _window4Flag = 1; + } else if (getGameType() == GType_SIMON1 && (getFeatures() & GF_DEMO)) { + // The DOS Floppy demo was based off Waxworks engine + if (_windowNum == 4 || (_windowNum >= 10 && _windowNum <= 27)) { + state->surf_addr = _window4BackScn; + state->surf_pitch = _videoWindows[18] * 16; + + xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; + yoffs = (vlut[1] - _videoWindows[17] + state->y); + + uint xmax = (xoffs + state->draw_width * 2); + uint ymax = (yoffs + state->draw_height); + setMoveRect(xoffs, yoffs, xmax, ymax); + + _window4Flag = 1; + } else { + state->surf_addr = getFrontBuf(); + state->surf_pitch = _screenWidth; + xoffs = (vlut[0] * 2 + state->x) * 8; yoffs = vlut[1] + state->y; - //} - } else if (getGameType() == GType_WW) { - //if (_windowNum == 4 || (_windowNum >= 10 && _windowNum < 28)) { - // xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; - // yoffs = (vlut[1] - _videoWindows[17] + state->y); - //} else { + } + } else if (getGameType() == GType_SIMON1) { + if (_windowNum == 3 || _windowNum == 4 || _windowNum >= 10) { + if (_window3Flag == 1) { + state->surf2_addr = getBackGround(); + state->surf2_pitch = _screenWidth; + + state->surf_addr = getBackGround(); + state->surf_pitch = _screenWidth; + } else { + state->surf2_addr = getBackGround(); + state->surf2_pitch = _screenWidth; + + state->surf_addr = _window4BackScn; + state->surf_pitch = _screenWidth; + } + + xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; + yoffs = (vlut[1] - _videoWindows[17] + state->y); + + uint xmax = (xoffs + state->draw_width * 2); + uint ymax = (yoffs + state->draw_height); + setMoveRect(xoffs, yoffs, xmax, ymax); + + _window4Flag = 1; + } else { + state->surf2_addr = getBackGround(); + state->surf2_pitch = _screenWidth; + + state->surf_addr = getFrontBuf(); + state->surf_pitch = _screenWidth; + xoffs = (vlut[0] * 2 + state->x) * 8; yoffs = vlut[1] + state->y; - //} + } + } + + state->surf_addr += xoffs + yoffs * state->surf_pitch; + state->surf2_addr += xoffs + yoffs * state->surf2_pitch; + + if (_backFlag == 1) { + drawBackGroundImage(state); + } else if (state->flags & kDFMasked) { + drawMaskedImage(state); + } else if (((_lockWord & 0x20) && state->palette == 0) || state->palette == 0xC0) { + draw32ColorImage(state); } else { - xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; - yoffs = (vlut[1] - _videoWindows[17] + state->y); + drawVertImage(state); } +} - state->surf2_addr += xoffs + yoffs * state->surf_pitch; - state->surf_addr += xoffs + yoffs * state->surf2_pitch; +void AGOSEngine::drawBackGroundImage(VC10_state *state) { + const byte *src; + byte *dst; + uint h, i; - if (state->flags & kDFUseFrontBuf) { - state->surf_addr = state->surf2_addr; - state->surf_pitch = state->surf2_pitch; + state->width = _screenWidth; + if (_window3Flag == 1) { + state->width = 0; + state->x_skip = 0; + state->y_skip = 0; } - if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) - state->palette = state->surf_addr[0] & 0xF0; + src = state->srcPtr + (state->width * state->y_skip) + (state->x_skip * 8); + dst = state->surf_addr; + + state->draw_width *= 2; + + h = state->draw_height; + do { + for (i = 0; i != state->draw_width; i++) + dst[i] = src[i] + state->paletteMod; + dst += state->surf_pitch; + src += state->width; + } while (--h); +} +void AGOSEngine::drawVertImage(VC10_state *state) { if (state->flags & kDFCompressed) { uint w, h; byte *src, *dst, *dstPtr; @@ -697,6 +756,9 @@ void AGOSEngine::drawImages(VC10_state *state) { vc10_skip_cols(state); dstPtr = state->surf_addr; + if (!(state->flags & kDFNonTrans) && (state->flags & 0x40)) { /* reached */ + dstPtr += vcReadVar(252); + } w = 0; do { byte color; @@ -712,7 +774,7 @@ void AGOSEngine::drawImages(VC10_state *state) { color = (*src & 15); if ((state->flags & kDFNonTrans) || color != 0) dst[1] = color | state->palette; - dst += _screenWidth; + dst += state->surf_pitch; src++; } while (++h != state->draw_height); dstPtr += 2; @@ -722,26 +784,115 @@ void AGOSEngine::drawImages(VC10_state *state) { byte *dst; uint count; - src = state->depack_src + (state->width * state->y_skip) * 8; + src = state->srcPtr + (state->width * state->y_skip) * 8; dst = state->surf_addr; state->x_skip *= 4; do { for (count = 0; count != state->draw_width; count++) { byte color; - color = (src[count + state->x_skip] / 16); + color = (src[count + state->x_skip] / 16) + state->paletteMod; if ((state->flags & kDFNonTrans) || color) dst[count * 2] = color | state->palette; - color = (src[count + state->x_skip] & 15); + color = (src[count + state->x_skip] & 15) + state->paletteMod; if ((state->flags & kDFNonTrans) || color) dst[count * 2 + 1] = color | state->palette; } - dst += _screenWidth; + dst += state->surf_pitch; src += state->width * 8; } while (--state->draw_height); } } +void AGOSEngine::drawImage(VC10_state *state) { + const uint16 *vlut = &_videoWindows[_windowNum * 4]; + + if (!drawImage_clip(state)) + return; + + uint16 xoffs = 0, yoffs = 0; + if (getGameType() == GType_WW) { + if (_windowNum == 4 || (_windowNum >= 10 && _windowNum <= 27)) { + state->surf_addr = _window4BackScn; + state->surf_pitch = _videoWindows[18] * 16; + + xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; + yoffs = (vlut[1] - _videoWindows[17] + state->y); + + uint xmax = (xoffs + state->draw_width * 2); + uint ymax = (yoffs + state->draw_height); + setMoveRect(xoffs, yoffs, xmax, ymax); + + _window4Flag = 1; + } else { + state->surf_addr = getFrontBuf(); + state->surf_pitch = _screenWidth; + + xoffs = (vlut[0] * 2 + state->x) * 8; + yoffs = vlut[1] + state->y; + } + } else if (getGameType() == GType_ELVIRA2) { + if (_windowNum == 4 || _windowNum >= 10) { + state->surf_addr = _window4BackScn; + state->surf_pitch = _videoWindows[18] * 16; + + xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; + yoffs = (vlut[1] - _videoWindows[17] + state->y); + + uint xmax = (xoffs + state->draw_width * 2); + uint ymax = (yoffs + state->draw_height); + setMoveRect(xoffs, yoffs, xmax, ymax); + + _window4Flag = 1; + } else { + state->surf_addr = getFrontBuf(); + state->surf_pitch = _screenWidth; + + xoffs = (vlut[0] * 2 + state->x) * 8; + yoffs = vlut[1] + state->y; + } + } else if (getGameType() == GType_ELVIRA1) { + if (_windowNum == 6) { + state->surf_addr = _window6BackScn; + state->surf_pitch = 48; + + xoffs = state->x * 8; + yoffs = state->y; + } else if (_windowNum == 2 || _windowNum == 3) { + state->surf_addr = getFrontBuf(); + state->surf_pitch = _screenWidth; + + xoffs = (vlut[0] * 2 + state->x) * 8; + yoffs = vlut[1] + state->y; + } else { + state->surf_addr = _window4BackScn; + state->surf_pitch = _videoWindows[18] * 16; + + xoffs = ((vlut[0] - _videoWindows[16]) * 2 + state->x) * 8; + yoffs = (vlut[1] - _videoWindows[17] + state->y); + + uint xmax = (xoffs + state->draw_width * 2); + uint ymax = (yoffs + state->draw_height); + setMoveRect(xoffs, yoffs, xmax, ymax); + + _window4Flag = 1; + } + } + + state->surf_addr += xoffs + yoffs * state->surf_pitch; + + if (getGameType() == GType_ELVIRA1 && (state->flags & kDFNonTrans) && yoffs > 133) + state->paletteMod = 16; + + if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) + state->palette = state->surf_addr[0] & 0xF0; + + if (_backFlag == 1) { + drawBackGroundImage(state); + } else { + drawVertImage(state); + } +} void AGOSEngine::horizontalScroll(VC10_state *state) { const byte *src; @@ -753,7 +904,7 @@ void AGOSEngine::horizontalScroll(VC10_state *state) { else _scrollXMax = state->width * 2 - 40; _scrollYMax = 0; - _scrollImage = state->depack_src; + _scrollImage = state->srcPtr; _scrollHeight = state->height; if (_variableArrayPtr[34] < 0) state->x = _variableArrayPtr[251]; @@ -762,18 +913,26 @@ void AGOSEngine::horizontalScroll(VC10_state *state) { vcWriteVar(251, _scrollX); - dst = getBackBuf(); + if (getGameType() == GType_SIMON2) { + dst = _window4BackScn; + } else { + dst = getBackBuf(); + } if (getGameType() == GType_FF) - src = state->depack_src + _scrollX / 2; + src = state->srcPtr + _scrollX / 2; else - src = state->depack_src + _scrollX * 4; + src = state->srcPtr + _scrollX * 4; for (w = 0; w < _screenWidth; w += 8) { decodeColumn(dst, src + readUint32Wrapper(src), state->height); dst += 8; src += 4; } + + setMoveRect(0, 0, 320, _scrollHeight); + + _window4Flag = 1; } void AGOSEngine::verticalScroll(VC10_state *state) { @@ -783,7 +942,7 @@ void AGOSEngine::verticalScroll(VC10_state *state) { _scrollXMax = 0; _scrollYMax = state->height - 480; - _scrollImage = state->depack_src; + _scrollImage = state->srcPtr; _scrollWidth = state->width; if (_variableArrayPtr[34] < 0) state->y = _variableArrayPtr[250]; @@ -793,7 +952,7 @@ void AGOSEngine::verticalScroll(VC10_state *state) { vcWriteVar(250, _scrollY); dst = getBackBuf(); - src = state->depack_src + _scrollY / 2; + src = state->srcPtr + _scrollY / 2; for (h = 0; h < _screenHeight; h += 8) { decodeRow(dst, src + READ_LE_UINT32(src), state->width); @@ -802,70 +961,6 @@ void AGOSEngine::verticalScroll(VC10_state *state) { } } -void AGOSEngine::scaleClip(int16 h, int16 w, int16 y, int16 x, int16 scrollY) { - Common::Rect srcRect, dstRect; - float factor, xscale; - - srcRect.left = 0; - srcRect.top = 0; - srcRect.right = w; - srcRect.bottom = h; - - if (scrollY > _baseY) - factor = 1 + ((scrollY - _baseY) * _scale); - else - factor = 1 - ((_baseY - scrollY) * _scale); - - xscale = ((w * factor) / 2); - - dstRect.left = (int16)(x - xscale); - if (dstRect.left > _screenWidth - 1) - return; - dstRect.top = (int16)(y - (h * factor)); - if (dstRect.top > _screenHeight - 1) - return; - - dstRect.right = (int16)(x + xscale); - dstRect.bottom = y; - - _feebleRect = dstRect; - - _variableArray[20] = _feebleRect.top; - _variableArray[21] = _feebleRect.left; - _variableArray[22] = _feebleRect.bottom; - _variableArray[23] = _feebleRect.right; - - debug(5, "Left %d Right %d Top %d Bottom %d", dstRect.left, dstRect.right, dstRect.top, dstRect.bottom); - - // Unlike normal rectangles in ScummVM, it seems that in the case of - // the destination rectangle the bottom and right coordinates are - // considered to be inside the rectangle. For the source rectangle, - // I believe that they are not. - - int scaledW = dstRect.width() + 1; - int scaledH = dstRect.height() + 1; - - byte *src = getScaleBuf(); - byte *dst = getBackBuf(); - - dst += _dxSurfacePitch * dstRect.top + dstRect.left; - - for (int dstY = 0; dstY < scaledH; dstY++) { - if (dstRect.top + dstY >= 0 && dstRect.top + dstY < _screenHeight) { - int srcY = (dstY * h) / scaledH; - byte *srcPtr = src + _dxSurfacePitch * srcY; - byte *dstPtr = dst + _dxSurfacePitch * dstY; - for (int dstX = 0; dstX < scaledW; dstX++) { - if (dstRect.left + dstX >= 0 && dstRect.left + dstX < _screenWidth) { - int srcX = (dstX * w) / scaledW; - if (srcPtr[srcX]) - dstPtr[dstX] = srcPtr[srcX]; - } - } - } - } -} - void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) { byte *p = palPtr; @@ -886,7 +981,7 @@ void AGOSEngine::paletteFadeOut(byte *palPtr, uint num, uint size) { } while (--num); } -void AGOSEngine::animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, uint y, uint palette, bool vgaScript) { +void AGOSEngine::animate(uint16 windowNum, uint16 zoneNum, uint16 vgaSpriteId, int16 x, int16 y, uint16 palette, bool vgaScript) { VgaSprite *vsp; VgaPointersEntry *vpe; byte *p, *pp; @@ -959,10 +1054,7 @@ void AGOSEngine::animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, p += sizeof(AnimationHeader_Simon); } - if (READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) != vgaSpriteId) { - debug(0, "setImage: Animation %d not found.", vgaSpriteId); - return; - } + assert(READ_BE_UINT16(&((AnimationHeader_Simon *) p)->id) == vgaSpriteId); } else { p = pp + READ_BE_UINT16(pp + 10); p += 20; @@ -1009,11 +1101,11 @@ void AGOSEngine::animate(uint windowNum, uint zoneNum, uint vgaSpriteId, uint x, } if (getGameType() == GType_FF || getGameType() == GType_PP) { - addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, zoneNum); + addVgaEvent(_vgaBaseDelay, ANIMATE_EVENT, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, zoneNum); } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, zoneNum); + addVgaEvent(_vgaBaseDelay, ANIMATE_EVENT, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, zoneNum); } else { - addVgaEvent(_vgaBaseDelay, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum); + addVgaEvent(_vgaBaseDelay, ANIMATE_EVENT, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_WW *) p)->scriptOffs), vgaSpriteId, zoneNum); } } @@ -1072,12 +1164,10 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) { break; b += sizeof(ImageHeader_Simon); } + assert(READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) == vga_res_id); - - if (READ_BE_UINT16(&((ImageHeader_Simon *) b)->id) != vga_res_id) { - debug(0, "setImage: Image %d not found.", vga_res_id); - return; - } + if (!vgaScript) + clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_Simon *) b)->color)); } else { b = bb + READ_BE_UINT16(bb + 10); b += 20; @@ -1093,7 +1183,7 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) { assert(READ_BE_UINT16(&((ImageHeader_WW *) b)->id) == vga_res_id); if (!vgaScript) - clearWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color)); + clearVideoWindow(_windowNum, READ_BE_UINT16(&((ImageHeader_WW *) b)->color)); } if (_startVgaScript) { @@ -1121,6 +1211,8 @@ void AGOSEngine::setImage(uint16 vga_res_id, bool vgaScript) { } void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) { + _window3Flag = 0; + if (mode == 4) { vc29_stopAllSounds(); @@ -1141,35 +1233,37 @@ void AGOSEngine::setWindowImageEx(uint16 mode, uint16 vga_res) { if (_lockWord & 0x10) error("setWindowImageEx: _lockWord & 0x10"); - setWindowImage(mode, vga_res); + if (getGameType() != GType_PP && getGameType() != GType_FF) { + if (getGameType() == GType_WW && (mode == 6 || mode == 8 || mode == 9)) { + setWindowImage(mode, vga_res); + } else { + while (_copyScnFlag) + delay(1); + + setWindowImage(mode, vga_res); + } + } else { + setWindowImage(mode, vga_res); + } } void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) { - uint num_lines; uint16 updateWindow; _windowNum = updateWindow = mode; _lockWord |= 0x20; + VgaTimerEntry *vte = _vgaTimerList; + while (vte->type != 2) + vte++; + + vte->delay = 2; + if (getGameType() == GType_FF || getGameType() == GType_PP) { vc27_resetSprite(); } - if (vga_res_id == 0) { - if (getGameType() == GType_SIMON1) { - _unkPalFlag = true; - } else if (getGameType() == GType_SIMON2) { - _useBackGround = true; - _restoreWindow6 = true; - } - } - - if (getGameType() == GType_SIMON1) { - if (vga_res_id == 16300) { - clearBackFromTop(134); - _usePaletteDelay = true; - } - } else if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) { + if (getGameType() == GType_SIMON2 || getGameType() == GType_FF) { _scrollX = 0; _scrollY = 0; _scrollXMax = 0; @@ -1191,55 +1285,113 @@ void AGOSEngine::setWindowImage(uint16 mode, uint16 vga_res_id) { fillFrontFromBack(0, 0, _screenWidth, _screenHeight); fillBackGroundFromBack(_screenHeight); _syncFlag2 = 1; - } else if (getGameType() == GType_SIMON2) { - if (!_useBackGround) { - num_lines = _windowNum == 4 ? 134 : 200; - _boxStarHeight = num_lines; - fillFrontFromBack(0, 0, _screenWidth, num_lines); - fillBackGroundFromBack(num_lines); - _syncFlag2 = 1; + } else { + _copyScnFlag = 2; + _vgaSpriteChanged++; + + if (_window3Flag == 1) { + clearVideoBackGround(3, 0); + _lockWord &= ~0x20; + return; } - _useBackGround = false; - } else if (getGameType() == GType_SIMON1) { - // Allow one section of Simon the Sorcerer 1 introduction to be displayed - // in lower half of screen - if (_subroutine == 2923 || _subroutine == 2926) - num_lines = 200; - else - num_lines = _windowNum == 4 ? 134 : 200; - fillFrontFromBack(0, 0, _screenWidth, num_lines); - fillBackGroundFromBack(num_lines); - _syncFlag2 = 1; - _timer5 = 0; - } else { - num_lines = _windowNum == 4 ? 134 : 200; - fillFrontFromBack(0, 0, _screenWidth, num_lines); - fillBackGroundFromBack(num_lines); - _syncFlag2 = 1; - _timer5 = 0; - } + uint xoffs = _videoWindows[updateWindow * 4 + 0] * 16; + uint yoffs = _videoWindows[updateWindow * 4 + 1]; + uint width = _videoWindows[updateWindow * 4 + 2] * 16; + uint height = _videoWindows[updateWindow * 4 + 3]; + + byte *dst = getBackGround() + xoffs + yoffs * _screenWidth; + byte *src = dst; + uint srcWidth = 0; + + if (getGameType() == GType_SIMON2) { + src = _window4BackScn + xoffs + yoffs * 320; + srcWidth = 320; + } else if (getGameType() == GType_SIMON1 && (getFeatures() & GF_DEMO)) { + // The DOS Floppy demo was based off Waxworks engine + if (updateWindow == 4 || updateWindow >= 10) { + src = _window4BackScn; + srcWidth = _videoWindows[18] * 16; + } else if (updateWindow == 3 || updateWindow == 9) { + src = getFrontBuf() + xoffs + yoffs * _screenWidth; + srcWidth = _screenWidth; + } else { + _lockWord &= ~0x20; + return; + } + } else if (getGameType() == GType_SIMON1) { + if (updateWindow == 4) { + src = _window4BackScn; + srcWidth = _videoWindows[18] * 16; + } else if (updateWindow >= 10) { + src = _window4BackScn + xoffs + yoffs * 320; + srcWidth = _videoWindows[18] * 16; + } else if (updateWindow == 0) { + src = getFrontBuf() + xoffs + yoffs * _screenWidth; + srcWidth = _screenWidth; + } else { + _lockWord &= ~0x20; + return; + } + } else if (getGameType() == GType_WW) { + if (updateWindow == 4 || updateWindow >= 10) { + src = _window4BackScn; + srcWidth = _videoWindows[18] * 16; + } else if (updateWindow == 3 || updateWindow == 9) { + src = getFrontBuf() + xoffs + yoffs * _screenWidth; + srcWidth = _screenWidth; + } else { + _lockWord &= ~0x20; + return; + } + } else if (getGameType() == GType_ELVIRA2) { + if (updateWindow == 4 || updateWindow >= 10) { + src = _window4BackScn; + srcWidth = _videoWindows[18] * 16; + } else if (updateWindow == 3) { + src = getFrontBuf() + xoffs + yoffs * _screenWidth; + srcWidth = _screenWidth; + } else { + _lockWord &= ~0x20; + return; + } + } else if (getGameType() == GType_ELVIRA1) { + if (updateWindow == 6) { + _window6Flag = 1; + src = _window6BackScn; + srcWidth = 48; + } else if (updateWindow == 2 || updateWindow == 3) { + src = getFrontBuf() + xoffs + yoffs * _screenWidth; + srcWidth = _screenWidth; + } else { + src = _window4BackScn; + srcWidth = _videoWindows[18] * 16; + } + } - if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette != 0) { - byte *dst = getBackBuf() + 42560; - int size = 21440; + _boxStarHeight = height; - while (size--) { - *dst += 0x10; - dst++; + for (; height > 0; height--) { + memcpy(dst, src, width); + dst += _screenWidth; + src += srcWidth; } - } - _lockWord &= ~0x20; + if (getGameType() == GType_ELVIRA1 && updateWindow == 3 && _bottomPalette) { + dst = getFrontBuf() + 133 * _screenWidth; + int size = 67 * _screenWidth; - if (getGameType() == GType_SIMON1) { - if (_unkPalFlag) { - _unkPalFlag = false; - while (_fastFadeInFlag != 0) { - delay(10); + while (size--) { + *dst += 0x10; + dst++; } } + + _syncFlag2 = 1; + _timer5 = 0; } + + _lockWord &= ~0x20; } } // End of namespace AGOS diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp index 4a67a914d8..72afd25f43 100644 --- a/engines/agos/icons.cpp +++ b/engines/agos/icons.cpp @@ -58,12 +58,12 @@ void AGOSEngine::loadIconData() { error("Out of icon memory"); memcpy(_iconFilePtr, src, 43 * 336); - os1_unfreezeZones(); + unfreezeBottom(); } // Thanks to Stuart Caie for providing the original // C conversion upon which this function is based. -static void decompressIconAmiga(byte *dst, byte *src, uint width, uint height, byte base, uint pitch, bool decompress = true) { +static void decompressIconPlanar(byte *dst, byte *src, uint width, uint height, byte base, uint pitch, bool decompress = true) { byte icon_pln[288]; byte *i, *o, *srcPtr, x, y; @@ -167,190 +167,123 @@ static void decompressIcon(byte *dst, byte *src, uint width, uint height, byte b } } -void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { +void AGOSEngine_Simon2::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { byte *dst; byte *src; _lockWord |= 0x8000; dst = getFrontBuf(); - if (getGameType() == GType_SIMON2) { - dst += 110; - dst += x; - dst += (y + window->y) * _dxSurfacePitch; + dst += 110; + dst += x; + dst += (y + window->y) * _dxSurfacePitch; - src = _iconFilePtr; - src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]); - decompressIcon(dst, src, 20, 10, 224, _dxSurfacePitch); + src = _iconFilePtr; + src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 0]); + decompressIcon(dst, src, 20, 10, 224, _dxSurfacePitch); - src = _iconFilePtr; - src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]); - decompressIcon(dst, src, 20, 10, 208, _dxSurfacePitch); - } else if (getGameType() == GType_SIMON1) { - dst += (x + window->x) * 8; - dst += (y * 25 + window->y) * _dxSurfacePitch; - - if (getPlatform() == Common::kPlatformAmiga) { - src = _iconFilePtr; - src += READ_BE_UINT32(&((uint32 *)src)[icon]); - uint8 color = (getFeatures() & GF_32COLOR) ? 16 : 240; - decompressIconAmiga(dst, src, 24, 24, color, _dxSurfacePitch); - } else { - src = _iconFilePtr; - src += READ_LE_UINT16(&((uint16 *)src)[icon]); - decompressIcon(dst, src, 24, 12, 224, _dxSurfacePitch); - } - } else if (getGameType() == GType_WW) { - dst += (x + window->x) * 8; - dst += (y * 20 + window->y) * _dxSurfacePitch; + src = _iconFilePtr; + src += READ_LE_UINT16(&((uint16 *)src)[icon * 2 + 1]); + decompressIcon(dst, src, 20, 10, 208, _dxSurfacePitch); - uint8 color = dst[0] & 0xF0; + _lockWord &= ~0x8000; +} - if (getPlatform() == Common::kPlatformAmiga) { - src = _iconFilePtr; - src += READ_BE_UINT32(&((uint32 *)src)[icon]); - decompressIconAmiga(dst, src, 24, 20, color, _dxSurfacePitch); - } else { - src = _iconFilePtr; - src += READ_LE_UINT16(&((uint16 *)src)[icon]); - decompressIcon(dst, src, 24, 10, color, _dxSurfacePitch); - } - } else if (getGameType() == GType_ELVIRA2) { - dst += (x + window->x) * 8; - dst += (y * 8 + window->y) * _dxSurfacePitch; +void AGOSEngine_Simon1::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { + byte *dst; + byte *src; - uint color = dst[0] & 0xF0; + _lockWord |= 0x8000; + dst = getFrontBuf(); - if (getPlatform() == Common::kPlatformAmiga) { - src = _iconFilePtr; - src += READ_BE_UINT32(&((uint32 *)src)[icon]); - decompressIconAmiga(dst, src, 24, 24, color, _dxSurfacePitch); - } else { - src = _iconFilePtr; - src += READ_LE_UINT16(&((uint16 *)src)[icon]); - decompressIcon(dst, src, 24, 12, color, _dxSurfacePitch); - } - } else if (getGameType() == GType_ELVIRA1) { - dst += (x + window->x) * 8; - dst += (y * 8 + window->y) * _dxSurfacePitch; + dst += (x + window->x) * 8; + dst += (y * 25 + window->y) * _dxSurfacePitch; + if (getPlatform() == Common::kPlatformAmiga) { src = _iconFilePtr; - src += icon * 288; - decompressIconAmiga(dst, src, 24, 24, 16, _dxSurfacePitch, false); + src += READ_BE_UINT32(&((uint32 *)src)[icon]); + uint8 color = (getFeatures() & GF_32COLOR) ? 16 : 240; + decompressIconPlanar(dst, src, 24, 24, color, _dxSurfacePitch); + } else { + src = _iconFilePtr; + src += READ_LE_UINT16(&((uint16 *)src)[icon]); + decompressIcon(dst, src, 24, 12, 224, _dxSurfacePitch); } _lockWord &= ~0x8000; } -void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) { - if (getGameType() == GType_FF) { - drawIconArray_FF(num, itemRef, line, classMask); - } else { - drawIconArray_Simon(num, itemRef, line, classMask); - } -} +void AGOSEngine_Waxworks::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { + byte *dst; + byte *src; -void AGOSEngine::drawIconArray_Simon(uint num, Item *itemRef, int line, int classMask) { - Item *item_ptr_org = itemRef; - WindowBlock *window; - uint width, height; - uint k, i, curWidth; - bool item_again, showArrows; - uint x_pos, y_pos; - const int iconSize = (getGameType() == GType_SIMON2) ? 20 : 1; + _lockWord |= 0x8000; + dst = getFrontBuf(); - window = _windowArray[num & 7]; + dst += (x + window->x) * 8; + dst += (y * 20 + window->y) * _dxSurfacePitch; - if (getGameType() == GType_SIMON2) { - width = 100; - height = 40; + uint8 color = dst[0] & 0xF0; + if (getPlatform() == Common::kPlatformAmiga) { + // TODO + return; } else { - width = window->width / 3; - height = window->height / 3; + src = _iconFilePtr; + src += READ_LE_UINT16(&((uint16 *)src)[icon]); + decompressIcon(dst, src, 24, 10, color, _dxSurfacePitch); } - i = 0; - - if (window == NULL) - return; - - if (window->iconPtr) - removeIconArray(num); + _lockWord &= ~0x8000; +} - window->iconPtr = (IconBlock *) malloc(sizeof(IconBlock)); - window->iconPtr->itemRef = itemRef; - window->iconPtr->upArrow = -1; - window->iconPtr->downArrow = -1; - window->iconPtr->line = line; - window->iconPtr->classMask = classMask; +void AGOSEngine_Elvira2::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { + byte *dst; + byte *src; - itemRef = derefItem(itemRef->child); + _lockWord |= 0x8000; + dst = getFrontBuf(); - while (itemRef && line-- != 0) { - curWidth = 0; - while (itemRef && width > curWidth) { - if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) - curWidth += iconSize; - itemRef = derefItem(itemRef->next); - } - } + dst += (x + window->x) * 8; + dst += (y * 8 + window->y) * _dxSurfacePitch; - if (itemRef == NULL) { - window->iconPtr->line = 0; - itemRef = derefItem(item_ptr_org->child); + uint color = dst[0] & 0xF0; + if (getFeatures() & GF_PLANAR) { + src = _iconFilePtr; + src += READ_BE_UINT32(&((uint32 *)src)[icon]); + decompressIconPlanar(dst, src, 24, 24, color, _dxSurfacePitch); + } else { + src = _iconFilePtr; + src += READ_LE_UINT16(&((uint16 *)src)[icon]); + decompressIcon(dst, src, 24, 12, color, _dxSurfacePitch); } - x_pos = 0; - y_pos = 0; - k = 0; - item_again = false; - showArrows = false; + _lockWord &= ~0x8000; +} - while (itemRef) { - if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) { - if (item_again == false) { - window->iconPtr->iconArray[k].item = itemRef; - if (getGameType() == GType_SIMON2) { - drawIcon(window, itemGetIconNumber(itemRef), x_pos, y_pos); - window->iconPtr->iconArray[k].boxCode = - setupIconHitArea(window, 0, x_pos, y_pos, itemRef); - } else if (getGameType() == GType_SIMON1) { - drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos); - window->iconPtr->iconArray[k].boxCode = - setupIconHitArea(window, 0, x_pos * 3, y_pos, itemRef); - } else { - drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos * 3); - window->iconPtr->iconArray[k].boxCode = - setupIconHitArea(window, 0, x_pos * 3, y_pos * 3, itemRef); - } - k++; - } else { - window->iconPtr->iconArray[k].item = NULL; - showArrows = 1; - } +void AGOSEngine::drawIcon(WindowBlock *window, uint icon, uint x, uint y) { + byte *dst; + byte *src; - x_pos += iconSize; - if (x_pos >= width) { - x_pos = 0; - y_pos += iconSize; - if (y_pos >= height) - item_again = true; - } - } - itemRef = derefItem(itemRef->next); - } + _lockWord |= 0x8000; + dst = getFrontBuf(); - window->iconPtr->iconArray[k].item = NULL; + dst += (x + window->x) * 8; + dst += (y * 8 + window->y) * _dxSurfacePitch; - if (showArrows != 0 || window->iconPtr->line != 0) { - /* Plot arrows and add their boxes */ - addArrows(window); - window->iconPtr->upArrow = _scrollUpHitArea; - window->iconPtr->downArrow = _scrollDownHitArea; + if (getFeatures() & GF_PLANAR) { + src = _iconFilePtr; + src += READ_BE_UINT16(&((uint16 *)src)[icon]); + decompressIconPlanar(dst, src, 24, 24, 16, _dxSurfacePitch); + } else { + src = _iconFilePtr; + src += icon * 288; + decompressIconPlanar(dst, src, 24, 24, 16, _dxSurfacePitch, false); } + + _lockWord &= ~0x8000; } -void AGOSEngine::drawIconArray_FF(uint num, Item *itemRef, int line, int classMask) { +void AGOSEngine_Feeble::drawIconArray(uint num, Item *itemRef, int line, int classMask) { Item *item_ptr_org = itemRef; WindowBlock *window; uint16 flagnumber = 201; @@ -454,225 +387,412 @@ l1:; itemRef = derefItem(itemRef->next); window->iconPtr->downArrow = _scrollDownHitArea; } -uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { - HitArea *ha; +void AGOSEngine::drawIconArray(uint num, Item *itemRef, int line, int classMask) { + Item *item_ptr_org = itemRef; + WindowBlock *window; + uint width, height; + uint k, i, curWidth; + bool item_again, showArrows; + uint x_pos, y_pos; + const int iconSize = (getGameType() == GType_SIMON2) ? 20 : 1; - ha = findEmptyHitArea(); + window = _windowArray[num & 7]; - if (getGameType() == GType_FF) { - ha->x = x; - ha->y = y; - ha->item_ptr = item_ptr; - ha->width = 45; - ha->height = 44; - ha->flags = kBFBoxInUse | kBFBoxItem; - ha->id = num; - ha->priority = 100; - ha->verb = 208; - } else if (getGameType() == GType_SIMON2) { - ha->x = x + 110; - ha->y = window->y + y; - ha->item_ptr = item_ptr; - ha->width = 20; - ha->height = 20; - ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; - ha->id = 0x7FFD; - ha->priority = 100; - ha->verb = 208; - } else if (getGameType() == GType_SIMON1) { - ha->x = (x + window->x) * 8; - ha->y = y * 25 + window->y; - ha->item_ptr = item_ptr; - ha->width = 24; - ha->height = 24; - ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; - ha->id = 0x7FFD; - ha->priority = 100; - ha->verb = 208; + if (getGameType() == GType_SIMON2) { + width = 100; + height = 40; } else if (getGameType() == GType_WW) { - ha->x = (x + window->x) * 8; - ha->y = y * 20 + window->y; - ha->item_ptr = item_ptr; - ha->width = 24; - ha->height = 20; - ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; - ha->id = 0x7FFD; - ha->priority = 100; - ha->verb = 208; - } else if (getGameType() == GType_ELVIRA2) { - ha->x = (x + window->x) * 8; - ha->y = y * 8 + window->y; - ha->item_ptr = item_ptr; - ha->width = 24; - ha->height = 24; - ha->id = 0x7FFD; - ha->priority = 100; - - if (window->iconPtr->classMask == 2) { - ha->flags = kBFDragBox | kBFBoxInUse; - ha->verb = 248 + 0x4000; - } else { - ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; - ha->verb = 208; + width = window->width / 3; + height = window->height / 2; + } else { + width = window->width / 3; + height = window->height / 3; + } + + i = 0; + + if (window == NULL) + return; + + if (window->iconPtr) + removeIconArray(num); + + window->iconPtr = (IconBlock *) malloc(sizeof(IconBlock)); + window->iconPtr->itemRef = itemRef; + window->iconPtr->upArrow = -1; + window->iconPtr->downArrow = -1; + window->iconPtr->line = line; + window->iconPtr->classMask = classMask; + + itemRef = derefItem(itemRef->child); + + while (itemRef && line-- != 0) { + curWidth = 0; + while (itemRef && width > curWidth) { + if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) + curWidth += iconSize; + itemRef = derefItem(itemRef->next); } + } + + if (itemRef == NULL) { + window->iconPtr->line = 0; + itemRef = derefItem(item_ptr_org->child); + } + + x_pos = 0; + y_pos = 0; + k = 0; + item_again = false; + showArrows = false; + + while (itemRef) { + if ((classMask == 0 || itemRef->classFlags & classMask) && hasIcon(itemRef)) { + if (item_again == false) { + window->iconPtr->iconArray[k].item = itemRef; + if (getGameType() == GType_SIMON2) { + drawIcon(window, itemGetIconNumber(itemRef), x_pos, y_pos); + window->iconPtr->iconArray[k].boxCode = + setupIconHitArea(window, 0, x_pos, y_pos, itemRef); + } else if (getGameType() == GType_SIMON1 || getGameType() == GType_WW) { + drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos); + window->iconPtr->iconArray[k].boxCode = + setupIconHitArea(window, 0, x_pos * 3, y_pos, itemRef); + } else { + drawIcon(window, itemGetIconNumber(itemRef), x_pos * 3, y_pos * 3); + window->iconPtr->iconArray[k].boxCode = + setupIconHitArea(window, 0, x_pos * 3, y_pos * 3, itemRef); + } + k++; + } else { + window->iconPtr->iconArray[k].item = NULL; + showArrows = 1; + } + + x_pos += iconSize; + if (x_pos >= width) { + x_pos = 0; + y_pos += iconSize; + if (y_pos >= height) + item_again = true; + } + } + itemRef = derefItem(itemRef->next); + } + + window->iconPtr->iconArray[k].item = NULL; + + if (showArrows != 0 || window->iconPtr->line != 0) { + /* Plot arrows and add their boxes */ + addArrows(window); + window->iconPtr->upArrow = _scrollUpHitArea; + window->iconPtr->downArrow = _scrollDownHitArea; + } +} + +uint AGOSEngine_Feeble::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { + HitArea *ha = findEmptyHitArea(); + + ha->x = x; + ha->y = y; + ha->item_ptr = item_ptr; + ha->width = 45; + ha->height = 44; + ha->flags = kBFBoxInUse | kBFBoxItem; + ha->id = num; + ha->priority = 100; + ha->verb = 208; + + return ha - _hitAreas; +} + +uint AGOSEngine_Simon2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { + HitArea *ha = findEmptyHitArea(); + + ha->x = x + 110; + ha->y = window->y + y; + ha->item_ptr = item_ptr; + ha->width = 20; + ha->height = 20; + ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; + ha->id = 0x7FFD; + ha->priority = 100; + ha->verb = 208; + + return ha - _hitAreas; +} + +uint AGOSEngine_Simon1::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { + HitArea *ha = findEmptyHitArea(); + + ha->x = (x + window->x) * 8; + ha->y = y * 25 + window->y; + ha->item_ptr = item_ptr; + ha->width = 24; + ha->height = 24; + ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; + ha->id = 0x7FFD; + ha->priority = 100; + ha->verb = 208; + + return ha - _hitAreas; +} + +uint AGOSEngine_Waxworks::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { + HitArea *ha = findEmptyHitArea(); + + ha->x = (x + window->x) * 8; + ha->y = y * 20 + window->y; + ha->item_ptr = item_ptr; + ha->width = 24; + ha->height = 20; + ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; + ha->id = 0x7FFD; + ha->priority = 100; + ha->verb = 208; + + return ha - _hitAreas; +} + +uint AGOSEngine_Elvira2::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { + HitArea *ha = findEmptyHitArea(); + + ha->x = (x + window->x) * 8; + ha->y = y * 8 + window->y; + ha->item_ptr = item_ptr; + ha->width = 24; + ha->height = 24; + ha->id = 0x7FFD; + ha->priority = 100; + + if (window->iconPtr->classMask == 2) { + ha->flags = kBFDragBox | kBFBoxInUse; + ha->verb = 248 + 0x4000; } else { - ha->x = (x + window->x) * 8; - ha->y = y * 8 + window->y; - ha->item_ptr = item_ptr; - ha->width = 24; - ha->height = 24; ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; - ha->id = 0x7FFD; - ha->priority = 100; - ha->verb = 253; + ha->verb = 208; } return ha - _hitAreas; } -void AGOSEngine::addArrows(WindowBlock *window) { +uint AGOSEngine::setupIconHitArea(WindowBlock *window, uint num, uint x, uint y, Item *item_ptr) { + HitArea *ha = findEmptyHitArea(); + + ha->x = (x + window->x) * 8; + ha->y = y * 8 + window->y; + ha->item_ptr = item_ptr; + ha->width = 24; + ha->height = 24; + ha->flags = kBFDragBox | kBFBoxInUse | kBFBoxItem; + ha->id = 0x7FFD; + ha->priority = 100; + ha->verb = 253; + + return ha - _hitAreas; +} + +void AGOSEngine_Feeble::addArrows(WindowBlock *window) { HitArea *ha; ha = findEmptyHitArea(); _scrollUpHitArea = ha - _hitAreas; - if (getGameType() == GType_FF) { - ha->x = 496; - ha->y = 279; - ha->width = 30; - ha->height = 45; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else if (getGameType() == GType_SIMON2) { - ha->x = 81; - ha->y = 158; - ha->width = 12; - ha->height = 26; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else if (getGameType() == GType_SIMON1) { - ha->x = 308; - ha->y = 149; - ha->width = 12; - ha->height = 17; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else if (getGameType() == GType_WW) { - setBitFlag(22, true); - ha->x = 255; - ha->y = 153; - ha->width = 9; - ha->height = 11; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else if (getGameType() == GType_ELVIRA2) { - setBitFlag(21, true); - ha->x = 54; - ha->y = 154; - ha->width = 12; - ha->height = 10; - ha->flags = kBFBoxInUse; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else { - ha->x = 30 * 8; - ha->y = 151; - ha->width = 16; - ha->height = 19; - ha->flags = kBFBoxInUse; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } + + ha->x = 496; + ha->y = 279; + ha->width = 30; + ha->height = 45; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFB; + ha->priority = 100; + ha->window = window; + ha->verb = 1; ha = findEmptyHitArea(); _scrollDownHitArea = ha - _hitAreas; - if (getGameType() == GType_FF) { - ha->x = 496; - ha->y = 324; - ha->width = 30; - ha->height = 44; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFC; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else if (getGameType() == GType_SIMON2) { - ha->x = 227; - ha->y = 162; - ha->width = 12; - ha->height = 26; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFC; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - } else if (getGameType() == GType_SIMON1) { - ha->x = 308; - ha->y = 176; - ha->width = 12; - ha->height = 17; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFC; - ha->priority = 100; - ha->window = window; - ha->verb = 1; + ha->x = 496; + ha->y = 324; + ha->width = 30; + ha->height = 44; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFC; + ha->priority = 100; + ha->window = window; + ha->verb = 1; +} - stopAnimate(128); - animate(0, 1, 128, 0, 0, 14); - } else if (getGameType() == GType_WW) { - ha->x = 255; - ha->y = 170; - ha->width = 9; - ha->height = 11; - ha->flags = kBFBoxInUse | kBFNoTouchName; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - setWindowImageEx(6, 103); - } else if (getGameType() == GType_ELVIRA2) { - ha->x = 54; - ha->y = 178; - ha->width = 12; - ha->height = 10; - ha->flags = kBFBoxInUse; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; - setWindowImageEx(6, 106); +void AGOSEngine_Simon2::addArrows(WindowBlock *window) { + HitArea *ha; + + ha = findEmptyHitArea(); + _scrollUpHitArea = ha - _hitAreas; + + ha->x = 81; + ha->y = 158; + ha->width = 12; + ha->height = 26; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFB; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + + ha = findEmptyHitArea(); + _scrollDownHitArea = ha - _hitAreas; + + ha->x = 227; + ha->y = 162; + ha->width = 12; + ha->height = 26; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFC; + ha->priority = 100; + ha->window = window; + ha->verb = 1; +} + +void AGOSEngine_Simon1::addArrows(WindowBlock *window) { + HitArea *ha; + + ha = findEmptyHitArea(); + _scrollUpHitArea = ha - _hitAreas; + + ha->x = 308; + ha->y = 149; + ha->width = 12; + ha->height = 17; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFB; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + + ha = findEmptyHitArea(); + _scrollDownHitArea = ha - _hitAreas; + + ha->x = 308; + ha->y = 176; + ha->width = 12; + ha->height = 17; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFC; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + + if (getFeatures() & GF_32COLOR) { + // TODO: Manually draws arrows } else { - ha->x = 30 * 8; - ha->y = 170; - ha->width = 16; - ha->height = 19; - ha->flags = kBFBoxInUse; - ha->id = 0x7FFB; - ha->priority = 100; - ha->window = window; - ha->verb = 1; + stopAnimate(128); + uint8 palette = (getPlatform() == Common::kPlatformAmiga) ? 15: 14; + animate(0, 1, 128, 0, 0, palette); } } +void AGOSEngine_Waxworks::addArrows(WindowBlock *window) { + HitArea *ha; + + ha = findEmptyHitArea(); + _scrollUpHitArea = ha - _hitAreas; + + setBitFlag(22, true); + ha->x = 255; + ha->y = 153; + ha->width = 9; + ha->height = 11; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFB; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + + ha = findEmptyHitArea(); + _scrollDownHitArea = ha - _hitAreas; + + ha->x = 255; + ha->y = 170; + ha->width = 9; + ha->height = 11; + ha->flags = kBFBoxInUse | kBFNoTouchName; + ha->id = 0x7FFC; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + setWindowImageEx(6, 103); +} + +void AGOSEngine_Elvira2::addArrows(WindowBlock *window) { + HitArea *ha; + + ha = findEmptyHitArea(); + _scrollUpHitArea = ha - _hitAreas; + + setBitFlag(21, true); + ha->x = 54; + ha->y = 154; + ha->width = 12; + ha->height = 10; + ha->flags = kBFBoxInUse; + ha->id = 0x7FFB; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + + ha = findEmptyHitArea(); + _scrollDownHitArea = ha - _hitAreas; + + ha->x = 54; + ha->y = 178; + ha->width = 12; + ha->height = 10; + ha->flags = kBFBoxInUse; + ha->id = 0x7FFC; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + setWindowImageEx(6, 106); +} + +void AGOSEngine::addArrows(WindowBlock *window) { + HitArea *ha; + + ha = findEmptyHitArea(); + _scrollUpHitArea = ha - _hitAreas; + + ha->x = 30 * 8; + ha->y = 151; + ha->width = 16; + ha->height = 19; + ha->flags = kBFBoxInUse; + ha->id = 0x7FFB; + ha->priority = 100; + ha->window = window; + ha->verb = 1; + + ha = findEmptyHitArea(); + _scrollDownHitArea = ha - _hitAreas; + + ha->x = 30 * 8; + ha->y = 170; + ha->width = 16; + ha->height = 19; + ha->flags = kBFBoxInUse; + ha->id = 0x7FFC; + ha->priority = 100; + ha->window = window; + ha->verb = 1; +} + void AGOSEngine::removeArrows(WindowBlock *window, uint num) { if (getGameType() == GType_SIMON1) { - stopAnimate(128); + if (getFeatures() & GF_32COLOR) { + // TODO: Manually removes arrows + } else { + stopAnimate(129); + uint8 palette = (getPlatform() == Common::kPlatformAmiga) ? 15: 14; + animate(0, 1, 129, 0, 0, palette); + } } else if (getGameType() == GType_WW) { setBitFlag(22, false); setWindowImageEx(6, 103); @@ -695,7 +815,7 @@ void AGOSEngine::removeIconArray(uint num) { if (getGameType() != GType_FF && getGameType() != GType_PP) { changeWindow(num); - windowPutChar(12); + sendWindow(12); changeWindow(curWindow); } diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp index f84083b7bc..3c02018421 100644 --- a/engines/agos/input.cpp +++ b/engines/agos/input.cpp @@ -40,7 +40,7 @@ uint AGOSEngine::setVerbText(HitArea *ha) { if (ha->flags & kBFTextBox) { if (getGameType() == GType_PP) id = ha->id; - else if (getGameType() == GType_FF && (_lastHitArea->flags & kBFHyperBox)) + else if (getGameType() == GType_FF && (ha->flags & kBFHyperBox)) id = ha->data; else id = ha->flags / 256; @@ -160,6 +160,7 @@ out_of_here: _lastHitArea3 = 0; _lastHitArea = 0; _lastNameOn = NULL; + _mouseCursor = 0; _noRightClick = 0; } @@ -174,6 +175,7 @@ void AGOSEngine::waitForInput() { _verbHitArea = 0; _hitAreaSubjectItem = NULL; _hitAreaObjectItem = NULL; + _clickOnly = 0; _nameLocked = 0; if (getGameType() == GType_WW) { @@ -190,9 +192,9 @@ void AGOSEngine::waitForInput() { _dragAccept = 1; for (;;) { - if (getGameType() != GType_FF && getGameType() != GType_PP && _keyPressed == 35) + if ((getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) && _keyPressed == 35) displayBoxStars(); - if (processSpecialKeys() != 0) { + if (processSpecialKeys()) { if ((getGameType() == GType_PP && getGameId() != GID_DIMP) || getGameType() == GType_WW) goto out_of_here; @@ -202,14 +204,14 @@ void AGOSEngine::waitForInput() { _lastHitArea3 = NULL; _dragAccept = 1; } else { - if (_lastHitArea3 != 0 || _dragMode != 0) + if (_lastHitArea3 || _dragMode) break; hitarea_stuff_helper(); delay(100); } } - if (_lastHitArea3 == 0 && _dragMode != 0) { + if (!_lastHitArea3 && _dragMode) { ha = _lastClickRem; if (ha == 0 || ha->item_ptr == NULL || !(ha->flags & kBFDragBox)) { @@ -253,11 +255,8 @@ void AGOSEngine::waitForInput() { } ha = _lastHitArea; - if (_lastHitArea == NULL) { - continue; - } - - if (ha->id == 0x7FFB) { + if (ha == NULL) { + } else if (ha->id == 0x7FFB) { inventoryUp(ha->window); } else if (ha->id == 0x7FFC) { inventoryDown(ha->window); @@ -297,7 +296,7 @@ void AGOSEngine::waitForInput() { waitForSync(34); } } - if (ha->item_ptr && (ha->verb == 0 || _verbHitArea != 0 || + if (ha->item_ptr && (!ha->verb || _verbHitArea || (_hitAreaSubjectItem != ha->item_ptr && (ha->flags & kBFBoxItem))) ) { _hitAreaSubjectItem = ha->item_ptr; @@ -306,7 +305,7 @@ void AGOSEngine::waitForInput() { displayName(ha); _nameLocked = 1; - if (_verbHitArea != 0) { + if (_verbHitArea) { break; } @@ -317,8 +316,8 @@ void AGOSEngine::waitForInput() { else if (getGameType() == GType_ELVIRA1) lightMenuStrip(getUserFlag1(ha->item_ptr, 6)); } else { - if (ha->verb != 0) { - if (getGameType() == GType_WW && _mouseCursor != 0 && _mouseCursor < 4) { + if (ha->verb) { + if (getGameType() == GType_WW && _mouseCursor && _mouseCursor < 4) { _hitAreaSubjectItem = ha->item_ptr; break; } @@ -370,7 +369,7 @@ void AGOSEngine::hitarea_stuff_helper() { } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW || getGameType() == GType_SIMON1) { uint subr_id = (uint16)_variableArray[254]; - if (subr_id != 0) { + if (subr_id) { Subroutine *sub = getSubroutineByID(subr_id); if (sub != NULL) { startSubroutineEx(sub); @@ -387,6 +386,9 @@ void AGOSEngine::hitarea_stuff_helper() { if (kickoffTimeEvents()) permitInput(); } + + if (getGameId() == GID_DIMP) + delay(200); } void AGOSEngine::hitarea_stuff_helper_2() { @@ -394,7 +396,7 @@ void AGOSEngine::hitarea_stuff_helper_2() { Subroutine *sub; subr_id = (uint16)_variableArray[249]; - if (subr_id != 0) { + if (subr_id) { sub = getSubroutineByID(subr_id); if (sub != NULL) { _variableArray[249] = 0; @@ -405,7 +407,7 @@ void AGOSEngine::hitarea_stuff_helper_2() { } subr_id = (uint16)_variableArray[254]; - if (subr_id != 0) { + if (subr_id) { sub = getSubroutineByID(subr_id); if (sub != NULL) { _variableArray[254] = 0; @@ -442,7 +444,7 @@ void AGOSEngine::permitInput() { } _curWindow = 0; - if (_windowArray[0] != 0) { + if (_windowArray[0]) { _textWindow = _windowArray[0]; justifyStart(); } @@ -453,6 +455,20 @@ void AGOSEngine::permitInput() { bool AGOSEngine::processSpecialKeys() { bool verbCode = false; + if (getGameId() == GID_DIMP) { + static time_t lastMinute = 0; + time_t t; + time_t t1; + t = time(&t); + t1 = t / 30; + if (!lastMinute) + lastMinute = t1; + if (t1 - lastMinute) { + _variableArray[120] += (t1 - lastMinute); + lastMinute = t1; + } + } + switch (_keyPressed) { case 17: // Up if (getGameType() == GType_PP) @@ -575,10 +591,6 @@ bool AGOSEngine::processSpecialKeys() { if (_debugMode) _continousVgaScript ^= 1; break; - case 'i': - if (_debugMode) - _drawImagesDebug ^= 1; - break; case 'd': if (_debugMode) _dumpImages ^=1; diff --git a/engines/agos/module.mk b/engines/agos/module.mk index 5c3fd8496b..f9dcabb1db 100644 --- a/engines/agos/module.mk +++ b/engines/agos/module.mk @@ -8,9 +8,9 @@ MODULE_OBJS := \ cursor.o \ debug.o \ debugger.o \ + detection.o \ draw.o \ event.o \ - game.o \ gfx.o \ icons.o \ input.o \ diff --git a/engines/agos/oracle.cpp b/engines/agos/oracle.cpp index efed6c8d5b..9aa3a4bf87 100644 --- a/engines/agos/oracle.cpp +++ b/engines/agos/oracle.cpp @@ -31,7 +31,7 @@ namespace AGOS { -void AGOSEngine::checkLinkBox() { // Check for boxes spilling over to next row of text +void AGOSEngine_Feeble::checkLinkBox() { // Check for boxes spilling over to next row of text if (_hyperLink != 0) { _variableArray[52] = _textWindow->x + _textWindow->textColumn - _variableArray[50]; if (_variableArray[52] != 0) { @@ -43,7 +43,7 @@ void AGOSEngine::checkLinkBox() { // Check for boxes spilling over to next row o } } -void AGOSEngine::hyperLinkOn(uint16 x) { +void AGOSEngine_Feeble::hyperLinkOn(uint16 x) { if (!getBitFlag(51)) return; @@ -53,7 +53,7 @@ void AGOSEngine::hyperLinkOn(uint16 x) { } -void AGOSEngine::hyperLinkOff() { +void AGOSEngine_Feeble::hyperLinkOff() { if (!getBitFlag(51)) return; @@ -63,28 +63,117 @@ void AGOSEngine::hyperLinkOff() { _hyperLink = 0; } -void AGOSEngine::linksUp() { // Scroll Oracle Links +void AGOSEngine_Feeble::linksUp() { // Scroll Oracle Links uint16 j; for (j = 700; j < _variableArray[53]; j++) { moveBox(j, 0, -15); } } -void AGOSEngine::linksDown() { +void AGOSEngine_Feeble::linksDown() { uint16 i; for (i = 700; i < _variableArray[53]; i++) { moveBox(i,0, 15); } } -void AGOSEngine::scrollOracle() { +void AGOSEngine_Feeble::checkUp(WindowBlock *window) { + uint16 j, k; + + if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[31] > 52)) { + k = (((_variableArray[31] / 52) - 2) % 3); + j = k * 6; + if (!isBoxDead(j + 201)) { + uint index = getWindowNum(window); + drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask); + animate(4, 9, k + 34, 0, 0, 0); + } + } + if ((_variableArray[31] - _variableArray[30]) == 76) { + k = ((_variableArray[31] / 52) % 3); + j = k * 6; + if (isBoxDead(j + 201)) { + animate(4, 9, k + 31, 0, 0, 0); + undefineBox(j + 201); + undefineBox(j + 202); + undefineBox(j + 203); + undefineBox(j + 204); + undefineBox(j + 205); + undefineBox(j + 206); + } + _variableArray[31] -= 52; + _iOverflow = 1; + } +} + +void AGOSEngine_Feeble::inventoryUp(WindowBlock *window) { + _marks = 0; + checkUp(window); + animate(4, 9, 21, 0 ,0, 0); + while (1) { + if (_currentBox->id != 0x7FFB || !getBitFlag(89)) + break; + checkUp(window); + delay(1); + } + waitForMark(2); + checkUp(window); + sendSync(922); + waitForMark(1); + checkUp(window); +} + + +void AGOSEngine_Feeble::checkDown(WindowBlock *window) { + uint16 j, k; + + if (((_variableArray[31] - _variableArray[30]) == 24) && (_iOverflow == 1)) { + uint index = getWindowNum(window); + drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask); + k = ((_variableArray[31] / 52) % 3); + animate(4, 9, k + 25, 0, 0, 0); + _variableArray[31] += 52; + } + if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[30] > 52)) { + k = (((_variableArray[31] / 52) + 1) % 3); + j = k * 6; + if (isBoxDead(j + 201)) { + animate(4, 9, k + 28, 0, 0, 0); + undefineBox(j + 201); + undefineBox(j + 202); + undefineBox(j + 203); + undefineBox(j + 204); + undefineBox(j + 205); + undefineBox(j + 206); + } + } +} + +void AGOSEngine_Feeble::inventoryDown(WindowBlock *window) { + _marks = 0; + checkDown(window); + animate(4, 9, 23, 0, 0, 0); + while (1) { + if (_currentBox->id != 0x7FFC || !getBitFlag(89)) + break; + checkDown(window); + delay(1); + } + waitForMark(2); + checkDown(window); + sendSync(924); + waitForMark(1); + checkDown(window); +} + +void AGOSEngine_Feeble::scrollOracle() { int i; for (i = 0; i < 5; i++) scrollOracleUp(); } -void AGOSEngine::oracleTextUp() { +void AGOSEngine_Feeble::oracleTextUp() { Subroutine *sub; int i = 0; changeWindow(3); @@ -118,7 +207,7 @@ void AGOSEngine::oracleTextUp() { } } -void AGOSEngine::oracleTextDown() { +void AGOSEngine_Feeble::oracleTextDown() { Subroutine *sub; int i = 0; changeWindow(3); @@ -152,7 +241,7 @@ void AGOSEngine::oracleTextDown() { } } -void AGOSEngine::scrollOracleUp() { +void AGOSEngine_Feeble::scrollOracleUp() { byte *src, *dst; uint16 w, h; @@ -181,7 +270,7 @@ void AGOSEngine::scrollOracleUp() { } } -void AGOSEngine::scrollOracleDown() { +void AGOSEngine_Feeble::scrollOracleDown() { byte *src, *dst; uint16 w, h; @@ -209,7 +298,7 @@ void AGOSEngine::scrollOracleDown() { } } -void AGOSEngine::oracleLogo() { +void AGOSEngine_Feeble::oracleLogo() { Common::Rect srcRect, dstRect; byte *src, *dst; uint16 w, h; @@ -237,7 +326,7 @@ void AGOSEngine::oracleLogo() { } } -void AGOSEngine::swapCharacterLogo() { +void AGOSEngine_Feeble::swapCharacterLogo() { Common::Rect srcRect, dstRect; byte *src, *dst; uint16 w, h; @@ -277,7 +366,7 @@ void AGOSEngine::swapCharacterLogo() { } } -void AGOSEngine::listSaveGames(int n) { +void AGOSEngine_Feeble::listSaveGames(int n) { char b[108]; Common::InSaveFile *in; uint16 j, k, z, maxFiles; @@ -344,7 +433,7 @@ void AGOSEngine::listSaveGames(int n) { } } -void AGOSEngine::saveUserGame(int slot) { +void AGOSEngine_Feeble::saveUserGame(int slot) { WindowBlock *window; Common::InSaveFile *in; char name[108]; @@ -407,7 +496,7 @@ void AGOSEngine::saveUserGame(int slot) { } } -void AGOSEngine::windowBackSpace(WindowBlock *window) { +void AGOSEngine_Feeble::windowBackSpace(WindowBlock *window) { byte *dst; uint x, y, h, w; diff --git a/engines/agos/res_ami.cpp b/engines/agos/res_ami.cpp index 6e4675f063..713e1e1722 100644 --- a/engines/agos/res_ami.cpp +++ b/engines/agos/res_ami.cpp @@ -36,7 +36,7 @@ enum { static void uncompressPlane(const byte *plane, byte *outptr, int length) { while (length != 0) { int wordlen; - char x = *plane++; + signed char x = *plane++; if (x >= 0) { wordlen = MIN<int>(x + 1, length); uint16 w = READ_UINT16(plane); plane += 2; @@ -141,7 +141,7 @@ byte *AGOSEngine::convertImage(VC10_state *state, bool compressed) { } } - const byte *src = state->depack_src; + const byte *src = state->srcPtr; int width = state->width * 16; int height = state->height; diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp index 4f49ad6121..41c3dce075 100644 --- a/engines/agos/res_snd.cpp +++ b/engines/agos/res_snd.cpp @@ -152,6 +152,7 @@ void AGOSEngine::loadModule(uint music) { Common::MemoryReadStream stream(dstBuf, dstSize); audioStream = Audio::makeProtrackerStream(&stream, _mixer->getOutputRate()); + free(dstBuf); } else { audioStream = Audio::makeProtrackerStream(&f, _mixer->getOutputRate()); } @@ -380,6 +381,22 @@ static const char *dimpSoundList[32] = { }; +void AGOSEngine::loadSoundFile(const char* filename) { + File in; + + in.open(filename); + if (in.isOpen() == false) + error("loadSound: Can't load %s", filename); + + uint32 dstSize = in.size(); + byte *dst = (byte *)malloc(dstSize); + if (in.read(dst, dstSize) != dstSize) + error("loadSound: Read failed"); + in.close(); + + _sound->playSfxData(dst, 0, 0, 0); +} + void AGOSEngine::loadSound(uint sound, int pan, int vol, uint type) { byte *dst; diff --git a/engines/agos/rooms.cpp b/engines/agos/rooms.cpp index bd66d43722..3996b33839 100644 --- a/engines/agos/rooms.cpp +++ b/engines/agos/rooms.cpp @@ -158,7 +158,69 @@ Item *AGOSEngine::getExitOf_e1(Item *item, uint16 d) { return derefItem(x->parent); } -void AGOSEngine::moveDirn_e1(Item *i, uint x) { +void AGOSEngine_Waxworks::moveDirn(Item *i, uint x) { + Item *d; + uint16 n; + + if (i->parent == 0) + return; + + n = getExitOf(derefItem(i->parent), x); + if (derefItem(n) == NULL) { + loadRoomItems(n); + n = getExitOf(derefItem(i->parent), x); + } + + d = derefItem(n); + if (d) { + n = getDoorState(derefItem(i->parent), x); + if (n == 1) { + if (!canPlace(i, d)) + setItemParent(i, d); + } + } +} + +void AGOSEngine_Elvira2::moveDirn(Item *i, uint x) { + SubSuperRoom *sr; + Item *d, *p; + uint16 a, n; + + if (i->parent == 0) + return; + + p = derefItem(i->parent); + if (findChildOfType(p, 4)) { + n = getExitState(p, _superRoomNumber,x); + if (n == 1) { + sr = (SubSuperRoom *)findChildOfType(p, 4); + switch (x) { + case 0: a = -(sr->roomX); break; + case 1: a = 1; break; + case 2: a = sr->roomX; break; + case 3: a = 0xFFFF; break; + case 4: a = -(sr->roomX * sr->roomY); break; + case 5: a = (sr->roomX * sr->roomY); break; + default: return; + } + _superRoomNumber += a; + } + return; + } + + n = getExitOf(derefItem(i->parent), x); + + d = derefItem(n); + if (d) { + n = getDoorState(derefItem(i->parent), x); + if (n == 1) { + if (!canPlace(i, d)) + setItemParent(i, d); + } + } +} + +void AGOSEngine::moveDirn(Item *i, uint x) { Item *d, *p; p = derefItem(i->parent); @@ -189,7 +251,7 @@ void AGOSEngine::moveDirn_e1(Item *i, uint x) { } // Elvira 2 specific -int AGOSEngine::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) { +int AGOSEngine_Elvira2::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) { int b, bd; uint16 mask = 3; uint16 bs = s; @@ -250,7 +312,7 @@ int AGOSEngine::changeExitStates(SubSuperRoom *sr, int n, int d, uint16 s) { return 1; } -uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) { +uint16 AGOSEngine_Elvira2::getExitState(Item *i, uint16 x, uint16 d) { SubSuperRoom *sr; uint16 mask = 3; uint16 n; @@ -266,13 +328,13 @@ uint16 AGOSEngine::getExitState(Item *i, uint16 x, uint16 d) { return n; } -void AGOSEngine::setExitState(Item *i, uint16 n, uint16 d, uint16 s) { +void AGOSEngine_Elvira2::setExitState(Item *i, uint16 n, uint16 d, uint16 s) { SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(i, 4); if (sr) changeExitStates(sr, n, d, s); } -void AGOSEngine::setSRExit(Item *i, int n, int d, uint16 s) { +void AGOSEngine_Elvira2::setSRExit(Item *i, int n, int d, uint16 s) { uint16 mask = 3; SubSuperRoom *sr = (SubSuperRoom *)findChildOfType(i, 4); @@ -286,74 +348,8 @@ void AGOSEngine::setSRExit(Item *i, int n, int d, uint16 s) { } } -void AGOSEngine::moveDirn_e2(Item *i, uint x) { - SubSuperRoom *sr; - Item *d, *p; - uint16 a, n; - - if (i->parent == 0) - return; - - p = derefItem(i->parent); - if (findChildOfType(p, 4)) { - n = getExitState(p, _superRoomNumber,x); - if (n == 1) { - sr = (SubSuperRoom *)findChildOfType(p, 4); - switch (x) { - case 0: a = -(sr->roomX); break; - case 1: a = 1; break; - case 2: a = sr->roomX; break; - case 3: a = 0xFFFF; break; - case 4: a = -(sr->roomX * sr->roomY); break; - case 5: a = (sr->roomX * sr->roomY); break; - default: return; - } - _superRoomNumber += a; - } - return; - } - - n = getExitOf(derefItem(i->parent), x); - if (derefItem(n) == NULL) { - loadRoomItems(n); - n=getExitOf(derefItem(i->parent), x); - } - - d = derefItem(n); - if (d) { - n = getDoorState(derefItem(i->parent), x); - if (n == 1) { - if (!canPlace(i, d)) - setItemParent(i, d); - } - } -} - // Waxworks specific -void AGOSEngine::moveDirn_ww(Item *i, uint x) { - Item *d; - uint16 n; - - if (i->parent == 0) - return; - - n = getExitOf(derefItem(i->parent), x); - if (derefItem(n) == NULL) { - loadRoomItems(n); - n = getExitOf(derefItem(i->parent), x); - } - - d = derefItem(n); - if (d) { - n = getDoorState(derefItem(i->parent), x); - if (n == 1) { - if (!canPlace(i, d)) - setItemParent(i, d); - } - } -} - -bool AGOSEngine::loadRoomItems(uint item) { +bool AGOSEngine_Waxworks::loadRoomItems(uint item) { byte *p; uint i, min_num, max_num; char filename[30]; diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp index 0e82033ea2..de3a0f416a 100644 --- a/engines/agos/saveload.cpp +++ b/engines/agos/saveload.cpp @@ -54,59 +54,6 @@ int AGOSEngine::countSaveGames() { return i; } -int AGOSEngine::displaySaveGameList(int curpos, bool load, char *dst) { - int slot, last_slot; - Common::InSaveFile *in; - - showMessageFormat("\xC"); - - memset(dst, 0, 108); - - slot = curpos; - - while (curpos + 6 > slot) { - if (!(in = _saveFileMan->openForLoading(genSaveName(slot)))) - break; - - in->read(dst, 18); - delete in; - - last_slot = slot; - if (slot < 10) { - showMessageFormat(" "); - } else if (_language == Common::HB_ISR) { - last_slot = (slot % 10) * 10; - last_slot += slot / 10; - } - - if (_language == Common::HB_ISR && !(slot % 10)) - showMessageFormat("0"); - showMessageFormat("%d", last_slot); - showMessageFormat(".%s\n", dst); - dst += 18; - slot++; - } - // while_break - if (!load) { - if (curpos + 6 == slot) - slot++; - else { - if (slot < 10) - showMessageFormat(" "); - showMessageFormat("%d.\n", slot); - } - } else { - if (curpos + 6 == slot) { - if ((in = _saveFileMan->openForLoading(genSaveName(slot)))) { - slot++; - delete in; - } - } - } - - return slot - curpos; -} - char *AGOSEngine::genSaveName(int slot) { static char buf[15]; @@ -118,15 +65,21 @@ char *AGOSEngine::genSaveName(int slot) { sprintf(buf, "feeble.%.3d", slot); } else if (getGameType() == GType_SIMON2) { sprintf(buf, "simon2.%.3d", slot); - } else { + } else if (getGameType() == GType_SIMON1) { sprintf(buf, "simon1.%.3d", slot); + } else if (getGameType() == GType_WW) { + sprintf(buf, "waxworks.%.3d", slot); + } else if (getGameType() == GType_ELVIRA2) { + sprintf(buf, "elvira2.%.3d", slot); + } else if (getGameType() == GType_ELVIRA1) { + sprintf(buf, "elvira1.%.3d", slot); } return buf; } void AGOSEngine::quickLoadOrSave() { // Quick load & save is only supported complete version of Simon the Sorcerer 1/2 - if (getGameType() != GType_SIMON1 && getGameType() != GType_SIMON2 || + if (getGameType() == GType_PP || getGameType() == GType_FF || (getFeatures() & GF_DEMO)) { return; } @@ -140,15 +93,36 @@ void AGOSEngine::quickLoadOrSave() { success = loadGame(genSaveName(_saveLoadSlot)); if (!success) { sprintf(buf, "Failed to load game state to file:\n\n%s", filename); - } else { - // Redraw Inventory - mouseOff(); + } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { drawIconArray(2, me(), 0, 0); - mouseOn(); - // Reset engine? setBitFlag(97, true); sub = getSubroutineByID(100); startSubroutine(sub); + } else if (getGameType() == GType_WW) { + sub = getSubroutineByID(66); + startSubroutine(sub); + } else if (getGameType() == GType_ELVIRA2) { + sub = getSubroutineByID(87); + startSubroutine(sub); + setBitFlag(7, false); + sub = getSubroutineByID(19); + startSubroutine(sub); + //oe2_printStats(); + sub = getSubroutineByID(28); + startSubroutine(sub); + setBitFlag(17, false); + sub = getSubroutineByID(207); + startSubroutine(sub); + sub = getSubroutineByID(71); + startSubroutine(sub); + } else if (getGameType() == GType_ELVIRA1) { + drawIconArray(2, me(), 0, 0); + sub = getSubroutineByID(265); + startSubroutine(sub); + sub = getSubroutineByID(129); + startSubroutine(sub); + sub = getSubroutineByID(131); + startSubroutine(sub); } } else { success = saveGame(_saveLoadSlot, _saveLoadName); @@ -170,15 +144,255 @@ void AGOSEngine::quickLoadOrSave() { _saveLoadType = 0; } -void AGOSEngine::listSaveGames(char *buf) { - int i; +void AGOSEngine::listSaveGames(char *dst) { + Common::InSaveFile *in; + uint y, slot; + + const uint8 num = (getGameType() == GType_WW) ? 3 : 4; + + disableFileBoxes(); + + WindowBlock *window = _windowArray[num]; + window->textRow = 0; + window->textColumn = 0; + window->textColumnOffset = 4; + + windowPutChar(window, 12); + + memset(dst, 0, 200); + + slot = _saveLoadRowCurPos; + for (y = 0; y < 8; y++) { + window->textColumn = 0; + window->textColumnOffset = 4; + window->textLength = 0; + if ((in = _saveFileMan->openForLoading(genSaveName(slot++)))) { + in->read(dst, 8); + delete in; + + const char *name = dst; + for (; *name; name++) + windowPutChar(window, *name); + + enableBox(200 + y * 3 + 0); + } + dst+= 8; + + window->textColumn = 7; + window->textColumnOffset = 4; + window->textLength = 0; + if ((in = _saveFileMan->openForLoading(genSaveName(slot++)))) { + in->read(dst, 8); + delete in; + + const char *name = dst; + for (; *name; name++) + windowPutChar(window, *name); + + enableBox(200 + y * 3 + 1); + } + dst+= 8; + + window->textColumn = 15; + window->textColumnOffset = 4; + window->textLength = 0; + if ((in = _saveFileMan->openForLoading(genSaveName(slot++)))) { + in->read(dst, 8); + delete in; + + const char *name = dst; + for (; *name; name++) + windowPutChar(window, *name); + + enableBox(200 + y * 3 + 2); + } + dst+= 8; + + windowPutChar(window, 13); + } + + window->textRow = 9; + window->textColumn = 0; + window->textColumnOffset = 4; + window->textLength = 0; + + _saveGameNameLen = 0; +} + +void AGOSEngine::userGame(bool load) { + time_t saveTime; + int i, numSaveGames; + char *name; + bool b; + char buf[200]; + + _saveOrLoad = load; + + saveTime = time(NULL); + + if (getGameType() == GType_ELVIRA2) + haltAnimation(); + + numSaveGames = countSaveGames(); + _numSaveGameRows = numSaveGames; + _saveLoadRowCurPos = 1; + _saveLoadEdit = false; + + const uint8 num = (getGameType() == GType_WW) ? 3 : 4; + + listSaveGames(buf); + + if (!load) { + WindowBlock *window = _windowArray[num]; + name = buf + 192; + + for (;;) { + windowPutChar(window, 127); + + _saveLoadEdit = true; + + i = userGameGetKey(&b, buf, 128); + if (b) { + if (i <= 223) { + if (getGameType() == GType_WW) { + Subroutine *sub = getSubroutineByID(80); + if (sub != NULL) + startSubroutineEx(sub); + + if (_variableArray[253] != 0) { + listSaveGames(buf); + continue; + } + } + + if (!saveGame(_saveLoadRowCurPos + i, buf + i * 8)) + fileError(_windowArray[num], true); + } + + goto get_out; + } + userGameBackSpace(_windowArray[num], 8); + if (i == 10 || i == 13) + break; + if (i == 8) { + // do_backspace + if (_saveGameNameLen) { + _saveGameNameLen--; + name[_saveGameNameLen] = 0; + userGameBackSpace(_windowArray[num], 8); + } + } else if (i >= 32 && _saveGameNameLen != 8) { + name[_saveGameNameLen++] = i; + windowPutChar(_windowArray[num], i); + } + } + + if (!saveGame(numSaveGames, buf + 192)) + fileError(_windowArray[num], true); + } else { + i = userGameGetKey(&b, buf, 128); + if (i != 225) { + if (!loadGame(genSaveName(_saveLoadRowCurPos + i))) + fileError(_windowArray[num], false); + } + } + +get_out:; disableFileBoxes(); - i = displaySaveGameList(_saveLoadRowCurPos, _saveOrLoad, buf); + _gameStoppedClock = time(NULL) - saveTime + _gameStoppedClock; + + if (getGameType() == GType_ELVIRA2) + restartAnimation(); +} + +int AGOSEngine::userGameGetKey(bool *b, char *buf, uint maxChar) { + HitArea *ha; + *b = true; + + _keyPressed = 0; + + for (;;) { + _lastHitArea = NULL; + _lastHitArea3 = NULL; + + do { + if (_saveLoadEdit && _keyPressed && _keyPressed < maxChar) { + *b = false; + return _keyPressed; + } + delay(10); + } while (_lastHitArea3 == 0); + + ha = _lastHitArea; + if (ha == NULL || ha->id < 200) { + } else if (ha->id == 225) { + return ha->id; + } else if (ha->id == 224) { + _saveGameNameLen = 0; + _saveLoadRowCurPos += 24; + if (_saveLoadRowCurPos >= _numSaveGameRows) + _saveLoadRowCurPos = 1; + + listSaveGames(buf); + } else if (ha->id < 224) { + return ha->id - 200; + } + } +} + +void AGOSEngine_Simon1::listSaveGames(char *dst) { + Common::InSaveFile *in; + uint i, slot, lastSlot; + + disableFileBoxes(); + + showMessageFormat("\xC"); + + memset(dst, 0, 108); + + slot = _saveLoadRowCurPos; + while (_saveLoadRowCurPos + 6 > slot) { + if (!(in = _saveFileMan->openForLoading(genSaveName(slot)))) + break; + + in->read(dst, 8); + delete in; + + lastSlot = slot; + if (slot < 10) { + showMessageFormat(" "); + } + + if (_language == Common::HB_ISR && !(slot % 10)) + showMessageFormat("0"); + showMessageFormat("%d", lastSlot); + showMessageFormat(".%s\n", dst); + dst += 18; + slot++; + } + + if (!_saveOrLoad) { + if (_saveLoadRowCurPos + 6 == slot) + slot++; + else { + if (slot < 10) + showMessageFormat(" "); + showMessageFormat("%d.\n", slot); + } + } else { + if (_saveLoadRowCurPos + 6 == slot) { + if ((in = _saveFileMan->openForLoading(genSaveName(slot)))) { + slot++; + delete in; + } + } + } _saveDialogFlag = true; + i = slot - _saveLoadRowCurPos; if (i != 7) { i++; if (!_saveOrLoad) @@ -194,7 +408,6 @@ void AGOSEngine::listSaveGames(char *buf) { } while (--i); } - const byte hebrewKeyTable[96] = { 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 90, 45, 85, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 83, 83, 90, 61, 85, 63, 35, 89, 80, 65, 66, 87, @@ -204,10 +417,9 @@ const byte hebrewKeyTable[96] = { 123, 124, 125, 126, 127, }; -void AGOSEngine::userGame(bool load) { - time_t save_time; - int number_of_savegames; - int i, name_len, result; +void AGOSEngine_Simon1::userGame(bool load) { + time_t saveTime; + int i, numSaveGames, result; WindowBlock *window; char *name; bool b; @@ -216,29 +428,25 @@ void AGOSEngine::userGame(bool load) { _saveOrLoad = load; - save_time = time(NULL); - - _copyPartialMode = 1; + saveTime = time(NULL); - number_of_savegames = countSaveGames(); + numSaveGames = countSaveGames(); if (!load) - number_of_savegames++; - number_of_savegames -= 6; - if (number_of_savegames < 0) - number_of_savegames = 0; - number_of_savegames++; - _numSaveGameRows = number_of_savegames; + numSaveGames++; + numSaveGames -= 6; + if (numSaveGames < 0) + numSaveGames = 0; + numSaveGames++; + _numSaveGameRows = numSaveGames; _saveLoadRowCurPos = 1; if (!load) - _saveLoadRowCurPos = number_of_savegames; + _saveLoadRowCurPos = numSaveGames; _saveLoadEdit = false; restart:; - do { - i = userGameGetKey(&b, buf); - } while (!b); + i = userGameGetKey(&b, buf, maxChar); if (i == 205) goto get_out; @@ -258,22 +466,21 @@ restart:; if (_language == Common::HB_ISR) { window->textColumn = 3; window->textColumnOffset = 6; - window->textLength = 3; } else { window->textColumn = 2; window->textColumnOffset = 2; - window->textLength = 3; } + window->textLength = 3; name = buf + i * 18; // now process entire savegame name to get correct x offset for cursor - name_len = 0; - while (name[name_len]) { + _saveGameNameLen = 0; + while (name[_saveGameNameLen]) { if (_language == Common::HB_ISR) { byte width = 6; - if (name[name_len] >= 64 && name[name_len] < 91) - width = _hebrewCharWidths [name[name_len] - 64]; + if (name[_saveGameNameLen] >= 64 && name[_saveGameNameLen] < 91) + width = _hebrewCharWidths [name[_saveGameNameLen] - 64]; window->textLength++; window->textColumnOffset -= width; if (window->textColumnOffset < width) { @@ -283,43 +490,37 @@ restart:; } else { window->textLength++; window->textColumnOffset += 6; - if (name[name_len] == 'i' || name[name_len] == 'l') + if (name[_saveGameNameLen] == 'i' || name[_saveGameNameLen] == 'l') window->textColumnOffset -= 2; if (window->textColumnOffset >= 8) { window->textColumnOffset -= 8; window->textColumn++; } } - name_len++; + _saveGameNameLen++; } - // while_1_end - // do_3_start for (;;) { - windowPutChar(window, 0x7f); + windowPutChar(window, 127); _saveLoadEdit = true; - // do_2 - do { - i = userGameGetKey(&b, buf); + i = userGameGetKey(&b, buf, maxChar); - if (b) { - if (i == 205) - goto get_out; - enableBox(208 + result); - if (_saveLoadEdit) { - userGameBackSpace(_windowArray[5], 8); - } - goto if_1; + if (b) { + if (i == 205) + goto get_out; + enableBox(208 + result); + if (_saveLoadEdit) { + userGameBackSpace(_windowArray[5], 8); } + goto if_1; + } - // is_not_b - if (!_saveLoadEdit) { - enableBox(208 + result); - goto restart; - } - } while (i >= maxChar || i == 0); + if (!_saveLoadEdit) { + enableBox(208 + result); + goto restart; + } if (_language == Common::HB_ISR) { if (i >= 128) @@ -328,36 +529,33 @@ restart:; i = hebrewKeyTable[i - 32]; } - // after_do_2 userGameBackSpace(_windowArray[5], 8); if (i == 10 || i == 13) break; if (i == 8) { // do_backspace - if (name_len != 0) { - int x; - byte m; + if (_saveGameNameLen) { + byte m, x; - name_len--; - m = name[name_len]; + _saveGameNameLen--; + m = name[_saveGameNameLen]; if (_language == Common::HB_ISR) x = 8; else - x = (name[name_len] == 'i' || name[name_len] == 'l') ? 1 : 8; + x = (name[_saveGameNameLen] == 'i' || name[_saveGameNameLen] == 'l') ? 1 : 8; - name[name_len] = 0; + name[_saveGameNameLen] = 0; userGameBackSpace(_windowArray[5], x, m); } - } else if (i >= 32 && name_len != 17) { - name[name_len++] = i; + } else if (i >= 32 && _saveGameNameLen != 17) { + name[_saveGameNameLen++] = i; windowPutChar(_windowArray[5], i); } } - // do_save if (!saveGame(_saveLoadRowCurPos + result, buf + result * 18)) fileError(_windowArray[5], true); } else { @@ -368,18 +566,10 @@ restart:; get_out:; disableFileBoxes(); - _gameStoppedClock = time(NULL) - save_time + _gameStoppedClock; - _copyPartialMode = 0; - - restoreBlock(94, 208, 46, 80); - - i = _timer4; - do { - delay(10); - } while (i == _timer4); + _gameStoppedClock = time(NULL) - saveTime + _gameStoppedClock; } -int AGOSEngine::userGameGetKey(bool *b, char *buf) { +int AGOSEngine_Simon1::userGameGetKey(bool *b, char *buf, uint maxChar) { HitArea *ha; *b = true; @@ -394,7 +584,7 @@ int AGOSEngine::userGameGetKey(bool *b, char *buf) { _lastHitArea3 = NULL; do { - if (_saveLoadEdit && _keyPressed != 0) { + if (_saveLoadEdit && _keyPressed && _keyPressed < maxChar) { *b = false; return _keyPressed; } @@ -431,8 +621,15 @@ int AGOSEngine::userGameGetKey(bool *b, char *buf) { } void AGOSEngine::disableFileBoxes() { - for (int i = 208; i != 214; i++) - disableBox(i); + int i; + + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + for (i = 208; i != 214; i++) + disableBox(i); + } else { + for (i = 200; i != 224; i++) + disableBox(i); + } } void AGOSEngine::userGameBackSpace(WindowBlock *window, int x, byte b) { @@ -556,7 +753,8 @@ void writeItemID(Common::WriteStream *f, uint16 val) { f->writeUint32BE(val - 1); } -bool AGOSEngine::loadGame_e1(const char *filename, bool restartMode) { +bool AGOSEngine::loadGame(const char *filename, bool restartMode) { + char ident[100]; Common::SeekableReadStream *f = NULL; uint num, item_index, i; @@ -576,6 +774,10 @@ bool AGOSEngine::loadGame_e1(const char *filename, bool restartMode) { return false; } + if (!restartMode) { + f->read(ident, 8); + } + num = f->readUint32BE(); if (f->readUint32BE() != 0xFFFFFFFF || num != _itemArrayInited - 1) { @@ -648,7 +850,7 @@ bool AGOSEngine::loadGame_e1(const char *filename, bool restartMode) { return true; } -bool AGOSEngine::saveGame_e1(const char *filename) { +bool AGOSEngine::saveGame(uint slot, const char *caption) { Common::OutSaveFile *f; uint item_index, num_item, i; TimeEvent *te; @@ -657,13 +859,15 @@ bool AGOSEngine::saveGame_e1(const char *filename) { _lockWord |= 0x100; - f = _saveFileMan->openForSaving(filename); + f = _saveFileMan->openForSaving(genSaveName(slot)); if (f == NULL) { - warning("saveGame: Failed to save %s", filename); + warning("saveGame: Failed to save slot %d", slot); _lockWord &= ~0x100; return false; } + f->write(caption, 8); + f->writeUint32BE(_itemArrayInited - 1); f->writeUint32BE(0xFFFFFFFF); f->writeUint32BE(0); @@ -726,7 +930,7 @@ bool AGOSEngine::saveGame_e1(const char *filename) { return result; } -bool AGOSEngine::loadGame(const char *filename, bool restartMode) { +bool AGOSEngine_Elvira2::loadGame(const char *filename, bool restartMode) { char ident[100]; Common::SeekableReadStream *f = NULL; uint num, item_index, i, j; @@ -752,6 +956,8 @@ bool AGOSEngine::loadGame(const char *filename, bool restartMode) { f->read(ident, 100); } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { f->read(ident, 18); + } else if (!restartMode) { + f->read(ident, 8); } num = f->readUint32BE(); @@ -872,7 +1078,7 @@ bool AGOSEngine::loadGame(const char *filename, bool restartMode) { return true; } -bool AGOSEngine::saveGame(uint slot, const char *caption) { +bool AGOSEngine_Elvira2::saveGame(uint slot, const char *caption) { Common::OutSaveFile *f; uint item_index, num_item, i, j; TimeEvent *te; @@ -893,6 +1099,8 @@ bool AGOSEngine::saveGame(uint slot, const char *caption) { curTime = time(NULL); } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { f->write(caption, 18); + } else { + f->write(caption, 8); } f->writeUint32BE(_itemArrayInited - 1); diff --git a/engines/agos/script.cpp b/engines/agos/script.cpp index 99f639474d..9961a3ff0b 100644 --- a/engines/agos/script.cpp +++ b/engines/agos/script.cpp @@ -36,140 +36,8 @@ extern bool isSmartphone(void); namespace AGOS { -void AGOSEngine::setupCommonOpcodes(OpcodeProc *op) { - // A common set of opcodes for Elvira 2 and later. - - op[1] = &AGOSEngine::o_at; - op[2] = &AGOSEngine::o_notAt; - op[5] = &AGOSEngine::o_carried; - op[6] = &AGOSEngine::o_notCarried; - op[7] = &AGOSEngine::o_isAt; - op[11] = &AGOSEngine::o_zero; - op[12] = &AGOSEngine::o_notZero; - op[13] = &AGOSEngine::o_eq; - op[14] = &AGOSEngine::o_notEq; - op[15] = &AGOSEngine::o_gt; - op[16] = &AGOSEngine::o_lt; - op[17] = &AGOSEngine::o_eqf; - op[18] = &AGOSEngine::o_notEqf; - op[19] = &AGOSEngine::o_ltf; - op[20] = &AGOSEngine::o_gtf; - op[23] = &AGOSEngine::o_chance; - op[25] = &AGOSEngine::o_isRoom; - op[26] = &AGOSEngine::o_isObject; - op[27] = &AGOSEngine::o_state; - op[28] = &AGOSEngine::o_oflag; - op[31] = &AGOSEngine::o_destroy; - op[33] = &AGOSEngine::o_place; - op[36] = &AGOSEngine::o_copyff; - op[41] = &AGOSEngine::o_clear; - op[42] = &AGOSEngine::o_let; - op[43] = &AGOSEngine::o_add; - op[44] = &AGOSEngine::o_sub; - op[45] = &AGOSEngine::o_addf; - op[46] = &AGOSEngine::o_subf; - op[47] = &AGOSEngine::o_mul; - op[48] = &AGOSEngine::o_div; - op[49] = &AGOSEngine::o_mulf; - op[50] = &AGOSEngine::o_divf; - op[51] = &AGOSEngine::o_mod; - op[52] = &AGOSEngine::o_modf; - op[53] = &AGOSEngine::o_random; - op[55] = &AGOSEngine::o_goto; - op[56] = &AGOSEngine::o_oset; - op[57] = &AGOSEngine::o_oclear; - op[58] = &AGOSEngine::o_putBy; - op[59] = &AGOSEngine::o_inc; - op[60] = &AGOSEngine::o_dec; - op[61] = &AGOSEngine::o_setState; - op[62] = &AGOSEngine::o_print; - op[63] = &AGOSEngine::o_message; - op[64] = &AGOSEngine::o_msg; - op[68] = &AGOSEngine::o_end; - op[69] = &AGOSEngine::o_done; - op[71] = &AGOSEngine::o_process; - op[76] = &AGOSEngine::o_when; - op[77] = &AGOSEngine::o_if1; - op[78] = &AGOSEngine::o_if2; - op[79] = &AGOSEngine::o_isCalled; - op[80] = &AGOSEngine::o_is; - op[82] = &AGOSEngine::o_debug; - op[87] = &AGOSEngine::o_comment; - op[90] = &AGOSEngine::o_getParent; - op[91] = &AGOSEngine::o_getNext; - op[92] = &AGOSEngine::o_getChildren; - op[96] = &AGOSEngine::o_picture; - op[97] = &AGOSEngine::o_loadZone; - op[100] = &AGOSEngine::o_killAnimate; - op[101] = &AGOSEngine::o_defWindow; - op[102] = &AGOSEngine::o_window; - op[103] = &AGOSEngine::o_cls; - op[104] = &AGOSEngine::o_closeWindow; - op[107] = &AGOSEngine::o_addBox; - op[108] = &AGOSEngine::o_delBox; - op[109] = &AGOSEngine::o_enableBox; - op[110] = &AGOSEngine::o_disableBox; - op[111] = &AGOSEngine::o_moveBox; - op[114] = &AGOSEngine::o_doIcons; - op[115] = &AGOSEngine::o_isClass; - op[116] = &AGOSEngine::o_setClass; - op[117] = &AGOSEngine::o_unsetClass; - op[119] = &AGOSEngine::o_waitSync; - op[120] = &AGOSEngine::o_sync; - op[121] = &AGOSEngine::o_defObj; - op[125] = &AGOSEngine::o_here; - op[126] = &AGOSEngine::o_doClassIcons; - op[130] = &AGOSEngine::o_setAdjNoun; - op[132] = &AGOSEngine::o_saveUserGame; - op[133] = &AGOSEngine::o_loadUserGame; - op[136] = &AGOSEngine::o_copysf; - op[137] = &AGOSEngine::o_restoreIcons; - op[138] = &AGOSEngine::o_freezeZones; - op[139] = &AGOSEngine::o_placeNoIcons; - op[140] = &AGOSEngine::o_clearTimers; - op[141] = &AGOSEngine::o_setDollar; - op[142] = &AGOSEngine::o_isBox; - op[143] = &AGOSEngine::oe2_doTable; - op[151] = &AGOSEngine::oe2_storeItem; - op[152] = &AGOSEngine::oe2_getItem; - op[153] = &AGOSEngine::oe2_bSet; - op[154] = &AGOSEngine::oe2_bClear; - op[155] = &AGOSEngine::oe2_bZero; - op[156] = &AGOSEngine::oe2_bNotZero; - op[157] = &AGOSEngine::oe2_getOValue; - op[158] = &AGOSEngine::oe2_setOValue; - op[160] = &AGOSEngine::oe2_ink; -} - void AGOSEngine::setupOpcodes() { - memset(_opcode_table, 0, sizeof(_opcode_table)); - _numOpcodes = ARRAYSIZE(_opcode_table); - - switch (getGameType()) { - case GType_ELVIRA1: - setupElvira1Opcodes(_opcode_table); - break; - case GType_ELVIRA2: - setupElvira2Opcodes(_opcode_table); - break; - case GType_WW: - setupWaxworksOpcodes(_opcode_table); - break; - case GType_SIMON1: - setupSimon1Opcodes(_opcode_table); - break; - case GType_SIMON2: - setupSimon2Opcodes(_opcode_table); - break; - case GType_FF: - setupFeebleOpcodes(_opcode_table); - break; - case GType_PP: - setupPuzzleOpcodes(_opcode_table); - break; - default: - error("setupOpcodes: Unknown game"); - } + error("setupOpcodes: Unknown game"); } void AGOSEngine::setScriptCondition(bool cond) { @@ -192,6 +60,10 @@ int AGOSEngine::getScriptReturn() { // Common Opcodes // ----------------------------------------------------------------------- +void AGOSEngine::o_invalid() { + error("Invalid opcode %d", _opcode); +} + void AGOSEngine::o_at() { // 1: ptrA parent is setScriptCondition(me()->parent == getNextItemID()); @@ -575,6 +447,18 @@ void AGOSEngine::o_comment() { void AGOSEngine::o_haltAnimation() { // 88: stop animation _lockWord |= 0x10; + + if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { + VgaTimerEntry *vte = _vgaTimerList; + while (vte->delay) { + if (vte->type == 0) + vte->delay += 10; + vte++; + } + + _scrollCount = 0; + _scrollFlag = 0; + } } void AGOSEngine::o_restartAnimation() { @@ -639,6 +523,13 @@ void AGOSEngine::o_loadZone() { } loadZone(vga_res); + + if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || + getGameType() == GType_WW) { + _copyScnFlag = 0; + _vgaSpriteChanged = 0; + } + _lockWord &= ~0x80; } @@ -827,6 +718,18 @@ void AGOSEngine::o_doClassIcons() { mouseOn(); } +void AGOSEngine::o_playTune() { + // 127: play tune + int music = getVarOrWord(); + int track = getVarOrWord(); + + if (music != _lastMusicPlayed) { + _lastMusicPlayed = music; + loadMusic(music); + _midi.startTrack(track); + } +} + void AGOSEngine::o_setAdjNoun() { // 130: set adj noun uint var = getVarOrByte(); @@ -998,7 +901,6 @@ void AGOSEngine::writeVariable(uint variable, uint16 contents) { } int AGOSEngine::runScript() { - int opcode; bool flag; do { @@ -1006,12 +908,12 @@ int AGOSEngine::runScript() { dumpOpcode(_codePtr); if (getGameType() == GType_ELVIRA1) { - opcode = getVarOrWord(); - if (opcode == 10000) + _opcode = getVarOrWord(); + if (_opcode == 10000) return 0; } else { - opcode = getByte(); - if (opcode == 0xFF) + _opcode = getByte(); + if (_opcode == 0xFF) return 0; } @@ -1021,17 +923,17 @@ int AGOSEngine::runScript() { /* Invert condition? */ flag = false; if (getGameType() == GType_ELVIRA1) { - if (opcode == 203) { + if (_opcode == 203) { flag = true; - opcode = getVarOrWord(); - if (opcode == 10000) + _opcode = getVarOrWord(); + if (_opcode == 10000) return 0; } } else { - if (opcode == 0) { + if (_opcode == 0) { flag = true; - opcode = getByte(); - if (opcode == 0xFF) + _opcode = getByte(); + if (_opcode == 0xFF) return 0; } } @@ -1039,10 +941,10 @@ int AGOSEngine::runScript() { setScriptCondition(true); setScriptReturn(0); - if (opcode > _numOpcodes || !_opcode_table[opcode]) - error("Invalid opcode '%d' encountered", opcode); + if (_opcode > _numOpcodes) + error("Invalid opcode '%d' encountered", _opcode); - (this->*_opcode_table[opcode]) (); + executeOpcode(_opcode); } while (getScriptCondition() != flag && !getScriptReturn()); return getScriptReturn(); diff --git a/engines/agos/script_e1.cpp b/engines/agos/script_e1.cpp index 3cbc168c80..105f4ba16b 100644 --- a/engines/agos/script_e1.cpp +++ b/engines/agos/script_e1.cpp @@ -28,169 +28,393 @@ namespace AGOS { -void AGOSEngine::setupElvira1Opcodes(OpcodeProc *op) { - op[0] = &AGOSEngine::o_at; - op[1] = &AGOSEngine::o_notAt; - op[2] = &AGOSEngine::oe1_present; - op[3] = &AGOSEngine::oe1_notPresent; - op[4] = &AGOSEngine::oe1_worn; - op[5] = &AGOSEngine::oe1_notWorn; - op[6] = &AGOSEngine::o_carried; - op[7] = &AGOSEngine::o_notCarried; - op[8] = &AGOSEngine::o_isAt; - op[9] = &AGOSEngine::oe1_isNotAt; - op[10] = &AGOSEngine::oe1_sibling; - op[11] = &AGOSEngine::oe1_notSibling; - op[12] = &AGOSEngine::o_zero; - op[13] = &AGOSEngine::o_notZero; - op[14] = &AGOSEngine::o_eq; - op[15] = &AGOSEngine::o_notEq; - op[16] = &AGOSEngine::o_gt; - op[17] = &AGOSEngine::o_lt; - op[18] = &AGOSEngine::o_eqf; - op[19] = &AGOSEngine::o_notEqf; - op[20] = &AGOSEngine::o_ltf; - op[21] = &AGOSEngine::o_gtf; - op[22] = &AGOSEngine::oe1_isIn; - op[23] = &AGOSEngine::oe1_isNotIn; - op[29] = &AGOSEngine::o_chance; - op[30] = &AGOSEngine::oe1_isPlayer; - op[32] = &AGOSEngine::o_isRoom; - op[33] = &AGOSEngine::o_isObject; - op[34] = &AGOSEngine::o_state; - op[36] = &AGOSEngine::o_oflag; - op[37] = &AGOSEngine::oe1_canPut; - op[47] = &AGOSEngine::oe1_create; - op[48] = &AGOSEngine::o_destroy; - op[51] = &AGOSEngine::o_place; - op[54] = &AGOSEngine::oe1_copyof; - op[55] = &AGOSEngine::oe1_copyfo; - op[56] = &AGOSEngine::o_copyff; - op[57] = &AGOSEngine::oe1_whatO; - op[59] = &AGOSEngine::oe1_weigh; - op[60] = &AGOSEngine::oe1_setFF; - op[61] = &AGOSEngine::o_clear; - op[64] = &AGOSEngine::o_let; - op[65] = &AGOSEngine::o_add; - op[66] = &AGOSEngine::o_sub; - op[67] = &AGOSEngine::o_addf; - op[68] = &AGOSEngine::o_subf; - op[69] = &AGOSEngine::o_mul; - op[70] = &AGOSEngine::o_div; - op[71] = &AGOSEngine::o_mulf; - op[72] = &AGOSEngine::o_divf; - op[73] = &AGOSEngine::o_mod; - op[74] = &AGOSEngine::o_modf; - op[75] = &AGOSEngine::o_random; - op[76] = &AGOSEngine::oe1_moveDirn; - op[77] = &AGOSEngine::o_goto; - op[80] = &AGOSEngine::o_oset; - op[81] = &AGOSEngine::o_oclear; - op[84] = &AGOSEngine::o_putBy; - op[85] = &AGOSEngine::o_inc; - op[86] = &AGOSEngine::o_dec; - op[87] = &AGOSEngine::o_setState; - op[89] = &AGOSEngine::o_print; - op[90] = &AGOSEngine::oe1_score; - op[91] = &AGOSEngine::o_message; - op[92] = &AGOSEngine::o_msg; - op[96] = &AGOSEngine::oe1_look; - op[97] = &AGOSEngine::o_end; - op[98] = &AGOSEngine::o_done; - op[105] = &AGOSEngine::o_process; - op[106] = &AGOSEngine::oe1_doClass; - op[112] = &AGOSEngine::oe1_pObj; - op[114] = &AGOSEngine::oe1_pName; - op[115] = &AGOSEngine::oe1_pcName; - op[119] = &AGOSEngine::o_when; - op[128] = &AGOSEngine::o_if1; - op[129] = &AGOSEngine::o_if2; - op[135] = &AGOSEngine::oe1_isCalled; - op[136] = &AGOSEngine::o_is; - op[152] = &AGOSEngine::o_debug; - op[162] = &AGOSEngine::oe1_cFlag; - op[164] = &AGOSEngine::oe1_rescan; - op[176] = &AGOSEngine::oe1_setUserItem; - op[177] = &AGOSEngine::oe1_getUserItem; - op[178] = &AGOSEngine::oe1_clearUserItem; - op[180] = &AGOSEngine::oe1_whereTo; - op[181] = &AGOSEngine::oe1_doorExit; - op[198] = &AGOSEngine::o_comment; - op[201] = &AGOSEngine::oe1_saveGame; - op[202] = &AGOSEngine::oe1_loadGame; - op[206] = &AGOSEngine::o_getParent; - op[207] = &AGOSEngine::o_getNext; - op[208] = &AGOSEngine::o_getChildren; - op[219] = &AGOSEngine::oe1_findMaster; - op[220] = &AGOSEngine::oe1_nextMaster; - op[224] = &AGOSEngine::o_picture; - op[225] = &AGOSEngine::o_loadZone; - op[226] = &AGOSEngine::oe1_animate; - op[227] = &AGOSEngine::oe1_stopAnimate; - op[228] = &AGOSEngine::o_killAnimate; - op[229] = &AGOSEngine::o_defWindow; - op[230] = &AGOSEngine::o_window; - op[231] = &AGOSEngine::o_cls; - op[232] = &AGOSEngine::o_closeWindow; - op[233] = &AGOSEngine::oe1_menu; - op[235] = &AGOSEngine::o_addBox; - op[236] = &AGOSEngine::o_delBox; - op[237] = &AGOSEngine::o_enableBox; - op[238] = &AGOSEngine::o_disableBox; - op[239] = &AGOSEngine::o_moveBox; - op[242] = &AGOSEngine::o_doIcons; - op[243] = &AGOSEngine::o_isClass; - op[249] = &AGOSEngine::o_setClass; - op[250] = &AGOSEngine::o_unsetClass; - op[251] = &AGOSEngine::oe1_bitClear; - op[252] = &AGOSEngine::oe1_bitSet; - op[253] = &AGOSEngine::oe1_bitTest; - op[255] = &AGOSEngine::o_waitSync; - op[256] = &AGOSEngine::o_sync; - op[257] = &AGOSEngine::o_defObj; - op[258] = &AGOSEngine::oe1_enableInput; - op[259] = &AGOSEngine::oe1_setTime; - op[260] = &AGOSEngine::oe1_ifTime; - op[261] = &AGOSEngine::o_here; - op[262] = &AGOSEngine::o_doClassIcons; - op[263] = &AGOSEngine::oe1_playTune; - op[266] = &AGOSEngine::o_setAdjNoun; - op[267] = &AGOSEngine::oe1_zoneDisk; - op[268] = &AGOSEngine::o_saveUserGame; - op[269] = &AGOSEngine::o_loadUserGame; - op[270] = &AGOSEngine::oe1_printStats; - op[271] = &AGOSEngine::oe1_stopTune; - op[272] = &AGOSEngine::oe1_printPlayerDamage; - op[273] = &AGOSEngine::oe1_printMonsterDamage; - op[274] = &AGOSEngine::oe1_pauseGame; - op[275] = &AGOSEngine::o_copysf; - op[276] = &AGOSEngine::o_restoreIcons; - op[277] = &AGOSEngine::oe1_printPlayerHit; - op[278] = &AGOSEngine::oe1_printMonsterHit; - op[279] = &AGOSEngine::o_freezeZones; - op[280] = &AGOSEngine::o_placeNoIcons; - op[281] = &AGOSEngine::o_clearTimers; - op[282] = &AGOSEngine::o_setDollar; - op[283] = &AGOSEngine::o_isBox; +#define OPCODE(x) _OPCODE(AGOSEngine_Elvira1, x) + +void AGOSEngine_Elvira1::setupOpcodes() { + static const OpcodeEntryElvira1 opcodes[] = { + /* 00 */ + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(oe1_present), + OPCODE(oe1_notPresent), + /* 04 */ + OPCODE(oe1_worn), + OPCODE(oe1_notWorn), + OPCODE(o_carried), + OPCODE(o_notCarried), + /* 08 */ + OPCODE(o_isAt), + OPCODE(oe1_isNotAt), + OPCODE(oe1_sibling), + OPCODE(oe1_notSibling), + /* 12 */ + OPCODE(o_zero), + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + /* 16 */ + OPCODE(o_gt), + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + /* 20 */ + OPCODE(o_ltf), + OPCODE(o_gtf), + OPCODE(oe1_isIn), + OPCODE(oe1_isNotIn), + /* 24 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 28 */ + OPCODE(o_invalid), + OPCODE(o_chance), + OPCODE(oe1_isPlayer), + OPCODE(o_invalid), + /* 32 */ + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + OPCODE(o_invalid), + /* 36 */ + OPCODE(o_oflag), + OPCODE(oe1_canPut), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 44 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe1_create), + /* 48 */ + OPCODE(o_destroy), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_place), + /* 52 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe1_copyof), + OPCODE(oe1_copyfo), + /* 56 */ + OPCODE(o_copyff), + OPCODE(oe1_whatO), + OPCODE(o_invalid), + OPCODE(oe1_weigh), + /* 60 */ + OPCODE(oe1_setFF), + OPCODE(o_clear), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 64 */ + OPCODE(o_let), + OPCODE(o_add), + OPCODE(o_sub), + OPCODE(o_addf), + /* 68 */ + OPCODE(o_subf), + OPCODE(o_mul), + OPCODE(o_div), + OPCODE(o_mulf), + /* 72 */ + OPCODE(o_divf), + OPCODE(o_mod), + OPCODE(o_modf), + OPCODE(o_random), + /* 76 */ + OPCODE(oe1_moveDirn), + OPCODE(o_goto), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 80 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 84 */ + OPCODE(o_putBy), + OPCODE(o_inc), + OPCODE(o_dec), + OPCODE(o_setState), + /* 88 */ + OPCODE(o_invalid), + OPCODE(o_print), + OPCODE(oe1_score), + OPCODE(o_message), + /* 92 */ + OPCODE(o_msg), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 96 */ + OPCODE(oe1_look), + OPCODE(o_end), + OPCODE(o_done), + OPCODE(o_invalid), + /* 100 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 104 */ + OPCODE(o_invalid), + OPCODE(o_process), + OPCODE(oe1_doClass), + OPCODE(o_invalid), + /* 108 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 112*/ + OPCODE(oe1_pObj), + OPCODE(o_invalid), + OPCODE(oe1_pName), + OPCODE(oe1_pcName), + /* 116 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_when), + /* 120 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 124 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 128 */ + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 132 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe1_isCalled), + /* 136 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 140 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 144 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 148 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 152 */ + OPCODE(o_debug), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 156 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 160 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe1_cFlag), + OPCODE(o_invalid), + /* 164 */ + OPCODE(oe1_rescan), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 168 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 172 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 176 */ + OPCODE(oe1_setUserItem), + OPCODE(oe1_getUserItem), + OPCODE(oe1_clearUserItem), + OPCODE(o_invalid), + /* 180 */ + OPCODE(oe1_whereTo), + OPCODE(oe1_doorExit), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 184 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 188 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 192 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 196 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_comment), + OPCODE(o_invalid), + /* 200 */ + OPCODE(o_invalid), + OPCODE(oe1_saveGame), + OPCODE(oe1_loadGame), + OPCODE(o_invalid), + /* 204 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 208 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 212 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 216 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe1_findMaster), + /* 220 */ + OPCODE(oe1_nextMaster), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 224 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(oe1_animate), + OPCODE(oe1_stopAnimate), + /* 228 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 232 */ + OPCODE(o_closeWindow), + OPCODE(oe1_menu), + OPCODE(o_invalid), + OPCODE(o_addBox), + /* 236 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 240 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 244 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 248 */ + OPCODE(o_invalid), + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(oe1_bitClear), + /* 252 */ + OPCODE(oe1_bitSet), + OPCODE(oe1_bitTest), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 256 */ + OPCODE(o_sync), + OPCODE(o_defObj), + OPCODE(oe1_enableInput), + OPCODE(oe1_setTime), + /* 260 */ + OPCODE(oe1_ifTime), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(oe1_playTune), + /* 264 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(oe1_zoneDisk), + /* 268 */ + OPCODE(oe1_saveUserGame), + OPCODE(oe1_loadUserGame), + OPCODE(oe1_printStats), + OPCODE(oe1_stopTune), + /* 272 */ + OPCODE(oe1_printPlayerDamage), + OPCODE(oe1_printMonsterDamage), + OPCODE(oe1_pauseGame), + OPCODE(o_copysf), + /* 276 */ + OPCODE(o_restoreIcons), + OPCODE(oe1_printPlayerHit), + OPCODE(oe1_printMonsterHit), + OPCODE(o_freezeZones), + /* 280 */ + OPCODE(o_placeNoIcons), + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox) + }; + + _opcodesElvira1 = opcodes; + _numOpcodes = 284; +} + +void AGOSEngine_Elvira1::executeOpcode(int opcode) { + OpcodeProcElvira1 op = _opcodesElvira1[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Elvira 1 Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::oe1_present() { +void AGOSEngine_Elvira1::oe1_present() { // 2: present (here or carried) Item *item = getNextItemPtr(); setScriptCondition(item->parent == getItem1ID() || item->parent == me()->parent); } -void AGOSEngine::oe1_notPresent() { +void AGOSEngine_Elvira1::oe1_notPresent() { // 3: not present (neither here nor carried) Item *item = getNextItemPtr(); setScriptCondition(item->parent != getItem1ID() && item->parent != me()->parent); } -void AGOSEngine::oe1_worn() { +void AGOSEngine_Elvira1::oe1_worn() { // 4: worn Item *item = getNextItemPtr(); SubObject *subObject = (SubObject *)findChildOfType(item, 2); @@ -201,7 +425,7 @@ void AGOSEngine::oe1_worn() { setScriptCondition((subObject->objectFlags & kOFWorn) != 0); } -void AGOSEngine::oe1_notWorn() { +void AGOSEngine_Elvira1::oe1_notWorn() { // 5: not worn Item *item = getNextItemPtr(); SubObject *subObject = (SubObject *)findChildOfType(item, 2); @@ -212,72 +436,72 @@ void AGOSEngine::oe1_notWorn() { setScriptCondition((subObject->objectFlags & kOFWorn) == 0); } -void AGOSEngine::oe1_isNotAt() { +void AGOSEngine_Elvira1::oe1_isNotAt() { // 9: parent is not Item *item = getNextItemPtr(); setScriptCondition(item->parent != getNextItemID()); } -void AGOSEngine::oe1_sibling() { +void AGOSEngine_Elvira1::oe1_sibling() { // 10: sibling Item *item1 = getNextItemPtr(); Item *item2 = getNextItemPtr(); setScriptCondition(item1->parent == item2->parent); } -void AGOSEngine::oe1_notSibling() { +void AGOSEngine_Elvira1::oe1_notSibling() { // 11: not sibling Item *item1 = getNextItemPtr(); Item *item2 = getNextItemPtr(); setScriptCondition(item1->parent != item2->parent); } -void AGOSEngine::oe1_isIn() { +void AGOSEngine_Elvira1::oe1_isIn() { // 22: is in Item *item1 = getNextItemPtr(); Item *item2 = getNextItemPtr(); setScriptCondition(contains(item1, item2) != 0); } -void AGOSEngine::oe1_isNotIn() { +void AGOSEngine_Elvira1::oe1_isNotIn() { // 23: is not in Item *item1 = getNextItemPtr(); Item *item2 = getNextItemPtr(); setScriptCondition(contains(item1, item2) == 0); } -void AGOSEngine::oe1_isPlayer() { +void AGOSEngine_Elvira1::oe1_isPlayer() { // 30: is player setScriptCondition(isPlayer(getNextItemPtr())); } -void AGOSEngine::oe1_canPut() { +void AGOSEngine_Elvira1::oe1_canPut() { // 37: can put Item *item1 = getNextItemPtr(); Item *item2 = getNextItemPtr(); setScriptCondition(canPlace(item1, item2) == 0); } -void AGOSEngine::oe1_create() { +void AGOSEngine_Elvira1::oe1_create() { // 47: create setItemParent(getNextItemPtr(), derefItem(me()->parent)); } -void AGOSEngine::oe1_copyof() { +void AGOSEngine_Elvira1::oe1_copyof() { // 54: copy of Item *item = getNextItemPtr(); uint tmp = getVarOrByte(); writeNextVarContents(getUserFlag(item, tmp)); } -void AGOSEngine::oe1_copyfo() { +void AGOSEngine_Elvira1::oe1_copyfo() { // 55: copy fo uint tmp = getNextVarContents(); Item *item = getNextItemPtr(); setUserFlag(item, getVarOrByte(), tmp); } -void AGOSEngine::oe1_whatO() { +void AGOSEngine_Elvira1::oe1_whatO() { // 57: what o int a = getVarOrWord(); @@ -287,30 +511,30 @@ void AGOSEngine::oe1_whatO() { _objectItem = findMaster(_scriptAdj2, _scriptNoun2); } -void AGOSEngine::oe1_weigh() { +void AGOSEngine_Elvira1::oe1_weigh() { // 59: weight Item *item = getNextItemPtr(); writeNextVarContents(weighUp(item)); } -void AGOSEngine::oe1_setFF() { +void AGOSEngine_Elvira1::oe1_setFF() { // 60: set FF writeNextVarContents(255); } -void AGOSEngine::oe1_moveDirn() { +void AGOSEngine_Elvira1::oe1_moveDirn() { // 54: move direction int16 d = readVariable(getVarOrWord()); - moveDirn_e1(me(), d); + moveDirn(me(), d); } -void AGOSEngine::oe1_score() { +void AGOSEngine_Elvira1::oe1_score() { // 90: score SubPlayer *p = (SubPlayer *) findChildOfType(me(), 3); showMessageFormat("Your score is %ld.\n", p->score); } -void AGOSEngine::oe1_look() { +void AGOSEngine_Elvira1::oe1_look() { // 96: look Item *i = derefItem(me()->parent); if (i == NULL) @@ -343,7 +567,7 @@ void AGOSEngine::oe1_look() { } } -void AGOSEngine::oe1_doClass() { +void AGOSEngine_Elvira1::oe1_doClass() { // 106: do class Item *i = getNextItemPtr(); int16 cm = getVarOrWord(); @@ -366,7 +590,7 @@ void AGOSEngine::oe1_doClass() { } } -void AGOSEngine::oe1_pObj() { +void AGOSEngine_Elvira1::oe1_pObj() { // 112: print object SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2); getVarOrWord(); @@ -375,28 +599,28 @@ void AGOSEngine::oe1_pObj() { showMessageFormat("%s", (const char *)getStringPtrByID(subObject->objectName)); } -void AGOSEngine::oe1_pName() { +void AGOSEngine_Elvira1::oe1_pName() { // 114: Item *i = getNextItemPtr(); showMessageFormat("%s", (const char *)getStringPtrByID(i->itemName)); } -void AGOSEngine::oe1_pcName() { +void AGOSEngine_Elvira1::oe1_pcName() { // 115: Item *i = getNextItemPtr(); - Common::String name = (const char *)getStringPtrByID(i->itemName); - name.toUppercase(); - showMessageFormat("%s", name.c_str()); + + // TODO: Change first letter to upper case. + showMessageFormat("%s\n", (const byte *)getStringPtrByID(i->itemName)); // Difference } -void AGOSEngine::oe1_isCalled() { +void AGOSEngine_Elvira1::oe1_isCalled() { // 135: childstruct fr2 is Item *item = getNextItemPtr(); uint stringId = getNextStringID(); setScriptCondition(!scumm_stricmp((const char *)getStringPtrByID(item->itemName), (const char *)getStringPtrByID(stringId))); } -void AGOSEngine::oe1_cFlag() { +void AGOSEngine_Elvira1::oe1_cFlag() { // 162: check container flag SubContainer *c = (SubContainer *)findChildOfType(getNextItemPtr(), 7); uint bit = getVarOrWord(); @@ -407,19 +631,19 @@ void AGOSEngine::oe1_cFlag() { setScriptCondition((c->flags & (1 << bit)) != 0); } -void AGOSEngine::oe1_rescan() { +void AGOSEngine_Elvira1::oe1_rescan() { // 164: restart subroutine setScriptReturn(-10); } -void AGOSEngine::oe1_setUserItem() { +void AGOSEngine_Elvira1::oe1_setUserItem() { // 176: set user item Item *i = getNextItemPtr(); uint tmp = getVarOrWord(); setUserItem(i, tmp, getNextItemID()); } -void AGOSEngine::oe1_getUserItem() { +void AGOSEngine_Elvira1::oe1_getUserItem() { // 177: get user item Item *i = getNextItemPtr(); int n = getVarOrWord(); @@ -430,7 +654,7 @@ void AGOSEngine::oe1_getUserItem() { _objectItem = derefItem(getUserItem(i, n)); } -void AGOSEngine::oe1_whereTo() { +void AGOSEngine_Elvira1::oe1_whereTo() { // 180: where to Item *i = getNextItemPtr(); int16 d = getVarOrWord(); @@ -442,7 +666,7 @@ void AGOSEngine::oe1_whereTo() { _objectItem = getExitOf_e1(i, d); } -void AGOSEngine::oe1_doorExit() { +void AGOSEngine_Elvira1::oe1_doorExit() { // 181: door exit Item *x; Item *a = (Item *)-1; @@ -466,34 +690,36 @@ void AGOSEngine::oe1_doorExit() { writeVariable(f, 255); } -void AGOSEngine::oe1_saveGame() { +void AGOSEngine_Elvira1::oe1_saveGame() { // 201: save game uint16 stringId = getNextStringID(); debug(0, "oe1_saveGame: stub (%s)", getStringPtrByID(stringId)); - saveGame_e1((const char *)getStringPtrByID(stringId)); + + // TODO: Add support for selecting slot + saveGame(1, (const char *)getStringPtrByID(stringId)); } -void AGOSEngine::oe1_loadGame() { +void AGOSEngine_Elvira1::oe1_loadGame() { // 202: load game uint16 stringId = getNextStringID(); debug(0, "oe1_loadGame: stub (%s)", (const char *)getStringPtrByID(stringId)); if (!scumm_stricmp(getFileName(GAME_RESTFILE), (const char *)getStringPtrByID(stringId))) { - loadGame_e1(getFileName(GAME_RESTFILE), true); + loadGame(getFileName(GAME_RESTFILE), true); } else { - loadGame_e1((const char *)getStringPtrByID(stringId)); + loadGame((const char *)getStringPtrByID(stringId)); } } -void AGOSEngine::oe1_clearUserItem() { +void AGOSEngine_Elvira1::oe1_clearUserItem() { // 178: clear user item Item *i = getNextItemPtr(); uint tmp = getVarOrWord(); setUserItem(i, tmp, 0); } -void AGOSEngine::oe1_findMaster() { +void AGOSEngine_Elvira1::oe1_findMaster() { // 219: find master int16 ad, no; int16 d = getVarOrByte(); @@ -508,7 +734,7 @@ void AGOSEngine::oe1_findMaster() { _objectItem = findMaster(ad, no); } -void AGOSEngine::oe1_nextMaster() { +void AGOSEngine_Elvira1::oe1_nextMaster() { // 220: next master int16 ad, no; Item *item = getNextItemPtr(); @@ -524,32 +750,32 @@ void AGOSEngine::oe1_nextMaster() { _objectItem = nextMaster(item, ad, no); } -void AGOSEngine::oe1_animate() { +void AGOSEngine_Elvira1::oe1_animate() { // 226: animate - uint vgaSpriteId = getVarOrWord(); - uint windowNum = getVarOrByte(); - uint x = getVarOrWord(); - uint y = getVarOrWord(); - uint palette = getVarOrWord(); + uint16 vgaSpriteId = getVarOrWord(); + uint16 windowNum = getVarOrByte(); + int16 x = getVarOrWord(); + int16 y = getVarOrWord(); + uint16 palette = getVarOrWord(); _lockWord |= 0x40; animate(windowNum, vgaSpriteId / 100, vgaSpriteId, x, y, palette); _lockWord &= ~0x40; } -void AGOSEngine::oe1_stopAnimate() { +void AGOSEngine_Elvira1::oe1_stopAnimate() { // 227: stop animate stopAnimate(getVarOrWord()); } -void AGOSEngine::oe1_menu() { +void AGOSEngine_Elvira1::oe1_menu() { // 233: agos menu uint b = getVarOrWord(); uint a = getVarOrWord(); drawMenuStrip(a, b); } -void AGOSEngine::oe1_bitClear() { +void AGOSEngine_Elvira1::oe1_bitClear() { // 251: set bit off int var = getVarOrWord(); int bit = getVarOrWord(); @@ -557,7 +783,7 @@ void AGOSEngine::oe1_bitClear() { writeVariable(var, _variableArray[var] & ~(1 << bit)); } -void AGOSEngine::oe1_bitSet() { +void AGOSEngine_Elvira1::oe1_bitSet() { // 252: set bit on int var = getVarOrWord(); int bit = getVarOrWord(); @@ -565,7 +791,7 @@ void AGOSEngine::oe1_bitSet() { writeVariable(var, _variableArray[var] | (1 << bit)); } -void AGOSEngine::oe1_bitTest() { +void AGOSEngine_Elvira1::oe1_bitTest() { // 253: bit test int var = getVarOrWord(); int bit = getVarOrWord(); @@ -573,7 +799,7 @@ void AGOSEngine::oe1_bitTest() { setScriptCondition((_variableArray[var] & (1 << bit)) != 0); } -void AGOSEngine::oe1_enableInput() { +void AGOSEngine_Elvira1::oe1_enableInput() { // 258: enable input _variableArray[500] = 0; @@ -591,14 +817,16 @@ void AGOSEngine::oe1_enableInput() { _lastHitArea3 = 0; _lastHitArea = 0; + + _clickOnly = 1; } -void AGOSEngine::oe1_setTime() { +void AGOSEngine_Elvira1::oe1_setTime() { // 259: set time time(&_timeStore); } -void AGOSEngine::oe1_ifTime() { +void AGOSEngine_Elvira1::oe1_ifTime() { // 260: if time time_t t; @@ -611,7 +839,7 @@ void AGOSEngine::oe1_ifTime() { setScriptCondition(false); } -void AGOSEngine::oe1_playTune() { +void AGOSEngine_Elvira1::oe1_playTune() { // 264: play tune int music = getVarOrWord(); int track = getVarOrWord(); @@ -631,13 +859,21 @@ void AGOSEngine::oe1_playTune() { } } -void AGOSEngine::oe1_zoneDisk() { +void AGOSEngine_Elvira1::oe1_zoneDisk() { // 267: set disk number of each zone getVarOrWord(); getVarOrWord(); } -void AGOSEngine::oe1_printStats() { +void AGOSEngine_Elvira1::oe1_saveUserGame() { + // TODO +} + +void AGOSEngine_Elvira1::oe1_loadUserGame() { + // TODO +} + +void AGOSEngine_Elvira1::oe1_printStats() { // 270: print stats WindowBlock *window = _dummyWindow; int val; @@ -697,11 +933,11 @@ void AGOSEngine::oe1_printStats() { mouseOn(); } -void AGOSEngine::oe1_stopTune() { +void AGOSEngine_Elvira1::oe1_stopTune() { // 271: stop tune } -void AGOSEngine::oe1_printPlayerDamage() { +void AGOSEngine_Elvira1::oe1_printPlayerDamage() { // 272: print player damage WindowBlock *window = _dummyWindow; window->flags = 1; @@ -711,7 +947,7 @@ void AGOSEngine::oe1_printPlayerDamage() { mouseOn(); } -void AGOSEngine::oe1_printMonsterDamage() { +void AGOSEngine_Elvira1::oe1_printMonsterDamage() { // 273: print monster damage WindowBlock *window = _dummyWindow; window->flags = 1; @@ -721,7 +957,7 @@ void AGOSEngine::oe1_printMonsterDamage() { mouseOn(); } -void AGOSEngine::oe1_pauseGame() { +void AGOSEngine_Elvira1::oe1_pauseGame() { // 274: pause game WindowBlock *window = _windowArray[4]; const char *message1, *message2; @@ -734,6 +970,7 @@ restart: window->textColumn = 0; window->textRow = 0; window->textColumnOffset = 0; + window->textLength = 0; // Difference switch (_language) { case Common::FR_FRA: @@ -760,6 +997,7 @@ restart: window->textColumn = 0; window->textRow = 0; window->textColumnOffset = 0; + window->textLength = 0; // Difference switch (_language) { case Common::FR_FRA: @@ -792,7 +1030,7 @@ restart: _gameStoppedClock = time(NULL) - pauseTime + _gameStoppedClock; } -void AGOSEngine::oe1_printPlayerHit() { +void AGOSEngine_Elvira1::oe1_printPlayerHit() { // 277: print player hit WindowBlock *window = _dummyWindow; window->flags = 1; @@ -802,7 +1040,7 @@ void AGOSEngine::oe1_printPlayerHit() { mouseOn(); } -void AGOSEngine::oe1_printMonsterHit() { +void AGOSEngine_Elvira1::oe1_printMonsterHit() { // 278: print monster hit WindowBlock *window = _dummyWindow; window->flags = 1; @@ -970,27 +1208,22 @@ void AGOSEngine::printScroll() { VC10_state state; VgaPointersEntry *vpe = &_vgaBufferPointers[1]; - state.depack_src = vpe->vgaFile2 + READ_BE_UINT32(vpe->vgaFile2 + 9 * 8); + state.srcPtr = vpe->vgaFile2 + READ_BE_UINT32(vpe->vgaFile2 + 9 * 8); state.palette = 0; + state.paletteMod = 0; state.x = 10; state.y = 32; state.width = state.draw_width = 10; state.height = state.draw_height = 72; - state.flags = kDFCompressed | kDFUseFrontBuf; + state.flags = kDFCompressed; _windowNum = 3; state.depack_cont = -0x80; state.x_skip = 0; state.y_skip = 0; - state.surf2_addr = getFrontBuf(); - state.surf2_pitch = _dxSurfacePitch; - - state.surf_addr = getBackBuf(); - state.surf_pitch = _dxSurfacePitch; - - drawImages(&state); + drawImage(&state); } } // End of namespace AGOS diff --git a/engines/agos/script_e2.cpp b/engines/agos/script_e2.cpp index 0da38a31c2..3b2c1203df 100644 --- a/engines/agos/script_e2.cpp +++ b/engines/agos/script_e2.cpp @@ -27,77 +27,262 @@ namespace AGOS { -void AGOSEngine::setupElvira2Opcodes(OpcodeProc *op) { - setupCommonOpcodes(op); - - op[8] = &AGOSEngine::oe1_isNotAt; - op[9] = &AGOSEngine::oe1_sibling; - op[10] = &AGOSEngine::oe1_notSibling; - op[21] = &AGOSEngine::oe1_isIn; - op[22] = &AGOSEngine::oe1_isNotIn; - op[24] = &AGOSEngine::oe1_isPlayer; - op[29] = &AGOSEngine::oe1_canPut; - op[34] = &AGOSEngine::oe1_copyof; - op[35] = &AGOSEngine::oe1_copyfo; - op[37] = &AGOSEngine::oe1_whatO; - op[39] = &AGOSEngine::oe1_weigh; - op[54] = &AGOSEngine::oe2_moveDirn; - op[72] = &AGOSEngine::oe2_doClass; - op[73] = &AGOSEngine::oe2_pObj; - op[74] = &AGOSEngine::oe1_pName; - op[75] = &AGOSEngine::oe1_pcName; - op[79] = &AGOSEngine::oe1_isCalled; - op[83] = &AGOSEngine::oe1_rescan; - op[89] = &AGOSEngine::oe2_loadGame; - op[94] = &AGOSEngine::oe1_findMaster; - op[95] = &AGOSEngine::oe1_nextMaster; - op[98] = &AGOSEngine::oe1_animate; - op[99] = &AGOSEngine::oe1_stopAnimate; - op[113] = &AGOSEngine::oe2_drawItem; - op[123] = &AGOSEngine::oe1_setTime; - op[124] = &AGOSEngine::oe1_ifTime; - op[127] = &AGOSEngine::os1_playTune; - op[135] = &AGOSEngine::oe2_pauseGame; - op[144] = &AGOSEngine::oe2_setDoorOpen; - op[145] = &AGOSEngine::oe2_setDoorClosed; - op[146] = &AGOSEngine::oe2_setDoorLocked; - op[147] = &AGOSEngine::oe2_setDoorClosed; - op[148] = &AGOSEngine::oe2_ifDoorOpen; - op[149] = &AGOSEngine::oe2_ifDoorClosed; - op[150] = &AGOSEngine::oe2_ifDoorLocked; - op[161] = &AGOSEngine::oe2_printStats; - op[165] = &AGOSEngine::oe2_setSuperRoom; - op[166] = &AGOSEngine::oe2_getSuperRoom; - op[167] = &AGOSEngine::oe2_setExitOpen; - op[168] = &AGOSEngine::oe2_setExitClosed; - op[169] = &AGOSEngine::oe2_setExitLocked; - op[170] = &AGOSEngine::oe2_setExitClosed; - op[171] = &AGOSEngine::oe2_ifExitOpen; - op[172] = &AGOSEngine::oe2_ifExitClosed; - op[173] = &AGOSEngine::oe2_ifExitLocked; - op[174] = &AGOSEngine::oe2_unk174; - op[175] = &AGOSEngine::oe2_getDollar2; - op[176] = &AGOSEngine::oe2_setSRExit; - op[177] = &AGOSEngine::oe2_unk177; - op[178] = &AGOSEngine::oe2_unk178; - op[179] = &AGOSEngine::oe2_isAdjNoun; - op[180] = &AGOSEngine::oe2_b2Set; - op[181] = &AGOSEngine::oe2_b2Clear; - op[182] = &AGOSEngine::oe2_b2Zero; - op[183] = &AGOSEngine::oe2_b2NotZero; +#define OPCODE(x) _OPCODE(AGOSEngine_Elvira2, x) + +void AGOSEngine_Elvira2::setupOpcodes() { + static const OpcodeEntryElvira2 opcodes[] = { + /* 00 */ + OPCODE(o_invalid), + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(o_invalid), + /* 04 */ + OPCODE(o_invalid), + OPCODE(o_carried), + OPCODE(o_notCarried), + OPCODE(o_isAt), + /* 08 */ + OPCODE(oe1_isNotAt), + OPCODE(oe1_sibling), + OPCODE(oe1_notSibling), + OPCODE(o_zero), + /* 12 */ + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + OPCODE(o_gt), + /* 16 */ + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + OPCODE(o_ltf), + /* 20 */ + OPCODE(o_gtf), + OPCODE(oe1_isIn), + OPCODE(oe1_isNotIn), + OPCODE(o_chance), + /* 24 */ + OPCODE(oe1_isPlayer), + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + /* 28 */ + OPCODE(o_oflag), + OPCODE(oe1_canPut), + OPCODE(o_invalid), + OPCODE(o_destroy), + /* 32 */ + OPCODE(o_invalid), + OPCODE(o_place), + OPCODE(oe1_copyof), + OPCODE(oe1_copyfo), + /* 36 */ + OPCODE(o_copyff), + OPCODE(oe1_whatO), + OPCODE(o_invalid), + OPCODE(oe1_weigh), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_clear), + OPCODE(o_let), + OPCODE(o_add), + /* 44 */ + OPCODE(o_sub), + OPCODE(o_addf), + OPCODE(o_subf), + OPCODE(o_mul), + /* 48 */ + OPCODE(o_div), + OPCODE(o_mulf), + OPCODE(o_divf), + OPCODE(o_mod), + /* 52 */ + OPCODE(o_modf), + OPCODE(o_random), + OPCODE(oe2_moveDirn), + OPCODE(o_goto), + /* 56 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_putBy), + OPCODE(o_inc), + /* 60 */ + OPCODE(o_dec), + OPCODE(o_setState), + OPCODE(o_print), + OPCODE(o_message), + /* 64 */ + OPCODE(o_msg), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 68 */ + OPCODE(o_end), + OPCODE(o_done), + OPCODE(o_invalid), + OPCODE(o_process), + /* 72 */ + OPCODE(oe2_doClass), + OPCODE(oe2_pObj), + OPCODE(oe1_pName), + OPCODE(oe1_pcName), + /* 76 */ + OPCODE(o_when), + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(oe1_isCalled), + /* 80 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_debug), + OPCODE(oe1_rescan), + /* 84 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_comment), + /* 88 */ + OPCODE(o_invalid), + OPCODE(oe1_loadGame), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 92 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(oe1_findMaster), + OPCODE(oe1_nextMaster), + /* 96 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(oe1_animate), + OPCODE(oe1_stopAnimate), + /* 100 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 104 */ + OPCODE(o_closeWindow), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_addBox), + /* 108 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 112 */ + OPCODE(o_invalid), + OPCODE(oe2_drawItem), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 116 */ + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 120*/ + OPCODE(o_sync), + OPCODE(o_defObj), + OPCODE(o_invalid), + OPCODE(oe1_setTime), + /* 124 */ + OPCODE(oe1_ifTime), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(o_playTune), + /* 128 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(o_invalid), + /* 132 */ + OPCODE(o_saveUserGame), + OPCODE(o_loadUserGame), + OPCODE(o_invalid), + OPCODE(oe2_pauseGame), + /* 136 */ + OPCODE(o_copysf), + OPCODE(o_restoreIcons), + OPCODE(o_freezeZones), + OPCODE(o_placeNoIcons), + /* 140 */ + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox), + OPCODE(oe2_doTable), + /* 144 */ + OPCODE(oe2_setDoorOpen), + OPCODE(oe2_setDoorClosed), + OPCODE(oe2_setDoorLocked), + OPCODE(oe2_setDoorClosed), + /* 148 */ + OPCODE(oe2_ifDoorOpen), + OPCODE(oe2_ifDoorClosed), + OPCODE(oe2_ifDoorLocked), + OPCODE(oe2_storeItem), + /* 152 */ + OPCODE(oe2_getItem), + OPCODE(oe2_bSet), + OPCODE(oe2_bClear), + OPCODE(oe2_bZero), + /* 156 */ + OPCODE(oe2_bNotZero), + OPCODE(oe2_getOValue), + OPCODE(oe2_setOValue), + OPCODE(o_invalid), + /* 160 */ + OPCODE(oe2_ink), + OPCODE(oe2_printStats), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 164 */ + OPCODE(o_invalid), + OPCODE(oe2_setSuperRoom), + OPCODE(oe2_getSuperRoom), + OPCODE(oe2_setExitOpen), + /* 168 */ + OPCODE(oe2_setExitClosed), + OPCODE(oe2_setExitLocked), + OPCODE(oe2_setExitClosed), + OPCODE(oe2_ifExitOpen), + /* 172 */ + OPCODE(oe2_ifExitClosed), + OPCODE(oe2_ifExitLocked), + OPCODE(oe2_unk174), + OPCODE(oe2_getDollar2), + /* 176 */ + OPCODE(oe2_setSRExit), + OPCODE(oe2_unk177), + OPCODE(oe2_unk178), + OPCODE(oe2_isAdjNoun), + /* 180 */ + OPCODE(oe2_b2Set), + OPCODE(oe2_b2Clear), + OPCODE(oe2_b2Zero), + OPCODE(oe2_b2NotZero) + }; + + _opcodesElvira2 = opcodes; + _numOpcodes = 184; +} + +void AGOSEngine_Elvira2::executeOpcode(int opcode) { + OpcodeProcElvira2 op = _opcodesElvira2[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Elvira 2 Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::oe2_moveDirn() { +void AGOSEngine_Elvira2::oe2_moveDirn() { // 54: move direction int16 d = getVarOrByte(); - moveDirn_e2(me(), d); + moveDirn(me(), d); } -void AGOSEngine::oe2_doClass() { +void AGOSEngine_Elvira2::oe2_doClass() { // 72: do class Item *i = getNextItemPtr(); byte cm = getByte(); @@ -120,27 +305,15 @@ void AGOSEngine::oe2_doClass() { } } -void AGOSEngine::oe2_pObj() { +void AGOSEngine_Elvira2::oe2_pObj() { // 73: print object SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2); if (subObject != NULL && subObject->objectFlags & kOFText) - showMessageFormat((const char *)getStringPtrByID(subObject->objectFlagValue[0])); + showMessageFormat("%s\n", (const char *)getStringPtrByID(subObject->objectFlagValue[0])); // Difference } -void AGOSEngine::oe2_loadGame() { - // 89: load game - uint16 stringId = getNextStringID(); - debug(0, "oe1_loadGame: stub (%s)", (const char *)getStringPtrByID(stringId)); - - if (!scumm_stricmp(getFileName(GAME_RESTFILE), (const char *)getStringPtrByID(stringId))) { - loadGame(getFileName(GAME_RESTFILE), true); - } else { - loadGame((const char *)getStringPtrByID(stringId)); - } -} - -void AGOSEngine::oe2_drawItem() { +void AGOSEngine_Elvira2::oe2_drawItem() { // 113: draw item Item *i = getNextItemPtr(); int a = getVarOrByte(); @@ -151,7 +324,7 @@ void AGOSEngine::oe2_drawItem() { mouseOn(); } -void AGOSEngine::oe2_doTable() { +void AGOSEngine_Elvira2::oe2_doTable() { // 143: start item sub Item *i = getNextItemPtr(); @@ -176,7 +349,7 @@ void AGOSEngine::oe2_doTable() { } } -void AGOSEngine::oe2_pauseGame() { +void AGOSEngine_Elvira2::oe2_pauseGame() { // 135: pause game HitArea *ha; @@ -205,53 +378,53 @@ void AGOSEngine::oe2_pauseGame() { _gameStoppedClock = time(NULL) - pauseTime + _gameStoppedClock; } -void AGOSEngine::oe2_setDoorOpen() { +void AGOSEngine_Elvira2::oe2_setDoorOpen() { // 144: set door open Item *i = getNextItemPtr(); setDoorState(i, getVarOrByte(), 1); } -void AGOSEngine::oe2_setDoorClosed() { +void AGOSEngine_Elvira2::oe2_setDoorClosed() { // 145: set door closed Item *i = getNextItemPtr(); setDoorState(i, getVarOrByte(), 2); } -void AGOSEngine::oe2_setDoorLocked() { +void AGOSEngine_Elvira2::oe2_setDoorLocked() { // 146: set door locked Item *i = getNextItemPtr(); setDoorState(i, getVarOrByte(), 3); } -void AGOSEngine::oe2_ifDoorOpen() { +void AGOSEngine_Elvira2::oe2_ifDoorOpen() { // 148: if door open Item *i = getNextItemPtr(); uint16 d = getVarOrByte(); setScriptCondition(getDoorState(i, d) == 1); } -void AGOSEngine::oe2_ifDoorClosed() { +void AGOSEngine_Elvira2::oe2_ifDoorClosed() { // 149: if door closed Item *i = getNextItemPtr(); uint16 d = getVarOrByte(); setScriptCondition(getDoorState(i, d) == 2); } -void AGOSEngine::oe2_ifDoorLocked() { +void AGOSEngine_Elvira2::oe2_ifDoorLocked() { // 150: if door locked Item *i=getNextItemPtr(); uint16 d = getVarOrByte(); setScriptCondition(getDoorState(i, d) == 3); } -void AGOSEngine::oe2_storeItem() { +void AGOSEngine_Elvira2::oe2_storeItem() { // 151: set array6 to item uint var = getVarOrByte(); Item *item = getNextItemPtr(); _itemStore[var] = item; } -void AGOSEngine::oe2_getItem() { +void AGOSEngine_Elvira2::oe2_getItem() { // 152: set m1 to m3 to array 6 Item *item = _itemStore[getVarOrByte()]; uint var = getVarOrByte(); @@ -262,22 +435,22 @@ void AGOSEngine::oe2_getItem() { } } -void AGOSEngine::oe2_bSet() { +void AGOSEngine_Elvira2::oe2_bSet() { // 153: set bit setBitFlag(getVarWrapper(), true); } -void AGOSEngine::oe2_bClear() { +void AGOSEngine_Elvira2::oe2_bClear() { // 154: clear bit setBitFlag(getVarWrapper(), false); } -void AGOSEngine::oe2_bZero() { +void AGOSEngine_Elvira2::oe2_bZero() { // 155: is bit clear setScriptCondition(!getBitFlag(getVarWrapper())); } -void AGOSEngine::oe2_bNotZero() { +void AGOSEngine_Elvira2::oe2_bNotZero() { // 156: is bit set uint bit = getVarWrapper(); @@ -289,7 +462,7 @@ void AGOSEngine::oe2_bNotZero() { setScriptCondition(getBitFlag(bit)); } -void AGOSEngine::oe2_getOValue() { +void AGOSEngine_Elvira2::oe2_getOValue() { // 157: get item int prop Item *item = getNextItemPtr(); SubObject *subObject = (SubObject *)findChildOfType(item, 2); @@ -303,7 +476,7 @@ void AGOSEngine::oe2_getOValue() { } } -void AGOSEngine::oe2_setOValue() { +void AGOSEngine_Elvira2::oe2_setOValue() { // 158: set item prop Item *item = getNextItemPtr(); SubObject *subObject = (SubObject *)findChildOfType(item, 2); @@ -316,12 +489,12 @@ void AGOSEngine::oe2_setOValue() { } } -void AGOSEngine::oe2_ink() { +void AGOSEngine_Elvira2::oe2_ink() { // 160 setTextColor(getVarOrByte()); } -void AGOSEngine::oe2_printStats() { +void AGOSEngine_Elvira2::oe2_printStats() { // 161: print stats WindowBlock *window = _dummyWindow; int val; @@ -366,17 +539,17 @@ void AGOSEngine::oe2_printStats() { mouseOn(); } -void AGOSEngine::oe2_setSuperRoom() { +void AGOSEngine_Elvira2::oe2_setSuperRoom() { // 165: set super room _superRoomNumber = getVarOrWord(); } -void AGOSEngine::oe2_getSuperRoom() { +void AGOSEngine_Elvira2::oe2_getSuperRoom() { // 166: get super room writeNextVarContents(_superRoomNumber); } -void AGOSEngine::oe2_setExitOpen() { +void AGOSEngine_Elvira2::oe2_setExitOpen() { // 167: set exit open Item *i = getNextItemPtr(); uint16 n = getVarOrWord(); @@ -384,7 +557,7 @@ void AGOSEngine::oe2_setExitOpen() { setExitState(i, n, d, 1); } -void AGOSEngine::oe2_setExitClosed() { +void AGOSEngine_Elvira2::oe2_setExitClosed() { // 168: set exit closed Item *i = getNextItemPtr(); uint16 n = getVarOrWord(); @@ -392,7 +565,7 @@ void AGOSEngine::oe2_setExitClosed() { setExitState(i, n, d, 2); } -void AGOSEngine::oe2_setExitLocked() { +void AGOSEngine_Elvira2::oe2_setExitLocked() { // 169: set exit locked Item *i = getNextItemPtr(); uint16 n = getVarOrWord(); @@ -400,7 +573,7 @@ void AGOSEngine::oe2_setExitLocked() { setExitState(i, n, d, 3); } -void AGOSEngine::oe2_ifExitOpen() { +void AGOSEngine_Elvira2::oe2_ifExitOpen() { // 171: if exit open Item *i = getNextItemPtr(); uint16 n = getVarOrWord(); @@ -408,7 +581,7 @@ void AGOSEngine::oe2_ifExitOpen() { setScriptCondition(getExitState(i, n, d) == 1); } -void AGOSEngine::oe2_ifExitClosed() { +void AGOSEngine_Elvira2::oe2_ifExitClosed() { // 172: if exit closed Item *i = getNextItemPtr(); uint16 n = getVarOrWord(); @@ -416,7 +589,7 @@ void AGOSEngine::oe2_ifExitClosed() { setScriptCondition(getExitState(i, n, d) == 2); } -void AGOSEngine::oe2_ifExitLocked() { +void AGOSEngine_Elvira2::oe2_ifExitLocked() { // 173: if exit locked Item *i = getNextItemPtr(); uint16 n = getVarOrWord(); @@ -424,13 +597,13 @@ void AGOSEngine::oe2_ifExitLocked() { setScriptCondition(getExitState(i, n, d) == 3); } -void AGOSEngine::oe2_unk174() { +void AGOSEngine_Elvira2::oe2_unk174() { // 174: uint a = getVarOrWord(); debug(0, "oe2_unk174: stub (%d)", a); } -void AGOSEngine::oe2_getDollar2() { +void AGOSEngine_Elvira2::oe2_getDollar2() { // 175 _showPreposition = true; @@ -455,7 +628,7 @@ void AGOSEngine::oe2_getDollar2() { _showPreposition = false; } -void AGOSEngine::oe2_setSRExit() { +void AGOSEngine_Elvira2::oe2_setSRExit() { // 176: set super room exit Item *i = getNextItemPtr(); uint n = getVarOrWord(); @@ -464,44 +637,56 @@ void AGOSEngine::oe2_setSRExit() { setSRExit(i, n, d, s); } -void AGOSEngine::oe2_unk177() { - // 177: set unknown vga event +void AGOSEngine_Elvira2::oe2_unk177() { + // 177: Set damage indicator event uint a = getVarOrByte(); + if (_opcode177Var1 && !_opcode177Var2 && a != 0 && a <= 10) { + addVgaEvent(_vgaBaseDelay, IMAGE_EVENT2, NULL, 0, a); + _opcode177Var2 = 0; + _opcode177Var1 = 0; + } + debug(0, "oe2_unk177: stub (%d)", a); } -void AGOSEngine::oe2_unk178() { +void AGOSEngine_Elvira2::oe2_unk178() { // 178: set unknown vga event uint a = getVarOrByte(); + if (_opcode178Var1 && !_opcode178Var2 && a != 0 && a <= 10) { + addVgaEvent(_vgaBaseDelay, IMAGE_EVENT3, NULL, 0, a); + _opcode178Var2 = 0; + _opcode178Var1 = 0; + } + debug(0, "oe2_unk178: stub (%d)", a); } -void AGOSEngine::oe2_isAdjNoun() { +void AGOSEngine_Elvira2::oe2_isAdjNoun() { // 179: item unk1 unk2 is Item *item = getNextItemPtr(); int16 a = getNextWord(), b = getNextWord(); setScriptCondition(item->adjective == a && item->noun == b); } -void AGOSEngine::oe2_b2Set() { +void AGOSEngine_Elvira2::oe2_b2Set() { // 180: set bit2 uint bit = getVarOrByte(); _bitArrayTwo[bit / 16] |= (1 << (bit & 15)); } -void AGOSEngine::oe2_b2Clear() { +void AGOSEngine_Elvira2::oe2_b2Clear() { // 181: clear bit2 uint bit = getVarOrByte(); _bitArrayTwo[bit / 16] &= ~(1 << (bit & 15)); } -void AGOSEngine::oe2_b2Zero() { +void AGOSEngine_Elvira2::oe2_b2Zero() { // 182: is bit2 clear uint bit = getVarOrByte(); setScriptCondition((_bitArrayTwo[bit / 16] & (1 << (bit & 15))) == 0); } -void AGOSEngine::oe2_b2NotZero() { +void AGOSEngine_Elvira2::oe2_b2NotZero() { // 183: is bit2 set uint bit = getVarOrByte(); setScriptCondition((_bitArrayTwo[bit / 16] & (1 << (bit & 15))) != 0); diff --git a/engines/agos/script_ff.cpp b/engines/agos/script_ff.cpp index 59c42c94ed..7dff2346cf 100644 --- a/engines/agos/script_ff.cpp +++ b/engines/agos/script_ff.cpp @@ -30,69 +30,276 @@ namespace AGOS { -void AGOSEngine::setupFeebleOpcodes(OpcodeProc *op) { - setupCommonOpcodes(op); - - op[23] = &AGOSEngine::off_chance; - op[37] = &AGOSEngine::off_jumpOut; - op[65] = &AGOSEngine::off_addTextBox; - op[66] = &AGOSEngine::oww_setShortText; - op[67] = &AGOSEngine::oww_setLongText; - op[70] = &AGOSEngine::off_printLongText; - op[83] = &AGOSEngine::os2_rescan; - op[98] = &AGOSEngine::os2_animate; - op[99] = &AGOSEngine::os2_stopAnimate; - op[107] = &AGOSEngine::off_addBox; - op[122] = &AGOSEngine::off_oracleTextDown; - op[123] = &AGOSEngine::off_oracleTextUp; - op[124] = &AGOSEngine::off_ifTime; - op[131] = &AGOSEngine::off_setTime; - op[132] = &AGOSEngine::off_saveUserGame; - op[133] = &AGOSEngine::off_loadUserGame; - op[134] = &AGOSEngine::off_listSaveGames; - op[135] = &AGOSEngine::off_checkCD; - op[161] = &AGOSEngine::off_screenTextBox; - op[162] = &AGOSEngine::os1_screenTextMsg; - op[164] = &AGOSEngine::oe2_getDollar2; - op[165] = &AGOSEngine::off_isAdjNoun; - op[166] = &AGOSEngine::oe2_b2Set; - op[167] = &AGOSEngine::oe2_b2Clear; - op[168] = &AGOSEngine::oe2_b2Zero; - op[169] = &AGOSEngine::oe2_b2NotZero; - op[171] = &AGOSEngine::off_hyperLinkOn; - op[172] = &AGOSEngine::off_hyperLinkOff; - op[173] = &AGOSEngine::off_checkPaths; - op[175] = &AGOSEngine::oww_lockZones; - op[176] = &AGOSEngine::oww_unlockZones; - op[177] = &AGOSEngine::off_screenTextPObj; - op[178] = &AGOSEngine::os1_getPathPosn; - op[179] = &AGOSEngine::os1_scnTxtLongText; - op[180] = &AGOSEngine::off_mouseOn; - op[181] = &AGOSEngine::off_mouseOff; - op[182] = &AGOSEngine::off_loadVideo; - op[183] = &AGOSEngine::off_playVideo; - op[184] = &AGOSEngine::os1_unloadZone; - op[186] = &AGOSEngine::os1_unfreezeZones; - op[187] = &AGOSEngine::off_centreScroll; - op[188] = &AGOSEngine::os2_isShortText; - op[189] = &AGOSEngine::os2_clearMarks; - op[190] = &AGOSEngine::os2_waitMark; - op[191] = &AGOSEngine::off_resetPVCount; - op[192] = &AGOSEngine::off_setPathValues; - op[193] = &AGOSEngine::off_stopClock; - op[194] = &AGOSEngine::off_restartClock; - op[195] = &AGOSEngine::off_setColour; - op[196] = &AGOSEngine::off_b3Set; - op[197] = &AGOSEngine::off_b3Clear; - op[198] = &AGOSEngine::off_b3Zero; - op[199] = &AGOSEngine::off_b3NotZero; +#define OPCODE(x) _OPCODE(AGOSEngine_Feeble, x) + +void AGOSEngine_Feeble::setupOpcodes() { + static const OpcodeEntryFeeble opcodes[] = { + /* 00 */ + OPCODE(o_invalid), + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(o_invalid), + /* 04 */ + OPCODE(o_invalid), + OPCODE(o_carried), + OPCODE(o_notCarried), + OPCODE(o_isAt), + /* 08 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_zero), + /* 12 */ + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + OPCODE(o_gt), + /* 16 */ + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + OPCODE(o_ltf), + /* 20 */ + OPCODE(o_gtf), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(off_chance), + /* 24 */ + OPCODE(o_invalid), + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + /* 28 */ + OPCODE(o_oflag), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_destroy), + /* 32 */ + OPCODE(o_invalid), + OPCODE(o_place), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 36 */ + OPCODE(o_copyff), + OPCODE(off_jumpOut), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_clear), + OPCODE(o_let), + OPCODE(o_add), + /* 44 */ + OPCODE(o_sub), + OPCODE(o_addf), + OPCODE(o_subf), + OPCODE(o_mul), + /* 48 */ + OPCODE(o_div), + OPCODE(o_mulf), + OPCODE(o_divf), + OPCODE(o_mod), + /* 52 */ + OPCODE(o_modf), + OPCODE(o_random), + OPCODE(o_invalid), + OPCODE(o_goto), + /* 56 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_putBy), + OPCODE(o_inc), + /* 60 */ + OPCODE(o_dec), + OPCODE(o_setState), + OPCODE(o_print), + OPCODE(o_message), + /* 64 */ + OPCODE(o_msg), + OPCODE(off_addTextBox), + OPCODE(oww_setShortText), + OPCODE(oww_setLongText), + /* 68 */ + OPCODE(o_end), + OPCODE(o_done), + OPCODE(off_printLongText), + OPCODE(o_process), + /* 72 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 76 */ + OPCODE(o_when), + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(o_isCalled), + /* 80 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_debug), + OPCODE(os2_rescan), + /* 84 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_comment), + /* 88 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 92 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 96 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(os2_animate), + OPCODE(os2_stopAnimate), + /* 100 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 104 */ + OPCODE(o_closeWindow), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(off_addBox), + /* 108 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 112 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 116 */ + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 120 */ + OPCODE(o_sync), + OPCODE(o_defObj), + OPCODE(off_oracleTextDown), + OPCODE(off_oracleTextUp), + /* 124 */ + OPCODE(off_ifTime), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(o_invalid), + /* 128 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(off_setTime), + /* 132 */ + OPCODE(off_saveUserGame), + OPCODE(off_loadUserGame), + OPCODE(off_listSaveGames), + OPCODE(off_checkCD), + /* 136 */ + OPCODE(o_copysf), + OPCODE(o_restoreIcons), + OPCODE(o_freezeZones), + OPCODE(o_placeNoIcons), + /* 140 */ + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox), + OPCODE(oe2_doTable), + /* 144 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 148 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe2_storeItem), + /* 152 */ + OPCODE(oe2_getItem), + OPCODE(oe2_bSet), + OPCODE(oe2_bClear), + OPCODE(oe2_bZero), + /* 156 */ + OPCODE(oe2_bNotZero), + OPCODE(oe2_getOValue), + OPCODE(oe2_setOValue), + OPCODE(o_invalid), + /* 160 */ + OPCODE(oe2_ink), + OPCODE(off_screenTextBox), + OPCODE(os1_screenTextMsg), + OPCODE(o_invalid), + /* 164 */ + OPCODE(oe2_getDollar2), + OPCODE(off_isAdjNoun), + OPCODE(oe2_b2Set), + OPCODE(oe2_b2Clear), + /* 168 */ + OPCODE(oe2_b2Zero), + OPCODE(oe2_b2NotZero), + OPCODE(o_invalid), + OPCODE(off_hyperLinkOn), + /* 172 */ + OPCODE(off_hyperLinkOff), + OPCODE(off_checkPaths), + OPCODE(o_invalid), + OPCODE(oww_lockZones), + /* 176 */ + OPCODE(oww_unlockZones), + OPCODE(off_screenTextPObj), + OPCODE(os1_getPathPosn), + OPCODE(os1_scnTxtLongText), + /* 180 */ + OPCODE(off_mouseOn), + OPCODE(off_mouseOff), + OPCODE(off_loadVideo), + OPCODE(off_playVideo), + /* 184 */ + OPCODE(os1_unloadZone), + OPCODE(o_invalid), + OPCODE(os1_unfreezeZones), + OPCODE(off_centreScroll), + /* 188 */ + OPCODE(os2_isShortText), + OPCODE(os2_clearMarks), + OPCODE(os2_waitMark), + OPCODE(off_resetPVCount), + /* 192 */ + OPCODE(off_setPathValues), + OPCODE(off_stopClock), + OPCODE(off_restartClock), + OPCODE(off_setColour), + /* 196 */ + OPCODE(off_b3Set), + OPCODE(off_b3Clear), + OPCODE(off_b3Zero), + OPCODE(off_b3NotZero) + }; + + _opcodesFeeble = opcodes; + _numOpcodes = 200; +} + +void AGOSEngine_Feeble::executeOpcode(int opcode) { + OpcodeProcFeeble op = _opcodesFeeble[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Feeble Files Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::off_chance() { +void AGOSEngine_Feeble::off_chance() { // 23 uint a = getVarOrWord(); @@ -112,13 +319,13 @@ void AGOSEngine::off_chance() { setScriptCondition(false); } -void AGOSEngine::off_jumpOut() { +void AGOSEngine_Feeble::off_jumpOut() { // 37 getVarOrByte(); setScriptReturn(1); } -void AGOSEngine::off_addTextBox() { +void AGOSEngine_Feeble::off_addTextBox() { // 65: add hit area uint flags = kBFTextBox | kBFBoxItem; uint id = getVarOrWord(); @@ -139,14 +346,14 @@ void AGOSEngine::off_addTextBox() { defineBox(id, x, y, w, h, flags + (num << 8), 208, _dummyItem2); } -void AGOSEngine::off_printLongText() { +void AGOSEngine_Feeble::off_printLongText() { // 70: show string from array int num = getVarOrByte(); const char *str = (const char *)getStringPtrByID(_longText[num]); sendInteractText(num, "%d. %s\n", num, str); } -void AGOSEngine::off_addBox() { +void AGOSEngine_Feeble::off_addBox() { // 107: add item hitarea uint flags = 0; uint id = getVarOrWord(); @@ -176,17 +383,17 @@ void AGOSEngine::off_addBox() { defineBox(id, x, y, w, h, flags, verb, item); } -void AGOSEngine::off_oracleTextDown() { +void AGOSEngine_Feeble::off_oracleTextDown() { // 122: oracle text down oracleTextDown(); } -void AGOSEngine::off_oracleTextUp() { +void AGOSEngine_Feeble::off_oracleTextUp() { // 123: oracle text up oracleTextUp(); } -void AGOSEngine::off_ifTime() { +void AGOSEngine_Feeble::off_ifTime() { // 124: if time time_t t; @@ -200,13 +407,13 @@ void AGOSEngine::off_ifTime() { setScriptCondition(false); } -void AGOSEngine::off_setTime() { +void AGOSEngine_Feeble::off_setTime() { // 131 time(&_timeStore); _timeStore -= _gameStoppedClock; } -void AGOSEngine::off_saveUserGame() { +void AGOSEngine_Feeble::off_saveUserGame() { // 132: save game _noOracleScroll = 0; _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); @@ -214,7 +421,7 @@ void AGOSEngine::off_saveUserGame() { _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); } -void AGOSEngine::off_loadUserGame() { +void AGOSEngine_Feeble::off_loadUserGame() { // 133: load game if (readVariable(55) == 999) { loadGame(getFileName(GAME_RESTFILE), true); @@ -223,12 +430,12 @@ void AGOSEngine::off_loadUserGame() { } } -void AGOSEngine::off_listSaveGames() { +void AGOSEngine_Feeble::off_listSaveGames() { // 134: dummy opcode? listSaveGames(1); } -void AGOSEngine::off_checkCD() { +void AGOSEngine_Feeble::off_checkCD() { // 135: switch CD uint disc = readVariable(97); @@ -244,7 +451,7 @@ void AGOSEngine::off_checkCD() { debug(0, "Switch to CD number %d", disc); } -void AGOSEngine::off_screenTextBox() { +void AGOSEngine_Feeble::off_screenTextBox() { // 161: setup text TextLocation *tl = getTextLocation(getVarOrByte()); @@ -253,7 +460,7 @@ void AGOSEngine::off_screenTextBox() { tl->width = getVarOrWord(); } -void AGOSEngine::off_isAdjNoun() { +void AGOSEngine_Feeble::off_isAdjNoun() { // 165: item unk1 unk2 is Item *item = getNextItemPtr(); int16 a = getNextWord(), b = getNextWord(); @@ -265,17 +472,17 @@ void AGOSEngine::off_isAdjNoun() { setScriptCondition(false); } -void AGOSEngine::off_hyperLinkOn() { +void AGOSEngine_Feeble::off_hyperLinkOn() { // 171: oracle hyperlink on hyperLinkOn(getVarOrWord()); } -void AGOSEngine::off_hyperLinkOff() { +void AGOSEngine_Feeble::off_hyperLinkOff() { // 172: oracle hyperlink off hyperLinkOff(); } -void AGOSEngine::off_checkPaths() { +void AGOSEngine_Feeble::off_checkPaths() { // 173 check paths int i, count; const uint8 *pathVal1 = _pathValues1; @@ -311,7 +518,7 @@ void AGOSEngine::off_checkPaths() { _variableArray2[52] = result; } -void AGOSEngine::off_screenTextPObj() { +void AGOSEngine_Feeble::off_screenTextPObj() { // 177: inventory descriptions uint vgaSpriteId = getVarOrByte(); uint color = getVarOrByte(); @@ -340,7 +547,7 @@ void AGOSEngine::off_screenTextPObj() { } } -void AGOSEngine::off_mouseOn() { +void AGOSEngine_Feeble::off_mouseOn() { // 180: force mouseOn if (_mouseCursor != 5) { resetVerbs(); @@ -349,29 +556,29 @@ void AGOSEngine::off_mouseOn() { _mouseHideCount = 0; } -void AGOSEngine::off_mouseOff() { +void AGOSEngine_Feeble::off_mouseOff() { // 181: force mouseOff scriptMouseOff(); clearName(); } -void AGOSEngine::off_loadVideo() { +void AGOSEngine_Feeble::off_loadVideo() { // 182: load video file const byte *filename = getStringPtrByID(getNextStringID()); _moviePlay->load((const char *)filename); } -void AGOSEngine::off_playVideo() { +void AGOSEngine_Feeble::off_playVideo() { // 183: play video _moviePlay->play(); } -void AGOSEngine::off_centreScroll() { +void AGOSEngine_Feeble::off_centreScroll() { // 187 centreScroll(); } -void AGOSEngine::off_resetPVCount() { +void AGOSEngine_Feeble::off_resetPVCount() { // 191 if (getBitFlag(83)) { _PVCount1 = 0; @@ -382,7 +589,7 @@ void AGOSEngine::off_resetPVCount() { } } -void AGOSEngine::off_setPathValues() { +void AGOSEngine_Feeble::off_setPathValues() { // 192 uint8 a = getVarOrByte(); uint8 b = getVarOrByte(); @@ -401,19 +608,19 @@ void AGOSEngine::off_setPathValues() { } } -void AGOSEngine::off_stopClock() { +void AGOSEngine_Feeble::off_stopClock() { // 193: pause clock _clockStopped = time(NULL); } -void AGOSEngine::off_restartClock() { +void AGOSEngine_Feeble::off_restartClock() { // 194: resume clock if (_clockStopped != 0) _gameStoppedClock += time(NULL) - _clockStopped; _clockStopped = 0; } -void AGOSEngine::off_setColour() { +void AGOSEngine_Feeble::off_setColour() { // 195: set palette colour uint c = getVarOrByte() * 4; uint r = getVarOrByte(); @@ -427,25 +634,25 @@ void AGOSEngine::off_setColour() { _paletteFlag = 2; } -void AGOSEngine::off_b3Set() { +void AGOSEngine_Feeble::off_b3Set() { // 196: set bit3 uint bit = getVarOrByte(); _bitArrayThree[bit / 16] |= (1 << (bit & 15)); } -void AGOSEngine::off_b3Clear() { +void AGOSEngine_Feeble::off_b3Clear() { // 197: clear bit3 uint bit = getVarOrByte(); _bitArrayThree[bit / 16] &= ~(1 << (bit & 15)); } -void AGOSEngine::off_b3Zero() { +void AGOSEngine_Feeble::off_b3Zero() { // 198: is bit3 clear uint bit = getVarOrByte(); setScriptCondition((_bitArrayThree[bit / 16] & (1 << (bit & 15))) == 0); } -void AGOSEngine::off_b3NotZero() { +void AGOSEngine_Feeble::off_b3NotZero() { // 199: is bit3 set uint bit = getVarOrByte(); setScriptCondition((_bitArrayThree[bit / 16] & (1 << (bit & 15))) != 0); diff --git a/engines/agos/script_pp.cpp b/engines/agos/script_pp.cpp index ef865a58ad..3038a48e0d 100644 --- a/engines/agos/script_pp.cpp +++ b/engines/agos/script_pp.cpp @@ -29,64 +29,271 @@ namespace AGOS { -void AGOSEngine::setupPuzzleOpcodes(OpcodeProc *op) { - setupCommonOpcodes(op); - - op[23] = &AGOSEngine::off_chance; - op[30] = &AGOSEngine::opp_iconifyWindow; - op[32] = &AGOSEngine::opp_restoreOopsPosition; - op[38] = &AGOSEngine::opp_loadMouseImage; - op[63] = &AGOSEngine::opp_message; - op[65] = &AGOSEngine::off_addTextBox; - op[66] = &AGOSEngine::opp_setShortText; - op[67] = &AGOSEngine::oww_setLongText; - op[70] = &AGOSEngine::off_printLongText; - op[83] = &AGOSEngine::os2_rescan; - op[98] = &AGOSEngine::os2_animate; - op[99] = &AGOSEngine::os2_stopAnimate; - op[105] = &AGOSEngine::opp_loadHiScores; - op[106] = &AGOSEngine::opp_checkHiScores; - op[107] = &AGOSEngine::off_addBox; - op[120] = &AGOSEngine::opp_sync; - op[122] = &AGOSEngine::off_oracleTextDown; - op[123] = &AGOSEngine::off_oracleTextUp; - op[124] = &AGOSEngine::off_ifTime; - op[131] = &AGOSEngine::off_setTime; - op[132] = &AGOSEngine::opp_saveUserGame; - op[133] = &AGOSEngine::opp_loadUserGame; - op[134] = &AGOSEngine::off_listSaveGames; - op[161] = &AGOSEngine::off_screenTextBox; - op[162] = &AGOSEngine::os1_screenTextMsg; - op[164] = &AGOSEngine::oe2_getDollar2; - op[165] = &AGOSEngine::off_isAdjNoun; - op[171] = &AGOSEngine::off_hyperLinkOn; - op[172] = &AGOSEngine::off_hyperLinkOff; - op[173] = &AGOSEngine::opp_saveOopsPosition; - op[175] = &AGOSEngine::oww_lockZones; - op[176] = &AGOSEngine::oww_unlockZones; - op[177] = &AGOSEngine::off_screenTextPObj; - op[178] = &AGOSEngine::os1_getPathPosn; - op[179] = &AGOSEngine::os1_scnTxtLongText; - op[180] = &AGOSEngine::os1_mouseOn; - op[181] = &AGOSEngine::off_mouseOff; - op[184] = &AGOSEngine::os1_unloadZone; - op[186] = &AGOSEngine::os1_unfreezeZones; - op[187] = &AGOSEngine::opp_resetGameTime; - op[188] = &AGOSEngine::os2_isShortText; - op[189] = &AGOSEngine::os2_clearMarks; - op[190] = &AGOSEngine::os2_waitMark; - op[191] = &AGOSEngine::opp_resetPVCount; - op[192] = &AGOSEngine::opp_setPathValues; - op[193] = &AGOSEngine::off_stopClock; - op[194] = &AGOSEngine::opp_restartClock; - op[195] = &AGOSEngine::off_setColour; +#define OPCODE(x) _OPCODE(AGOSEngine_PuzzlePack, x) + +void AGOSEngine_PuzzlePack::setupOpcodes() { + static const OpcodeEntryPuzzlePack opcodes[] = { + /* 00 */ + OPCODE(o_invalid), + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(o_invalid), + /* 04 */ + OPCODE(o_invalid), + OPCODE(o_carried), + OPCODE(o_notCarried), + OPCODE(o_isAt), + /* 08 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_zero), + /* 12 */ + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + OPCODE(o_gt), + /* 16 */ + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + OPCODE(o_ltf), + /* 20 */ + OPCODE(o_gtf), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(off_chance), + /* 24 */ + OPCODE(o_invalid), + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + /* 28 */ + OPCODE(o_oflag), + OPCODE(opp_iconifyWindow), + OPCODE(o_invalid), + OPCODE(o_destroy), + /* 32 */ + OPCODE(opp_restoreOopsPosition), + OPCODE(o_place), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 36 */ + OPCODE(o_copyff), + OPCODE(o_invalid), + OPCODE(opp_loadMouseImage), + OPCODE(o_invalid), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_clear), + OPCODE(o_let), + OPCODE(o_add), + /* 44 */ + OPCODE(o_sub), + OPCODE(o_addf), + OPCODE(o_subf), + OPCODE(o_mul), + /* 48 */ + OPCODE(o_div), + OPCODE(o_mulf), + OPCODE(o_divf), + OPCODE(o_mod), + /* 52 */ + OPCODE(o_modf), + OPCODE(o_random), + OPCODE(o_invalid), + OPCODE(o_goto), + /* 56 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_putBy), + OPCODE(o_inc), + /* 60 */ + OPCODE(o_dec), + OPCODE(o_setState), + OPCODE(o_print), + OPCODE(opp_message), + /* 64 */ + OPCODE(o_msg), + OPCODE(off_addTextBox), + OPCODE(opp_setShortText), + OPCODE(oww_setLongText), + /* 68 */ + OPCODE(o_end), + OPCODE(o_done), + OPCODE(off_printLongText), + OPCODE(o_process), + /* 72 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 76 */ + OPCODE(o_when), + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(o_isCalled), + /* 80 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_debug), + OPCODE(os2_rescan), + /* 84 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_comment), + /* 88 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 92 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 96 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(os2_animate), + OPCODE(os2_stopAnimate), + /* 100 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 104 */ + OPCODE(o_closeWindow), + OPCODE(opp_loadHiScores), + OPCODE(opp_checkHiScores), + OPCODE(off_addBox), + /* 108 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 112 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 116 */ + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 120 */ + OPCODE(opp_sync), + OPCODE(o_defObj), + OPCODE(off_oracleTextDown), + OPCODE(off_oracleTextUp), + /* 124 */ + OPCODE(off_ifTime), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(o_invalid), + /* 128 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(off_setTime), + /* 132 */ + OPCODE(opp_saveUserGame), + OPCODE(opp_loadUserGame), + OPCODE(off_listSaveGames), + OPCODE(o_invalid), + /* 136 */ + OPCODE(o_copysf), + OPCODE(o_restoreIcons), + OPCODE(o_freezeZones), + OPCODE(o_placeNoIcons), + /* 140 */ + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox), + OPCODE(oe2_doTable), + /* 144 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 148 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe2_storeItem), + /* 152 */ + OPCODE(oe2_getItem), + OPCODE(oe2_bSet), + OPCODE(oe2_bClear), + OPCODE(oe2_bZero), + /* 156 */ + OPCODE(oe2_bNotZero), + OPCODE(oe2_getOValue), + OPCODE(oe2_setOValue), + OPCODE(o_invalid), + /* 160 */ + OPCODE(oe2_ink), + OPCODE(off_screenTextBox), + OPCODE(os1_screenTextMsg), + OPCODE(o_invalid), + /* 164 */ + OPCODE(oe2_getDollar2), + OPCODE(off_isAdjNoun), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 168 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(off_hyperLinkOn), + /* 172 */ + OPCODE(off_hyperLinkOff), + OPCODE(opp_saveOopsPosition), + OPCODE(o_invalid), + OPCODE(oww_lockZones), + /* 176 */ + OPCODE(oww_unlockZones), + OPCODE(off_screenTextPObj), + OPCODE(os1_getPathPosn), + OPCODE(os1_scnTxtLongText), + /* 180 */ + OPCODE(os1_mouseOn), + OPCODE(off_mouseOff), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 184 */ + OPCODE(os1_unloadZone), + OPCODE(o_invalid), + OPCODE(os1_unfreezeZones), + OPCODE(opp_resetGameTime), + /* 188 */ + OPCODE(os2_isShortText), + OPCODE(os2_clearMarks), + OPCODE(os2_waitMark), + OPCODE(opp_resetPVCount), + /* 192 */ + OPCODE(opp_setPathValues), + OPCODE(off_stopClock), + OPCODE(opp_restartClock), + OPCODE(off_setColour), + }; + + _opcodesPuzzlePack = opcodes; + _numOpcodes = 196; +} + +void AGOSEngine_PuzzlePack::executeOpcode(int opcode) { + OpcodeProcPuzzlePack op = _opcodesPuzzlePack[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Puzzle Pack Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::opp_iconifyWindow() { +void AGOSEngine_PuzzlePack::opp_iconifyWindow() { // 30 getNextItemPtr(); if (_clockStopped != 0) @@ -95,7 +302,7 @@ void AGOSEngine::opp_iconifyWindow() { _system->setFeatureState(OSystem::kFeatureIconifyWindow, true); } -void AGOSEngine::opp_restoreOopsPosition() { +void AGOSEngine_PuzzlePack::opp_restoreOopsPosition() { // 32: restore oops position uint i; @@ -117,14 +324,14 @@ void AGOSEngine::opp_restoreOopsPosition() { } } -void AGOSEngine::opp_loadMouseImage() { +void AGOSEngine_PuzzlePack::opp_loadMouseImage() { // 38: load mouse image getNextItemPtr(); getVarOrByte(); loadMouseImage(); } -void AGOSEngine::opp_message() { +void AGOSEngine_PuzzlePack::opp_message() { // 63: show string nl if (getBitFlag(105)) { @@ -136,7 +343,7 @@ void AGOSEngine::opp_message() { } } -void AGOSEngine::opp_setShortText() { +void AGOSEngine_PuzzlePack::opp_setShortText() { // 66: set item name uint var = getVarOrByte(); uint stringId = getNextStringID(); @@ -147,18 +354,18 @@ void AGOSEngine::opp_setShortText() { } } -void AGOSEngine::opp_loadHiScores() { +void AGOSEngine_PuzzlePack::opp_loadHiScores() { // 105: load high scores getVarOrByte(); } -void AGOSEngine::opp_checkHiScores() { +void AGOSEngine_PuzzlePack::opp_checkHiScores() { // 106: check high scores getVarOrByte(); getVarOrByte(); } -void AGOSEngine::opp_sync() { +void AGOSEngine_PuzzlePack::opp_sync() { // 120: sync uint a = getVarOrWord(); if (a == 8001 || a == 8101 || a == 8201 || a == 8301 || a == 8401) { @@ -167,7 +374,7 @@ void AGOSEngine::opp_sync() { sendSync(a); } -void AGOSEngine::opp_saveUserGame() { +void AGOSEngine_PuzzlePack::opp_saveUserGame() { // 132: save game if (_clockStopped != 0) _gameTime += time(NULL) - _clockStopped; @@ -183,7 +390,7 @@ void AGOSEngine::opp_saveUserGame() { //saveHiScores() } -void AGOSEngine::opp_loadUserGame() { +void AGOSEngine_PuzzlePack::opp_loadUserGame() { // 133: load usergame // NoPatience or Jumble @@ -196,7 +403,7 @@ void AGOSEngine::opp_loadUserGame() { loadGame(genSaveName(1)); } -void AGOSEngine::opp_saveOopsPosition() { +void AGOSEngine_PuzzlePack::opp_saveOopsPosition() { // 173: save oops position if (!isVgaQueueEmpty()) { _oopsValid = true; @@ -208,18 +415,18 @@ void AGOSEngine::opp_saveOopsPosition() { } } -void AGOSEngine::opp_resetGameTime() { +void AGOSEngine_PuzzlePack::opp_resetGameTime() { // 187: reset game time _gameTime = 0; } -void AGOSEngine::opp_resetPVCount() { +void AGOSEngine_PuzzlePack::opp_resetPVCount() { // 191 _PVCount = 0; _GPVCount = 0; } -void AGOSEngine::opp_setPathValues() { +void AGOSEngine_PuzzlePack::opp_setPathValues() { // 192 _pathValues[_PVCount++] = getVarOrByte(); _pathValues[_PVCount++] = getVarOrByte(); @@ -227,7 +434,7 @@ void AGOSEngine::opp_setPathValues() { _pathValues[_PVCount++] = getVarOrByte(); } -void AGOSEngine::opp_restartClock() { +void AGOSEngine_PuzzlePack::opp_restartClock() { // 194: resume clock if (_clockStopped != 0) _gameTime += time(NULL) - _clockStopped; diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp index 12184fdfb4..b10013d186 100644 --- a/engines/agos/script_s1.cpp +++ b/engines/agos/script_s1.cpp @@ -33,55 +33,267 @@ extern bool isSmartphone(void); namespace AGOS { -void AGOSEngine::setupSimon1Opcodes(OpcodeProc *op) { - setupCommonOpcodes(op); - - op[65] = &AGOSEngine::oww_addTextBox; - op[66] = &AGOSEngine::oww_setShortText; - op[67] = &AGOSEngine::oww_setLongText; - op[70] = &AGOSEngine::oww_printLongText; - op[83] = &AGOSEngine::oe1_rescan; - op[88] = &AGOSEngine::o_haltAnimation; - op[89] = &AGOSEngine::o_restartAnimation; - op[98] = &AGOSEngine::os1_animate; - op[99] = &AGOSEngine::oe1_stopAnimate; - op[127] = &AGOSEngine::os1_playTune; - op[135] = &AGOSEngine::os1_pauseGame; - op[161] = &AGOSEngine::os1_screenTextBox; - op[162] = &AGOSEngine::os1_screenTextMsg; - op[163] = &AGOSEngine::os1_playEffect; - op[164] = &AGOSEngine::oe2_getDollar2; - op[165] = &AGOSEngine::oe2_isAdjNoun; - op[166] = &AGOSEngine::oe2_b2Set; - op[167] = &AGOSEngine::oe2_b2Clear; - op[168] = &AGOSEngine::oe2_b2Zero; - op[169] = &AGOSEngine::oe2_b2NotZero; - op[175] = &AGOSEngine::oww_lockZones; - op[176] = &AGOSEngine::oww_unlockZones; - op[177] = &AGOSEngine::os1_screenTextPObj; - op[178] = &AGOSEngine::os1_getPathPosn; - op[179] = &AGOSEngine::os1_scnTxtLongText; - op[180] = &AGOSEngine::os1_mouseOn; - op[181] = &AGOSEngine::os1_mouseOff; - op[182] = &AGOSEngine::os1_loadBeard; - op[183] = &AGOSEngine::os1_unloadBeard; - op[184] = &AGOSEngine::os1_unloadZone; - op[185] = &AGOSEngine::os1_loadStrings; - op[186] = &AGOSEngine::os1_unfreezeZones; - op[187] = &AGOSEngine::os1_specialFade; +#define OPCODE(x) _OPCODE(AGOSEngine_Simon1, x) + +void AGOSEngine_Simon1::setupOpcodes() { + static const OpcodeEntrySimon1 opcodes[] = { + /* 00 */ + OPCODE(o_invalid), + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(o_invalid), + /* 04 */ + OPCODE(o_invalid), + OPCODE(o_carried), + OPCODE(o_notCarried), + OPCODE(o_isAt), + /* 08 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_zero), + /* 12 */ + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + OPCODE(o_gt), + /* 16 */ + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + OPCODE(o_ltf), + /* 20 */ + OPCODE(o_gtf), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_chance), + /* 24 */ + OPCODE(o_invalid), + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + /* 28 */ + OPCODE(o_oflag), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_destroy), + /* 32 */ + OPCODE(o_invalid), + OPCODE(o_place), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 36 */ + OPCODE(o_copyff), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_clear), + OPCODE(o_let), + OPCODE(o_add), + /* 44 */ + OPCODE(o_sub), + OPCODE(o_addf), + OPCODE(o_subf), + OPCODE(o_mul), + /* 48 */ + OPCODE(o_div), + OPCODE(o_mulf), + OPCODE(o_divf), + OPCODE(o_mod), + /* 52 */ + OPCODE(o_modf), + OPCODE(o_random), + OPCODE(o_invalid), + OPCODE(o_goto), + /* 56 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_putBy), + OPCODE(o_inc), + /* 60 */ + OPCODE(o_dec), + OPCODE(o_setState), + OPCODE(o_print), + OPCODE(o_message), + /* 64 */ + OPCODE(o_msg), + OPCODE(oww_addTextBox), + OPCODE(oww_setShortText), + OPCODE(oww_setLongText), + /* 68 */ + OPCODE(o_end), + OPCODE(o_done), + OPCODE(oww_printLongText), + OPCODE(o_process), + /* 72 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 76 */ + OPCODE(o_when), + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(o_isCalled), + /* 80 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_debug), + OPCODE(oe1_rescan), + /* 84 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_comment), + /* 88 */ + OPCODE(o_haltAnimation), + OPCODE(o_restartAnimation), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 92 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 96 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(os1_animate), + OPCODE(oe1_stopAnimate), + /* 100 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 104 */ + OPCODE(o_closeWindow), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_addBox), + /* 108 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 112 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 116 */ + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 120 */ + OPCODE(o_sync), + OPCODE(o_defObj), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 124 */ + OPCODE(o_invalid), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(o_playTune), + /* 128 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(o_invalid), + /* 132 */ + OPCODE(o_saveUserGame), + OPCODE(o_loadUserGame), + OPCODE(o_invalid), + OPCODE(os1_pauseGame), + /* 136 */ + OPCODE(o_copysf), + OPCODE(o_restoreIcons), + OPCODE(o_freezeZones), + OPCODE(o_placeNoIcons), + /* 140 */ + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox), + OPCODE(oe2_doTable), + /* 144 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 148 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe2_storeItem), + /* 152 */ + OPCODE(oe2_getItem), + OPCODE(oe2_bSet), + OPCODE(oe2_bClear), + OPCODE(oe2_bZero), + /* 156 */ + OPCODE(oe2_bNotZero), + OPCODE(oe2_getOValue), + OPCODE(oe2_setOValue), + OPCODE(o_invalid), + /* 160 */ + OPCODE(oe2_ink), + OPCODE(os1_screenTextBox), + OPCODE(os1_screenTextMsg), + OPCODE(os1_playEffect), + /* 164 */ + OPCODE(oe2_getDollar2), + OPCODE(oe2_isAdjNoun), + OPCODE(oe2_b2Set), + OPCODE(oe2_b2Clear), + /* 168 */ + OPCODE(oe2_b2Zero), + OPCODE(oe2_b2NotZero), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 172 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oww_lockZones), + /* 176 */ + OPCODE(oww_unlockZones), + OPCODE(os1_screenTextPObj), + OPCODE(os1_getPathPosn), + OPCODE(os1_scnTxtLongText), + /* 180 */ + OPCODE(os1_mouseOn), + OPCODE(os1_mouseOff), + OPCODE(os1_loadBeard), + OPCODE(os1_unloadBeard), + /* 184 */ + OPCODE(os1_unloadZone), + OPCODE(os1_loadStrings), + OPCODE(os1_unfreezeZones), + OPCODE(os1_specialFade), + }; + + _opcodesSimon1 = opcodes; + _numOpcodes = 188; +} + +void AGOSEngine_Simon1::executeOpcode(int opcode) { + OpcodeProcSimon1 op = _opcodesSimon1[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Simon 1 Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::os1_animate() { +void AGOSEngine_Simon1::os1_animate() { // 98: animate - uint vgaSpriteId = getVarOrWord(); - uint windowNum = getVarOrByte(); - uint x = getVarOrWord(); - uint y = getVarOrWord(); - uint palette = getVarOrWord(); + uint16 vgaSpriteId = getVarOrWord(); + uint16 windowNum = getVarOrByte(); + int16 x = getVarOrWord(); + int16 y = getVarOrWord(); + uint16 palette = (getVarOrWord() & 15); if (getFeatures() & GF_TALKIE && vgaSpriteId >= 400) { _lastVgaWaitFor = 0; @@ -92,19 +304,7 @@ void AGOSEngine::os1_animate() { _lockWord &= ~0x40; } -void AGOSEngine::os1_playTune() { - // 127: play tune - int music = getVarOrWord(); - int track = getVarOrWord(); - - if (music != _lastMusicPlayed) { - _lastMusicPlayed = music; - loadMusic(music); - _midi.startTrack(track); - } -} - -void AGOSEngine::os1_pauseGame() { +void AGOSEngine_Simon1::os1_pauseGame() { // 135: pause game _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); @@ -158,7 +358,7 @@ void AGOSEngine::os1_pauseGame() { _system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false); } -void AGOSEngine::os1_screenTextBox() { +void AGOSEngine_Simon1::os1_screenTextBox() { // 161: setup text TextLocation *tl = getTextLocation(getVarOrByte()); @@ -167,7 +367,7 @@ void AGOSEngine::os1_screenTextBox() { tl->width = getVarOrWord(); } -void AGOSEngine::os1_screenTextMsg() { +void AGOSEngine_Simon1::os1_screenTextMsg() { // 162: print string uint vgaSpriteId = getVarOrByte(); uint color = getVarOrByte(); @@ -202,7 +402,7 @@ void AGOSEngine::os1_screenTextMsg() { } -void AGOSEngine::os1_playEffect() { +void AGOSEngine_Simon1::os1_playEffect() { // 163: play sound uint soundId = getVarOrWord(); @@ -212,7 +412,7 @@ void AGOSEngine::os1_playEffect() { _sound->playEffects(soundId); } -void AGOSEngine::os1_screenTextPObj() { +void AGOSEngine_Simon1::os1_screenTextPObj() { // 177: inventory descriptions uint vgaSpriteId = getVarOrByte(); uint color = getVarOrByte(); @@ -253,7 +453,7 @@ void AGOSEngine::os1_screenTextPObj() { } } -void AGOSEngine::os1_getPathPosn() { +void AGOSEngine_Simon1::os1_getPathPosn() { // 178: path find uint x = getVarOrWord(); uint y = getVarOrWord(); @@ -302,7 +502,7 @@ void AGOSEngine::os1_getPathPosn() { writeVariable(var_2, best_j); } -void AGOSEngine::os1_scnTxtLongText() { +void AGOSEngine_Simon1::os1_scnTxtLongText() { // 179: conversation responses and room descriptions uint vgaSpriteId = getVarOrByte(); uint color = getVarOrByte(); @@ -324,17 +524,17 @@ void AGOSEngine::os1_scnTxtLongText() { printScreenText(vgaSpriteId, color, string_ptr, tl->x, tl->y, tl->width); } -void AGOSEngine::os1_mouseOn() { +void AGOSEngine_Simon1::os1_mouseOn() { // 180: force mouseOn _mouseHideCount = 0; } -void AGOSEngine::os1_mouseOff() { +void AGOSEngine_Simon1::os1_mouseOff() { // 181: force mouseOff scriptMouseOff(); } -void AGOSEngine::os1_loadBeard() { +void AGOSEngine_Simon1::os1_loadBeard() { // 182: load beard if (_beardLoaded == false) { _beardLoaded = true; @@ -344,7 +544,7 @@ void AGOSEngine::os1_loadBeard() { } } -void AGOSEngine::os1_unloadBeard() { +void AGOSEngine_Simon1::os1_unloadBeard() { // 183: unload beard if (_beardLoaded == true) { _beardLoaded = false; @@ -354,7 +554,7 @@ void AGOSEngine::os1_unloadBeard() { } } -void AGOSEngine::os1_unloadZone() { +void AGOSEngine_Simon1::os1_unloadZone() { // 184: unload zone uint a = getVarOrWord(); VgaPointersEntry *vpe = &_vgaBufferPointers[a]; @@ -364,7 +564,7 @@ void AGOSEngine::os1_unloadZone() { vpe->vgaFile2 = NULL; } -void AGOSEngine::os1_loadStrings() { +void AGOSEngine_Simon1::os1_loadStrings() { // 185: load sound files _soundFileId = getVarOrWord(); if (getPlatform() == Common::kPlatformAmiga && getFeatures() & GF_TALKIE) { @@ -376,12 +576,12 @@ void AGOSEngine::os1_loadStrings() { } } -void AGOSEngine::os1_unfreezeZones() { +void AGOSEngine_Simon1::os1_unfreezeZones() { // 186: freeze zone unfreezeBottom(); } -void AGOSEngine::os1_specialFade() { +void AGOSEngine_Simon1::os1_specialFade() { // 187: fade to black uint i; diff --git a/engines/agos/script_s2.cpp b/engines/agos/script_s2.cpp index ddcc1132eb..9d61f377a0 100644 --- a/engines/agos/script_s2.cpp +++ b/engines/agos/script_s2.cpp @@ -27,55 +27,272 @@ namespace AGOS { -void AGOSEngine::setupSimon2Opcodes(OpcodeProc *op) { - setupCommonOpcodes(op); - - op[65] = &AGOSEngine::oww_addTextBox; - op[66] = &AGOSEngine::oww_setShortText; - op[67] = &AGOSEngine::oww_setLongText; - op[70] = &AGOSEngine::os2_printLongText; - op[83] = &AGOSEngine::os2_rescan; - op[88] = &AGOSEngine::o_haltAnimation; - op[89] = &AGOSEngine::o_restartAnimation; - op[98] = &AGOSEngine::os2_animate; - op[99] = &AGOSEngine::os2_stopAnimate; - op[127] = &AGOSEngine::os2_playTune; - op[135] = &AGOSEngine::os1_pauseGame; - op[161] = &AGOSEngine::os1_screenTextBox; - op[162] = &AGOSEngine::os1_screenTextMsg; - op[163] = &AGOSEngine::os1_playEffect; - op[164] = &AGOSEngine::oe2_getDollar2; - op[165] = &AGOSEngine::oe2_isAdjNoun; - op[166] = &AGOSEngine::oe2_b2Set; - op[167] = &AGOSEngine::oe2_b2Clear; - op[168] = &AGOSEngine::oe2_b2Zero; - op[169] = &AGOSEngine::oe2_b2NotZero; - op[175] = &AGOSEngine::oww_lockZones; - op[176] = &AGOSEngine::oww_unlockZones; - op[177] = &AGOSEngine::os2_screenTextPObj; - op[178] = &AGOSEngine::os1_getPathPosn; - op[179] = &AGOSEngine::os1_scnTxtLongText; - op[180] = &AGOSEngine::os2_mouseOn; - op[181] = &AGOSEngine::os2_mouseOff; - op[184] = &AGOSEngine::os1_unloadZone; - op[186] = &AGOSEngine::os1_unfreezeZones; - op[188] = &AGOSEngine::os2_isShortText; - op[189] = &AGOSEngine::os2_clearMarks; - op[190] = &AGOSEngine::os2_waitMark; +#define OPCODE(x) _OPCODE(AGOSEngine_Simon2, x) + +void AGOSEngine_Simon2::setupOpcodes() { + static const OpcodeEntrySimon2 opcodes[] = { + /* 00 */ + OPCODE(o_invalid), + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(o_invalid), + /* 04 */ + OPCODE(o_invalid), + OPCODE(o_carried), + OPCODE(o_notCarried), + OPCODE(o_isAt), + /* 08 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_zero), + /* 12 */ + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + OPCODE(o_gt), + /* 16 */ + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + OPCODE(o_ltf), + /* 20 */ + OPCODE(o_gtf), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_chance), + /* 24 */ + OPCODE(o_invalid), + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + /* 28 */ + OPCODE(o_oflag), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_destroy), + /* 32 */ + OPCODE(o_invalid), + OPCODE(o_place), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 36 */ + OPCODE(o_copyff), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_clear), + OPCODE(o_let), + OPCODE(o_add), + /* 44 */ + OPCODE(o_sub), + OPCODE(o_addf), + OPCODE(o_subf), + OPCODE(o_mul), + /* 48 */ + OPCODE(o_div), + OPCODE(o_mulf), + OPCODE(o_divf), + OPCODE(o_mod), + /* 52 */ + OPCODE(o_modf), + OPCODE(o_random), + OPCODE(o_invalid), + OPCODE(o_goto), + /* 56 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_putBy), + OPCODE(o_inc), + /* 60 */ + OPCODE(o_dec), + OPCODE(o_setState), + OPCODE(o_print), + OPCODE(o_message), + /* 64 */ + OPCODE(o_msg), + OPCODE(oww_addTextBox), + OPCODE(oww_setShortText), + OPCODE(oww_setLongText), + /* 68 */ + OPCODE(o_end), + OPCODE(o_done), + OPCODE(os2_printLongText), + OPCODE(o_process), + /* 72 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 76 */ + OPCODE(o_when), + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(o_isCalled), + /* 80 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_debug), + OPCODE(os2_rescan), + /* 84 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_comment), + /* 88 */ + OPCODE(o_haltAnimation), + OPCODE(o_restartAnimation), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 92 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 96 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(os2_animate), + OPCODE(os2_stopAnimate), + /* 100 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 104 */ + OPCODE(o_closeWindow), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_addBox), + /* 108 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 112 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 116 */ + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 120 */ + OPCODE(o_sync), + OPCODE(o_defObj), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 124 */ + OPCODE(o_invalid), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(os2_playTune), + /* 128 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(o_invalid), + /* 132 */ + OPCODE(o_saveUserGame), + OPCODE(o_loadUserGame), + OPCODE(o_invalid), + OPCODE(os1_pauseGame), + /* 136 */ + OPCODE(o_copysf), + OPCODE(o_restoreIcons), + OPCODE(o_freezeZones), + OPCODE(o_placeNoIcons), + /* 140 */ + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox), + OPCODE(oe2_doTable), + /* 144 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 148 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe2_storeItem), + /* 152 */ + OPCODE(oe2_getItem), + OPCODE(oe2_bSet), + OPCODE(oe2_bClear), + OPCODE(oe2_bZero), + /* 156C */ + OPCODE(oe2_bNotZero), + OPCODE(oe2_getOValue), + OPCODE(oe2_setOValue), + OPCODE(o_invalid), + /* 160 */ + OPCODE(oe2_ink), + OPCODE(os1_screenTextBox), + OPCODE(os1_screenTextMsg), + OPCODE(os1_playEffect), + /* 164 */ + OPCODE(oe2_getDollar2), + OPCODE(oe2_isAdjNoun), + OPCODE(oe2_b2Set), + OPCODE(oe2_b2Clear), + /* 168 */ + OPCODE(oe2_b2Zero), + OPCODE(oe2_b2NotZero), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 172 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oww_lockZones), + /* 176 */ + OPCODE(oww_unlockZones), + OPCODE(os2_screenTextPObj), + OPCODE(os1_getPathPosn), + OPCODE(os1_scnTxtLongText), + /* 180 */ + OPCODE(os2_mouseOn), + OPCODE(os2_mouseOff), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 184 */ + OPCODE(os1_unloadZone), + OPCODE(o_invalid), + OPCODE(os1_unfreezeZones), + OPCODE(o_invalid), + /* 188 */ + OPCODE(os2_isShortText), + OPCODE(os2_clearMarks), + OPCODE(os2_waitMark), + }; + + _opcodesSimon2 = opcodes; + _numOpcodes = 191; +} + +void AGOSEngine_Simon2::executeOpcode(int opcode) { + OpcodeProcSimon2 op = _opcodesSimon2[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Simon 2 Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::os2_printLongText() { +void AGOSEngine_Simon2::os2_printLongText() { // 70: show string from array const char *str = (const char *)getStringPtrByID(_longText[getVarOrByte()]); writeVariable(51, strlen(str) / 53 * 8 + 8); showMessageFormat("%s\n", str); } -void AGOSEngine::os2_rescan() { +void AGOSEngine_Simon2::os2_rescan() { // 83: restart subroutine if (_exitCutscene) { if (getBitFlag(9)) { @@ -88,28 +305,28 @@ void AGOSEngine::os2_rescan() { setScriptReturn(-10); } -void AGOSEngine::os2_animate() { +void AGOSEngine_Simon2::os2_animate() { // 98: start vga - uint zoneNum = getVarOrWord(); - uint vgaSpriteId = getVarOrWord(); - uint windowNum = getVarOrByte(); - uint x = getVarOrWord(); - uint y = getVarOrWord(); - uint palette = getVarOrWord(); + uint16 zoneNum = getVarOrWord(); + uint16 vgaSpriteId = getVarOrWord(); + uint16 windowNum = getVarOrByte(); + int16 x = getVarOrWord(); + int16 y = getVarOrWord(); + uint16 palette = (getVarOrWord() & 15); _lockWord |= 0x40; animate(windowNum, zoneNum, vgaSpriteId, x, y, palette); _lockWord &= ~0x40; } -void AGOSEngine::os2_stopAnimate() { +void AGOSEngine_Simon2::os2_stopAnimate() { // 99: kill sprite uint a = getVarOrWord(); uint b = getVarOrWord(); stopAnimateSimon2(a, b); } -void AGOSEngine::os2_playTune() { +void AGOSEngine_Simon2::os2_playTune() { // 127: deals with music int music = getVarOrWord(); int track = getVarOrWord(); @@ -131,7 +348,7 @@ void AGOSEngine::os2_playTune() { _midi.startTrack(track); } -void AGOSEngine::os2_screenTextPObj() { +void AGOSEngine_Simon2::os2_screenTextPObj() { // 177: inventory descriptions uint vgaSpriteId = getVarOrByte(); uint color = getVarOrByte(); @@ -216,7 +433,7 @@ void AGOSEngine::os2_screenTextPObj() { } } -void AGOSEngine::os2_mouseOn() { +void AGOSEngine_Simon2::os2_mouseOn() { // 180: force mouseOn if (getGameType() == GType_SIMON2 && getBitFlag(79)) { _mouseCursor = 0; @@ -224,26 +441,26 @@ void AGOSEngine::os2_mouseOn() { _mouseHideCount = 0; } -void AGOSEngine::os2_mouseOff() { +void AGOSEngine_Simon2::os2_mouseOff() { // 181: force mouseOff scriptMouseOff(); changeWindow(1); showMessageFormat("\xC"); } -void AGOSEngine::os2_isShortText() { +void AGOSEngine_Simon2::os2_isShortText() { // 188: string2 is uint i = getVarOrByte(); uint str = getNextStringID(); setScriptCondition(str < _numTextBoxes && _shortText[i] == str); } -void AGOSEngine::os2_clearMarks() { +void AGOSEngine_Simon2::os2_clearMarks() { // 189: clear_op189_flag _marks = 0; } -void AGOSEngine::os2_waitMark() { +void AGOSEngine_Simon2::os2_waitMark() { // 190 uint i = getVarOrByte(); if (!(_marks & (1 << i))) diff --git a/engines/agos/script_ww.cpp b/engines/agos/script_ww.cpp index 5b192a4199..5edcf1621d 100644 --- a/engines/agos/script_ww.cpp +++ b/engines/agos/script_ww.cpp @@ -29,70 +29,265 @@ namespace AGOS { -void AGOSEngine::setupWaxworksOpcodes(OpcodeProc *op) { - setupCommonOpcodes(op); - - op[8] = &AGOSEngine::oe1_isNotAt; - op[9] = &AGOSEngine::oe1_sibling; - op[10] = &AGOSEngine::oe1_notSibling; - op[21] = &AGOSEngine::oe1_isIn; - op[22] = &AGOSEngine::oe1_isNotIn; - op[24] = &AGOSEngine::oe1_isPlayer; - op[29] = &AGOSEngine::oe1_canPut; - op[34] = &AGOSEngine::oe1_copyof; - op[37] = &AGOSEngine::oe1_whatO; - op[35] = &AGOSEngine::oe1_copyfo; - op[39] = &AGOSEngine::oe1_weigh; - op[54] = &AGOSEngine::oww_moveDirn; - op[55] = &AGOSEngine::oww_goto; - op[65] = &AGOSEngine::oww_addTextBox; - op[66] = &AGOSEngine::oww_setShortText; - op[67] = &AGOSEngine::oww_setLongText; - op[70] = &AGOSEngine::oww_printLongText; - op[83] = &AGOSEngine::oe1_rescan; - op[85] = &AGOSEngine::oww_whereTo; - op[89] = &AGOSEngine::oe2_loadGame; - op[94] = &AGOSEngine::oe1_findMaster; - op[95] = &AGOSEngine::oe1_nextMaster; - op[98] = &AGOSEngine::oe1_animate; - op[99] = &AGOSEngine::oe1_stopAnimate; - op[105] = &AGOSEngine::oww_menu; - op[106] = &AGOSEngine::oww_textMenu; - op[127] = &AGOSEngine::os1_playTune; - op[135] = &AGOSEngine::oww_pauseGame; - op[144] = &AGOSEngine::oe2_setDoorOpen; - op[145] = &AGOSEngine::oe2_setDoorClosed; - op[146] = &AGOSEngine::oe2_setDoorLocked; - op[147] = &AGOSEngine::oe2_setDoorClosed; - op[148] = &AGOSEngine::oe2_ifDoorOpen; - op[149] = &AGOSEngine::oe2_ifDoorClosed; - op[150] = &AGOSEngine::oe2_ifDoorLocked; - op[175] = &AGOSEngine::oe2_getDollar2; - op[179] = &AGOSEngine::oe2_isAdjNoun; - op[180] = &AGOSEngine::oe2_b2Set; - op[181] = &AGOSEngine::oe2_b2Clear; - op[182] = &AGOSEngine::oe2_b2Zero; - op[183] = &AGOSEngine::oe2_b2NotZero; - op[184] = &AGOSEngine::oww_boxMessage; - op[185] = &AGOSEngine::oww_boxMsg; - op[186] = &AGOSEngine::oww_boxLongText; - op[187] = &AGOSEngine::oww_printBox; - op[188] = &AGOSEngine::oww_boxPObj; - op[189] = &AGOSEngine::oww_lockZones; - op[190] = &AGOSEngine::oww_unlockZones; +#define OPCODE(x) _OPCODE(AGOSEngine_Waxworks, x) + +void AGOSEngine_Waxworks::setupOpcodes() { + static const OpcodeEntryWaxworks opcodes[] = { + /* 00 */ + OPCODE(o_invalid), + OPCODE(o_at), + OPCODE(o_notAt), + OPCODE(o_invalid), + /* 04 */ + OPCODE(o_invalid), + OPCODE(o_carried), + OPCODE(o_notCarried), + OPCODE(o_isAt), + /* 08 */ + OPCODE(oe1_isNotAt), + OPCODE(oe1_sibling), + OPCODE(oe1_notSibling), + OPCODE(o_zero), + /* 12 */ + OPCODE(o_notZero), + OPCODE(o_eq), + OPCODE(o_notEq), + OPCODE(o_gt), + /* 16 */ + OPCODE(o_lt), + OPCODE(o_eqf), + OPCODE(o_notEqf), + OPCODE(o_ltf), + /* 20 */ + OPCODE(o_gtf), + OPCODE(oe1_isIn), + OPCODE(oe1_isNotIn), + OPCODE(o_chance), + /* 24 */ + OPCODE(oe1_isPlayer), + OPCODE(o_isRoom), + OPCODE(o_isObject), + OPCODE(o_state), + /* 28 */ + OPCODE(o_oflag), + OPCODE(oe1_canPut), + OPCODE(o_invalid), + OPCODE(o_destroy), + /* 32 */ + OPCODE(o_invalid), + OPCODE(o_place), + OPCODE(oe1_copyof), + OPCODE(oe1_copyfo), + /* 36 */ + OPCODE(o_copyff), + OPCODE(oe1_whatO), + OPCODE(o_invalid), + OPCODE(oe1_weigh), + /* 40 */ + OPCODE(o_invalid), + OPCODE(o_clear), + OPCODE(o_let), + OPCODE(o_add), + /* 44 */ + OPCODE(o_sub), + OPCODE(o_addf), + OPCODE(o_subf), + OPCODE(o_mul), + /* 48 */ + OPCODE(o_div), + OPCODE(o_mulf), + OPCODE(o_divf), + OPCODE(o_mod), + /* 52 */ + OPCODE(o_modf), + OPCODE(o_random), + OPCODE(oe2_moveDirn), + OPCODE(oww_goto), + /* 56 */ + OPCODE(o_oset), + OPCODE(o_oclear), + OPCODE(o_putBy), + OPCODE(o_inc), + /* 60 */ + OPCODE(o_dec), + OPCODE(o_setState), + OPCODE(o_print), + OPCODE(o_message), + /* 64 */ + OPCODE(o_msg), + OPCODE(oww_addTextBox), + OPCODE(oww_setShortText), + OPCODE(oww_setLongText), + /* 68 */ + OPCODE(o_end), + OPCODE(o_done), + OPCODE(o_invalid), + OPCODE(o_process), + /* 72 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 76 */ + OPCODE(o_when), + OPCODE(o_if1), + OPCODE(o_if2), + OPCODE(o_isCalled), + /* 80 */ + OPCODE(o_is), + OPCODE(o_invalid), + OPCODE(o_debug), + OPCODE(oe1_rescan), + /* 84 */ + OPCODE(o_invalid), + OPCODE(oww_whereTo), + OPCODE(o_invalid), + OPCODE(o_comment), + /* 88 */ + OPCODE(o_invalid), + OPCODE(oe1_loadGame), + OPCODE(o_getParent), + OPCODE(o_getNext), + /* 92 */ + OPCODE(o_getChildren), + OPCODE(o_invalid), + OPCODE(oe1_findMaster), + OPCODE(oe1_nextMaster), + /* 96 */ + OPCODE(o_picture), + OPCODE(o_loadZone), + OPCODE(oe1_animate), + OPCODE(oe1_stopAnimate), + /* 100 */ + OPCODE(o_killAnimate), + OPCODE(o_defWindow), + OPCODE(o_window), + OPCODE(o_cls), + /* 104 */ + OPCODE(o_closeWindow), + OPCODE(oww_menu), + OPCODE(oww_textMenu), + OPCODE(o_addBox), + /* 108 */ + OPCODE(o_delBox), + OPCODE(o_enableBox), + OPCODE(o_disableBox), + OPCODE(o_moveBox), + /* 112 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_doIcons), + OPCODE(o_isClass), + /* 116 */ + OPCODE(o_setClass), + OPCODE(o_unsetClass), + OPCODE(o_invalid), + OPCODE(o_waitSync), + /* 120 */ + OPCODE(o_sync), + OPCODE(o_defObj), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 124 */ + OPCODE(o_invalid), + OPCODE(o_here), + OPCODE(o_doClassIcons), + OPCODE(o_playTune), + /* 128 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_setAdjNoun), + OPCODE(o_invalid), + /* 132 */ + OPCODE(o_saveUserGame), + OPCODE(o_loadUserGame), + OPCODE(o_invalid), + OPCODE(oww_pauseGame), + /* 136 */ + OPCODE(o_copysf), + OPCODE(o_restoreIcons), + OPCODE(o_freezeZones), + OPCODE(o_placeNoIcons), + /* 140 */ + OPCODE(o_clearTimers), + OPCODE(o_setDollar), + OPCODE(o_isBox), + OPCODE(oe2_doTable), + /* 144 */ + OPCODE(oe2_setDoorOpen), + OPCODE(oe2_setDoorClosed), + OPCODE(oe2_setDoorLocked), + OPCODE(oe2_setDoorClosed), + /* 148 */ + OPCODE(oe2_ifDoorOpen), + OPCODE(oe2_ifDoorClosed), + OPCODE(oe2_ifDoorLocked), + OPCODE(oe2_storeItem), + /* 152 */ + OPCODE(oe2_getItem), + OPCODE(oe2_bSet), + OPCODE(oe2_bClear), + OPCODE(oe2_bZero), + /* 156 */ + OPCODE(oe2_bNotZero), + OPCODE(oe2_getOValue), + OPCODE(oe2_setOValue), + OPCODE(o_invalid), + /* 160 */ + OPCODE(oe2_ink), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 164 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 168 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + /* 172 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe2_getDollar2), + /* 176 */ + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(o_invalid), + OPCODE(oe2_isAdjNoun), + /* 180 */ + OPCODE(oe2_b2Set), + OPCODE(oe2_b2Clear), + OPCODE(oe2_b2Zero), + OPCODE(oe2_b2NotZero), + /* 184 */ + OPCODE(oww_boxMessage), + OPCODE(oww_boxMsg), + OPCODE(oww_boxLongText), + OPCODE(oww_printBox), + /* 188 */ + OPCODE(oww_boxPObj), + OPCODE(oww_lockZones), + OPCODE(oww_unlockZones), + }; + + _opcodesWaxworks = opcodes; + _numOpcodes = 191; +} + +void AGOSEngine_Waxworks::executeOpcode(int opcode) { + OpcodeProcWaxworks op = _opcodesWaxworks[opcode].proc; + (this->*op) (); } // ----------------------------------------------------------------------- // Waxworks Opcodes // ----------------------------------------------------------------------- -void AGOSEngine::oww_moveDirn() { - // 54: move direction - int16 d = getVarOrByte(); - moveDirn_ww(me(), d); -} - -void AGOSEngine::oww_goto() { +void AGOSEngine_Waxworks::oww_goto() { // 55: set itemA parent uint item = getNextItemID(); if (derefItem(item) == NULL) { @@ -102,7 +297,7 @@ void AGOSEngine::oww_goto() { setItemParent(me(), derefItem(item)); } -void AGOSEngine::oww_addTextBox() { +void AGOSEngine_Waxworks::oww_addTextBox() { // 65: add hit area uint id = getVarOrWord(); uint x = getVarOrWord(); @@ -114,7 +309,7 @@ void AGOSEngine::oww_addTextBox() { defineBox(id, x, y, w, h, (number << 8) + 129, 208, _dummyItem2); } -void AGOSEngine::oww_setShortText() { +void AGOSEngine_Waxworks::oww_setShortText() { // 66: set item name uint var = getVarOrByte(); uint stringId = getNextStringID(); @@ -123,7 +318,7 @@ void AGOSEngine::oww_setShortText() { } } -void AGOSEngine::oww_setLongText() { +void AGOSEngine_Waxworks::oww_setLongText() { // 67: set item description uint var = getVarOrByte(); uint stringId = getNextStringID(); @@ -140,13 +335,13 @@ void AGOSEngine::oww_setLongText() { } } -void AGOSEngine::oww_printLongText() { +void AGOSEngine_Waxworks::oww_printLongText() { // 70: show string from array const char *str = (const char *)getStringPtrByID(_longText[getVarOrByte()]); showMessageFormat("%s\n", str); } -void AGOSEngine::oww_whereTo() { +void AGOSEngine_Waxworks::oww_whereTo() { // 85: where to Item *i = getNextItemPtr(); int16 d = getVarOrByte(); @@ -158,18 +353,18 @@ void AGOSEngine::oww_whereTo() { _objectItem = derefItem(getExitOf(i, d)); } -void AGOSEngine::oww_menu() { +void AGOSEngine_Waxworks::oww_menu() { // 105: set agos menu _agosMenu = getVarOrByte(); } -void AGOSEngine::oww_textMenu() { +void AGOSEngine_Waxworks::oww_textMenu() { // 106: set text menu byte slot = getVarOrByte(); _textMenu[slot] = getVarOrByte(); } -void AGOSEngine::oww_pauseGame() { +void AGOSEngine_Waxworks::oww_pauseGame() { // 135: pause game HitArea *ha; @@ -200,27 +395,27 @@ void AGOSEngine::oww_pauseGame() { _gameStoppedClock = time(NULL) - pauseTime + _gameStoppedClock; } -void AGOSEngine::oww_boxMessage() { +void AGOSEngine_Waxworks::oww_boxMessage() { // 184: print message to box boxTextMessage((const char *)getStringPtrByID(getNextStringID())); } -void AGOSEngine::oww_boxMsg() { +void AGOSEngine_Waxworks::oww_boxMsg() { // 185: print msg to box boxTextMsg((const char *)getStringPtrByID(getNextStringID())); } -void AGOSEngine::oww_boxLongText() { +void AGOSEngine_Waxworks::oww_boxLongText() { // 186: print long text to box boxTextMsg((const char *)getStringPtrByID(_longText[getVarOrByte()])); } -void AGOSEngine::oww_printBox() { +void AGOSEngine_Waxworks::oww_printBox() { // 187: print box printBox(); } -void AGOSEngine::oww_boxPObj() { +void AGOSEngine_Waxworks::oww_boxPObj() { // 188: print object name to box SubObject *subObject = (SubObject *)findChildOfType(getNextItemPtr(), 2); @@ -228,12 +423,12 @@ void AGOSEngine::oww_boxPObj() { boxTextMsg((const char *)getStringPtrByID(subObject->objectFlagValue[0])); } -void AGOSEngine::oww_lockZones() { +void AGOSEngine_Waxworks::oww_lockZones() { // 189: lock zone _vgaMemBase = _vgaMemPtr; } -void AGOSEngine::oww_unlockZones() { +void AGOSEngine_Waxworks::oww_unlockZones() { // 190: unlock zone _vgaMemPtr = _vgaFrozenBase; _vgaMemBase = _vgaFrozenBase; diff --git a/engines/agos/sound.cpp b/engines/agos/sound.cpp index b11c130f87..1cfd465cd6 100644 --- a/engines/agos/sound.cpp +++ b/engines/agos/sound.cpp @@ -116,21 +116,21 @@ bool LoopingAudioStream::endOfData() const { class WavSound : public BaseSound { public: - WavSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {}; - WavSound(Audio::Mixer *mixer, File *file, uint32 *offsets) : BaseSound(mixer, file, offsets) {}; + WavSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {} + WavSound(Audio::Mixer *mixer, File *file, uint32 *offsets) : BaseSound(mixer, file, offsets) {} Audio::AudioStream *makeAudioStream(uint sound); void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0); }; class VocSound : public BaseSound { public: - VocSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {}; + VocSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {} void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0); }; class RawSound : public BaseSound { public: - RawSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {}; + RawSound(Audio::Mixer *mixer, File *file, uint32 base = 0, bool bigEndian = false) : BaseSound(mixer, file, base, bigEndian) {} void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0); }; @@ -267,7 +267,7 @@ void RawSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, #ifdef USE_MAD class MP3Sound : public BaseSound { public: - MP3Sound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}; + MP3Sound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {} Audio::AudioStream *makeAudioStream(uint sound); void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0); }; @@ -296,7 +296,7 @@ void MP3Sound::playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, #ifdef USE_VORBIS class VorbisSound : public BaseSound { public: - VorbisSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}; + VorbisSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {} Audio::AudioStream *makeAudioStream(uint sound); void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0); }; @@ -325,7 +325,7 @@ void VorbisSound::playSound(uint sound, uint loopSound, Audio::SoundHandle *hand #ifdef USE_FLAC class FlacSound : public BaseSound { public: - FlacSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {}; + FlacSound(Audio::Mixer *mixer, File *file, uint32 base = 0) : BaseSound(mixer, file, base) {} Audio::AudioStream *makeAudioStream(uint sound); void playSound(uint sound, uint loopSound, Audio::SoundHandle *handle, byte flags, int vol = 0); }; diff --git a/engines/agos/string.cpp b/engines/agos/string.cpp index ca376da718..2335d894ac 100644 --- a/engines/agos/string.cpp +++ b/engines/agos/string.cpp @@ -289,7 +289,160 @@ bool AGOSEngine::printNameOf(Item *item, uint x, uint y) { return true; } -void AGOSEngine::printInteractText(uint16 num, const char *string) { +void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { + char convertedString[320]; + char *convertedString2 = convertedString; + int16 height, talkDelay; + int stringLength = strlen(string); + int padding, lettersPerRow, lettersPerRowJustified; + const int textHeight = 10; + + height = textHeight; + lettersPerRow = width / 6; + lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1; + + talkDelay = (stringLength + 3) / 3; + if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) { + if (_variableArray[141] == 0) + _variableArray[141] = 9; + _variableArray[85] = _variableArray[141] * talkDelay; + } else { + if (_variableArray[86] == 0) + talkDelay /= 2; + if (_variableArray[86] == 2) + talkDelay *= 2; + _variableArray[85] = talkDelay * 5; + } + + assert(stringLength > 0); + + while (stringLength > 0) { + int pos = 0; + if (stringLength > lettersPerRow) { + int removeLastWord = 0; + if (lettersPerRow > lettersPerRowJustified) { + pos = lettersPerRowJustified; + while (string[pos] != ' ') + pos++; + if (pos > lettersPerRow) + removeLastWord = 1; + } + if (lettersPerRow <= lettersPerRowJustified || removeLastWord) { + pos = lettersPerRow; + while (string[pos] != ' ' && pos > 0) + pos--; + } + height += textHeight; + y -= textHeight; + } else + pos = stringLength; + padding = (lettersPerRow - pos) % 2 ? + (lettersPerRow - pos) / 2 + 1 : (lettersPerRow - pos) / 2; + while (padding--) + *convertedString2++ = ' '; + stringLength -= pos; + while (pos--) + *convertedString2++ = *string++; + *convertedString2++ = '\n'; + string++; // skip space + stringLength--; // skip space + } + *(convertedString2 - 1) = '\0'; + + if (getGameType() == GType_SIMON1) + stopAnimate(vgaSpriteId + 199); + else + stopAnimateSimon2(2, vgaSpriteId); + + if (getPlatform() == Common::kPlatformAmiga) { + color = color * 3 + 1; + renderStringAmiga(vgaSpriteId, color, width, height, convertedString); + } else { + color = color * 3 + 192; + renderString(vgaSpriteId, color, width, height, convertedString); + } + + int b = (!getBitFlag(133)) ? 3 : 4; + + x /= 8; + if (y < 2) + y = 2; + + if (getGameType() == GType_SIMON1) + animate(b, 2, vgaSpriteId + 199, x, y, 12); + else + animate(b, 2, vgaSpriteId, x, y, 12); +} + +// The Feeble Files specific +void AGOSEngine_Feeble::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { + char convertedString[320]; + char *convertedString2 = convertedString; + const char *string2 = string; + int16 height, talkDelay; + int stringLength = strlen(string); + int lettersPerRow, lettersPerRowJustified; + const int textHeight = 15; + + height = textHeight; + lettersPerRow = width / 6; + lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1; + + talkDelay = (stringLength + 3) / 3; + if (_variableArray[86] == 0) + talkDelay /= 2; + if (_variableArray[86] == 2) + talkDelay *= 2; + _variableArray[85] = talkDelay * 5; + + assert(stringLength > 0); + + uint16 b, pixels, spaces; + + while (1) { + string2 = getPixelLength(string, width, pixels); + if (*string2 == 0) { + spaces = (width - pixels) / 12; + if (spaces != 0) + spaces--; + while (spaces) { + *convertedString2++ = ' '; + spaces--; + } + strcpy(convertedString2, string); + break; + } + while (*string2 != ' ') { + byte chr = *string2; + pixels -= charWidth[chr]; + string2--; + } + spaces = (width - pixels) / 12; + if (spaces != 0) + spaces--; + while (spaces) { + *convertedString2++ = ' '; + spaces--; + } + b = string2 - string; + strncpy(convertedString2, string, b); + convertedString2 += b; + *convertedString2++ = '\n'; + height += textHeight; + y -= textHeight; + if (y < 2) + y = 2; + string = string2; + } + + stopAnimateSimon2(2, vgaSpriteId); + + renderString(1, color, width, height, convertedString); + + animate(4, 2, vgaSpriteId, x, y, 12); +} + +void AGOSEngine_Feeble::printInteractText(uint16 num, const char *string) { char convertedString[320]; char *convertedString2 = convertedString; const char *string2 = string; @@ -344,7 +497,7 @@ void AGOSEngine::printInteractText(uint16 num, const char *string) { _interactY += height; } -void AGOSEngine::sendInteractText(uint16 num, const char *fmt, ...) { +void AGOSEngine_Feeble::sendInteractText(uint16 num, const char *fmt, ...) { va_list arglist; char string[256]; @@ -355,142 +508,8 @@ void AGOSEngine::sendInteractText(uint16 num, const char *fmt, ...) { printInteractText(num, string); } -void AGOSEngine::printScreenText(uint vgaSpriteId, uint color, const char *string, int16 x, int16 y, int16 width) { - char convertedString[320]; - char *convertedString2 = convertedString; - const char *string2 = string; - int16 height, talkDelay; - int stringLength = strlen(string); - int padding, lettersPerRow, lettersPerRowJustified; - const int textHeight = (getGameType() == GType_FF) ? 15: 10; - - height = textHeight; - lettersPerRow = width / 6; - lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1; - - talkDelay = (stringLength + 3) / 3; - if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) { - if (_variableArray[141] == 0) - _variableArray[141] = 9; - _variableArray[85] = _variableArray[141] * talkDelay; - } else { - if (_variableArray[86] == 0) - talkDelay /= 2; - if (_variableArray[86] == 2) - talkDelay *= 2; - _variableArray[85] = talkDelay * 5; - } - - assert(stringLength > 0); - - if (getGameType() == GType_FF) { - uint16 b, pixels, spaces; - - while (1) { - string2 = getPixelLength(string, width, pixels); - if (*string2 == 0) { - spaces = (width - pixels) / 12; - if (spaces != 0) - spaces--; - while (spaces) { - *convertedString2++ = ' '; - spaces--; - } - strcpy(convertedString2, string); - break; - } - while (*string2 != ' ') { - byte chr = *string2; - pixels -= charWidth[chr]; - string2--; - } - spaces = (width - pixels) / 12; - if (spaces != 0) - spaces--; - while (spaces) { - *convertedString2++ = ' '; - spaces--; - } - b = string2 - string; - strncpy(convertedString2, string, b); - convertedString2 += b; - *convertedString2++ = '\n'; - height += textHeight; - y -= textHeight; - if (y < 2) - y = 2; - string = string2; - } - } else { - while (stringLength > 0) { - int pos = 0; - if (stringLength > lettersPerRow) { - int removeLastWord = 0; - if (lettersPerRow > lettersPerRowJustified) { - pos = lettersPerRowJustified; - while (string[pos] != ' ') - pos++; - if (pos > lettersPerRow) - removeLastWord = 1; - } - if (lettersPerRow <= lettersPerRowJustified || removeLastWord) { - pos = lettersPerRow; - while (string[pos] != ' ' && pos > 0) - pos--; - } - height += textHeight; - y -= textHeight; - } else - pos = stringLength; - padding = (lettersPerRow - pos) % 2 ? - (lettersPerRow - pos) / 2 + 1 : (lettersPerRow - pos) / 2; - while (padding--) - *convertedString2++ = ' '; - stringLength -= pos; - while (pos--) - *convertedString2++ = *string++; - *convertedString2++ = '\n'; - string++; // skip space - stringLength--; // skip space - } - *(convertedString2 - 1) = '\0'; - } - - if (getGameType() == GType_SIMON1) - stopAnimate(vgaSpriteId + 199); - else - stopAnimateSimon2(2, vgaSpriteId); - - if (getGameType() == GType_FF) { - renderString(1, color, width, height, convertedString); - } else { - if (getPlatform() == Common::kPlatformAmiga) { - color = color * 3 + 1; - renderStringAmiga(vgaSpriteId, color, width, height, convertedString); - } else { - color = color * 3 + 192; - renderString(vgaSpriteId, color, width, height, convertedString); - } - } - - int b = 4; - if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - if (!getBitFlag(133)) - b = 3; - - x /= 8; - if (y < 2) - y = 2; - } - - if (getGameType() == GType_SIMON1) - animate(b, 2, vgaSpriteId + 199, x, y, 12); - else - animate(b, 2, vgaSpriteId, x, y, 12); -} - -// String code for boxes in Waxworks -uint16 AGOSEngine::getBoxSize() { +// Waxworks specific +uint16 AGOSEngine_Waxworks::getBoxSize() { int x; switch (_boxLineCount) { case 1: x = _lineCounts[0]; @@ -634,7 +653,7 @@ uint16 AGOSEngine::getBoxSize() { } -uint16 AGOSEngine::checkFit(char *Ptr, int width, int lines) { +uint16 AGOSEngine_Waxworks::checkFit(char *Ptr, int width, int lines) { int countw = 0; int countl = 0; char *x = NULL; @@ -659,27 +678,26 @@ uint16 AGOSEngine::checkFit(char *Ptr, int width, int lines) { return 1; } -void AGOSEngine::boxTextMessage(const char *x) { - char *BoxBufferPtr = _boxBuffer; - sprintf(BoxBufferPtr, "%s\n", x); +void AGOSEngine_Waxworks::boxTextMessage(const char *x) { + sprintf(_boxBufferPtr, "%s\n", x); _lineCounts[_boxLineCount] += strlen(x); - BoxBufferPtr += strlen(x) + 1; + _boxBufferPtr += strlen(x) + 1; _boxLineCount++; - _linePtrs[_boxLineCount] = BoxBufferPtr; + _linePtrs[_boxLineCount] = _boxBufferPtr; _boxCR = 1; } -void AGOSEngine::boxTextMsg(const char *x) { - char *BoxBufferPtr = _boxBuffer; - sprintf(BoxBufferPtr, "%s", x); +void AGOSEngine_Waxworks::boxTextMsg(const char *x) { + sprintf(_boxBufferPtr, "%s", x); _lineCounts[_boxLineCount] += strlen(x); - BoxBufferPtr += strlen(x); + _boxBufferPtr += strlen(x); _boxCR = 0; } -void AGOSEngine::printBox() { - char *BoxBufferPtr = 0; +void AGOSEngine_Waxworks::printBox() { uint16 BoxSize; + + *_boxBufferPtr = 0; _linePtrs[0] = _boxBuffer; if (_boxCR == 0) _boxLineCount++; @@ -733,11 +751,11 @@ void AGOSEngine::printBox() { _textWindow->textLength = 0; justifyStart(); waitForSync(99); - BoxBufferPtr = _boxBuffer; - while (*BoxBufferPtr) - justifyOutPut(*BoxBufferPtr++); + _boxBufferPtr = _boxBuffer; + while (*_boxBufferPtr) + justifyOutPut(*_boxBufferPtr++); _boxLineCount = 0; - BoxBufferPtr = _boxBuffer; + _boxBufferPtr = _boxBuffer; _lineCounts[0] = 0; _lineCounts[1] = 0; _lineCounts[2] = 0; @@ -747,39 +765,4 @@ void AGOSEngine::printBox() { changeWindow(0); } -// String code for statistics in Elvira 1/2 -void AGOSEngine::writeChar(WindowBlock *window, int x, int y, int offs, int val) { - int chr; - - // Clear background of first digit - window->textColumnOffset = offs; - window->text_color = 0; - windowDrawChar(window, x * 8, y, 129); - - if (val != -1) { - // Print first digit - chr = val / 10 + 48; - window->text_color = 15; - windowDrawChar(window, x * 8, y, chr); - } - - offs += 6; - if (offs >= 7) { - offs -= 8; - x++; - } - - // Clear background of second digit - window->textColumnOffset = offs; - window->text_color = 0; - windowDrawChar(window, x * 8, y, 129); - - if (val != -1) { - // Print second digit - chr = val % 10 + 48; - window->text_color = 15; - windowDrawChar(window, x * 8, y, chr); - } -} - } // End of namespace AGOS diff --git a/engines/agos/subroutine.cpp b/engines/agos/subroutine.cpp index a876c5402a..8ab0c49110 100644 --- a/engines/agos/subroutine.cpp +++ b/engines/agos/subroutine.cpp @@ -287,14 +287,6 @@ File *AGOSEngine::openTablesFile_gme(const char *filename) { } bool AGOSEngine::loadTablesIntoMem(uint subr_id) { - if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) - return loadTablesOldIntoMem(subr_id); - else - return loadTablesNewIntoMem(subr_id); -} - - -bool AGOSEngine::loadTablesOldIntoMem(uint subr_id) { byte *p; uint16 min_num, max_num, file_num; File *in; @@ -329,7 +321,7 @@ bool AGOSEngine::loadTablesOldIntoMem(uint subr_id) { _tablesHeapCurPosNew = _tablesHeapCurPos; if (_tablesHeapCurPos > _tablesHeapSize) - error("loadTablesOldIntoMem: Out of table memory"); + error("loadTablesIntoMem: Out of table memory"); return 1; } @@ -339,11 +331,11 @@ bool AGOSEngine::loadTablesOldIntoMem(uint subr_id) { p += 6; } - debug(1,"loadTablesOldIntoMem: didn't find %d", subr_id); + debug(1,"loadTablesIntoMem: didn't find %d", subr_id); return 0; } -bool AGOSEngine::loadTablesNewIntoMem(uint subr_id) { +bool AGOSEngine_Waxworks::loadTablesIntoMem(uint subr_id) { byte *p; int i; uint min_num, max_num; @@ -395,13 +387,13 @@ bool AGOSEngine::loadTablesNewIntoMem(uint subr_id) { _tablesHeapCurPosNew = _tablesHeapCurPos; if (_tablesHeapCurPos > _tablesHeapSize) - error("loadTablesNewIntoMem: Out of table memory"); + error("loadTablesIntoMem: Out of table memory"); return 1; } } } - debug(1,"loadTablesNewIntoMem: didn't find %d", subr_id); + debug(1,"loadTablesIntoMem: didn't find %d", subr_id); return 0; } @@ -527,16 +519,6 @@ int AGOSEngine::startSubroutine(Subroutine *sub) { int result = -1; SubroutineLine *sl = (SubroutineLine *)((byte *)sub + sub->first); - // WORKAROUND: Bit Flag 171 isn't set when Simon rides the lion to the - // goblin camp in non-English versions. Bit Flag 171 is required to display - // the red trail between locations on the map, during the ride. - if (getGameType() == GType_SIMON2) { - if (sub->id == 13020) - setBitFlag(171, true); - if (sub->id == 13021) - setBitFlag(171, false); - } - const byte *old_code_ptr = _codePtr; Subroutine *old_currentTable = _currentTable; SubroutineLine *old_currentLine = _currentLine; diff --git a/engines/agos/verb.cpp b/engines/agos/verb.cpp index 59d75b4061..124065eaeb 100644 --- a/engines/agos/verb.cpp +++ b/engines/agos/verb.cpp @@ -176,6 +176,14 @@ static const char *const english_verb_prep_names[] = { "", "", "", "to whom ?" }; +void AGOSEngine_Feeble::clearName() { + stopAnimateSimon2(2, 6); + _lastNameOn = NULL; + _animatePointer = 0; + _mouseAnim = 1; + return; +} + void AGOSEngine::clearName() { if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) return; @@ -186,14 +194,6 @@ void AGOSEngine::clearName() { HitArea *last; HitArea *ha; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - stopAnimateSimon2(2, 6); - _lastNameOn = NULL; - _animatePointer = 0; - _mouseAnim = 1; - return; - } - if (getGameType() == GType_SIMON2) { if (getBitFlag(79)) { sendSync(202); @@ -465,8 +465,7 @@ void AGOSEngine::defineBox(int id, int x, int y, int width, int height, int flag ha->verb = verb; ha->item_ptr = item_ptr; - if ((getGameType() == GType_FF || getGameType() == GType_PP) && - (ha->flags & kBFHyperBox)) { + if (getGameType() == GType_FF && (ha->flags & kBFHyperBox)) { ha->data = _hyperLink; ha->priority = 50; } @@ -474,124 +473,126 @@ void AGOSEngine::defineBox(int id, int x, int y, int width, int height, int flag _needHitAreaRecalc++; } +void AGOSEngine_PuzzlePack::resetVerbs() { + _verbHitArea = 300; +} + +void AGOSEngine_Feeble::resetVerbs() { + _verbHitArea = 300; + int cursor = 0; + int animMax = 16; + + if (getBitFlag(203)) { + cursor = 14; + animMax = 9; + } else if (getBitFlag(204)) { + cursor = 15; + animMax = 9; + } else if (getBitFlag(207)) { + cursor = 26; + animMax = 2; + } + + _mouseCursor = cursor; + _mouseAnimMax = animMax; + _mouseAnim = 1; + _needHitAreaRecalc++; + + if (getBitFlag(99)) { + setVerb(NULL); + } +} + void AGOSEngine::resetVerbs() { if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) return; - if (getGameType() == GType_PP) { - _verbHitArea = 300; - } else if (getGameType() == GType_FF) { - _verbHitArea = 300; - int cursor = 0; - int animMax = 16; - - if (getBitFlag(203)) { - cursor = 14; - animMax = 9; - } else if (getBitFlag(204)) { - cursor = 15; - animMax = 9; - } else if (getBitFlag(207)) { - cursor = 26; - animMax = 2; - } - - _mouseCursor = cursor; - _mouseAnimMax = animMax; - _mouseAnim = 1; - _needHitAreaRecalc++; + uint id; + HitArea *ha; - if (getBitFlag(99)) { - setVerb(NULL); - } + if (getGameType() == GType_SIMON2) { + id = 2; + if (!getBitFlag(79)) + id = (_mouse.y >= 136) ? 102 : 101; } else { - uint id; - HitArea *ha; - - if (getGameType() == GType_SIMON2) { - id = 2; - if (!getBitFlag(79)) - id = (_mouse.y >= 136) ? 102 : 101; - } else { - id = (_mouse.y >= 136) ? 102 : 101; - } + id = (_mouse.y >= 136) ? 102 : 101; + } - _defaultVerb = id; + _defaultVerb = id; - ha = findBox(id); - if (ha == NULL) - return; + ha = findBox(id); + if (ha == NULL) + return; - if (ha->flags & kBFBoxDead) { - _defaultVerb = 999; - _currentVerbBox = NULL; - } else { - _verbHitArea = ha->verb; - setVerb(ha); - } + if (ha->flags & kBFBoxDead) { + _defaultVerb = 999; + _currentVerbBox = NULL; + } else { + _verbHitArea = ha->verb; + setVerb(ha); } } -void AGOSEngine::setVerb(HitArea *ha) { - if (getGameType() == GType_PP) { +void AGOSEngine_Feeble::setVerb(HitArea *ha) { + int cursor = _mouseCursor; + if (_noRightClick) return; - } else if (getGameType() == GType_FF) { - int cursor = _mouseCursor; - if (_noRightClick) - return; - if (cursor > 13) - cursor = 0; - cursor++; - if (cursor == 5) + if (cursor > 13) + cursor = 0; + cursor++; + if (cursor == 5) + cursor = 1; + if (cursor == 4) { + if (getBitFlag(72)) { cursor = 1; - if (cursor == 4) { - if (getBitFlag(72)) { - cursor = 1; - } - } else if (cursor == 2) { - if (getBitFlag(99)) { - cursor = 3; - } } + } else if (cursor == 2) { + if (getBitFlag(99)) { + cursor = 3; + } + } - _mouseCursor = cursor; - _mouseAnimMax = (cursor == 4) ? 14: 16; - _mouseAnim = 1; - _needHitAreaRecalc++; - _verbHitArea = cursor + 300; - } else { - HitArea *tmp = _currentVerbBox; - - if (ha == tmp) - return; + _mouseCursor = cursor; + _mouseAnimMax = (cursor == 4) ? 14: 16; + _mouseAnim = 1; + _needHitAreaRecalc++; + _verbHitArea = cursor + 300; +} - if (getGameType() == GType_SIMON1) { - if (tmp != NULL) { - tmp->flags |= kBFInvertTouch; - invertBox(tmp, 213, 208, 213, 10); - } +void AGOSEngine::setVerb(HitArea *ha) { + HitArea *tmp = _currentVerbBox; - if (ha->flags & kBFBoxSelected) - invertBox(ha, 218, 213, 213, 5); - else - invertBox(ha, 223, 218, 218, 10); + if (ha == tmp) + return; - ha->flags &= ~(kBFBoxSelected + kBFInvertTouch); - } else { - if (ha->id < 101) - return; - _mouseCursor = ha->id - 101; - _needHitAreaRecalc++; + if (getGameType() == GType_SIMON1) { + if (tmp != NULL) { + tmp->flags |= kBFInvertTouch; + invertBox(tmp, 213, 208, 213, 10); } - _currentVerbBox = ha; + + if (ha->flags & kBFBoxSelected) + invertBox(ha, 218, 213, 213, 5); + else + invertBox(ha, 223, 218, 218, 10); + + ha->flags &= ~(kBFBoxSelected + kBFInvertTouch); + } else { + if (ha->id < 101) + return; + _mouseCursor = ha->id - 101; + _needHitAreaRecalc++; } + _currentVerbBox = ha; +} + +void AGOSEngine_Feeble::hitarea_leave(HitArea *ha, bool state) { + invertBox(ha, state); } void AGOSEngine::hitarea_leave(HitArea *ha, bool state) { - if (getGameType() == GType_FF) { - invertBox_FF(ha, state); - } else if (getGameType() == GType_SIMON2) { + if (getGameType() == GType_SIMON2) { invertBox(ha, 231, 229, 230, 1); } else { invertBox(ha, 223, 213, 218, 5); @@ -604,109 +605,21 @@ void AGOSEngine::leaveHitAreaById(uint hitarea_id) { hitarea_leave(ha); } -void AGOSEngine::checkUp(WindowBlock *window) { - uint16 j, k; - - if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[31] > 52)) { - k = (((_variableArray[31] / 52) - 2) % 3); - j = k * 6; - if (!isBoxDead(j + 201)) { - uint index = getWindowNum(window); - drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask); - animate(4, 9, k + 34, 0, 0, 0); - } - } - if ((_variableArray[31] - _variableArray[30]) == 76) { - k = ((_variableArray[31] / 52) % 3); - j = k * 6; - if (isBoxDead(j + 201)) { - animate(4, 9, k + 31, 0, 0, 0); - undefineBox(j + 201); - undefineBox(j + 202); - undefineBox(j + 203); - undefineBox(j + 204); - undefineBox(j + 205); - undefineBox(j + 206); - } - _variableArray[31] -= 52; - _iOverflow = 1; - } -} - -void AGOSEngine::checkDown(WindowBlock *window) { - uint16 j, k; - - if (((_variableArray[31] - _variableArray[30]) == 24) && (_iOverflow == 1)) { - uint index = getWindowNum(window); - drawIconArray(index, window->iconPtr->itemRef, 0, window->iconPtr->classMask); - k = ((_variableArray[31] / 52) % 3); - animate(4, 9, k + 25, 0, 0, 0); - _variableArray[31] += 52; - } - if (((_variableArray[31] - _variableArray[30]) == 40) && (_variableArray[30] > 52)) { - k = (((_variableArray[31] / 52) + 1) % 3); - j = k * 6; - if (isBoxDead(j + 201)) { - animate(4, 9, k + 28, 0, 0, 0); - undefineBox(j + 201); - undefineBox(j + 202); - undefineBox(j + 203); - undefineBox(j + 204); - undefineBox(j + 205); - undefineBox(j + 206); - } - } -} - void AGOSEngine::inventoryUp(WindowBlock *window) { - if (getGameType() == GType_FF) { - _marks = 0; - checkUp(window); - animate(4, 9, 21, 0 ,0, 0); - while (1) { - if (_currentBox->id != 0x7FFB || !getBitFlag(89)) - break; - checkUp(window); - delay(1); - } - waitForMark(2); - checkUp(window); - sendSync(922); - waitForMark(1); - checkUp(window); - } else { - if (window->iconPtr->line == 0) - return; + if (window->iconPtr->line == 0) + return; - mouseOff(); - uint index = getWindowNum(window); - drawIconArray(index, window->iconPtr->itemRef, window->iconPtr->line - 1, window->iconPtr->classMask); - mouseOn(); - } + mouseOff(); + uint index = getWindowNum(window); + drawIconArray(index, window->iconPtr->itemRef, window->iconPtr->line - 1, window->iconPtr->classMask); + mouseOn(); } void AGOSEngine::inventoryDown(WindowBlock *window) { - if (getGameType() == GType_FF) { - _marks = 0; - checkDown(window); - animate(4, 9, 23, 0, 0, 0); - while (1) { - if (_currentBox->id != 0x7FFC || !getBitFlag(89)) - break; - checkDown(window); - delay(1); - } - waitForMark(2); - checkDown(window); - sendSync(924); - waitForMark(1); - checkDown(window); - } else { - mouseOff(); - uint index = getWindowNum(window); - drawIconArray(index, window->iconPtr->itemRef, window->iconPtr->line + 1, window->iconPtr->classMask); - mouseOn(); - } + mouseOff(); + uint index = getWindowNum(window); + drawIconArray(index, window->iconPtr->itemRef, window->iconPtr->line + 1, window->iconPtr->classMask); + mouseOn(); } void AGOSEngine::boxController(uint x, uint y, uint mode) { @@ -765,7 +678,17 @@ void AGOSEngine::boxController(uint x, uint y, uint mode) { _variableArray[500] = best_ha->verb & 0xBFFF; } } - } + + if (_clickOnly != 0 && best_ha->id < 8) { + uint id = best_ha->id; + if (id >= 4) + id -= 4; + + invertBox(findBox(id), 0, 0, 0, 0); + _clickOnly = 0; + return; + } + } if (best_ha->flags & kBFDragBox) { _lastClickRem = best_ha; @@ -809,27 +732,13 @@ void AGOSEngine::boxController(uint x, uint y, uint mode) { } void AGOSEngine::displayName(HitArea *ha) { - if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2) + if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_PP) return; bool result; int x = 0, y = 0; - if (getGameType() == GType_PP) { - if (ha->flags & kBFHyperBox) { - _lastNameOn = ha; - return; - } - if (findBox(50)) - return; - - y = ha->y; - y -= 17; - if (y < 0) - y = 0; - y += 2; - x = ha->width / 2 + ha->x; - } else if (getGameType() == GType_FF) { + if (getGameType() == GType_FF) { if (ha->flags & kBFHyperBox) { _lastNameOn = ha; return; @@ -867,7 +776,7 @@ void AGOSEngine::displayName(HitArea *ha) { _lastNameOn = ha; } -void AGOSEngine::invertBox_FF(HitArea *ha, bool state) { +void AGOSEngine_Feeble::invertBox(HitArea *ha, bool state) { if (getBitFlag(205) || getBitFlag(206)) { if (state != 0) { _mouseAnimMax = _oldMouseAnimMax; @@ -915,28 +824,19 @@ void AGOSEngine::invertBox(HitArea * ha, byte a, byte b, byte c, byte d) { int w, h, i; _lockWord |= 0x8000; - src = getFrontBuf() + ha->y * _dxSurfacePitch + ha->x; + src = getFrontBuf() + ha->y * _dxSurfacePitch + (ha->x - _scrollX * 8); _litBoxFlag = true; w = ha->width; h = ha->height; - // Works around bug in original Simon the Sorcerer 2 - // Animations continue in background when load/save dialog is open - // often causing the savegame name highlighter to be cut short - if (!(h > 0 && w > 0 && ha->x + w <= _screenWidth && ha->y + h <= _screenHeight)) { - debug(1,"Invalid coordinates in invertBox (%d,%d,%d,%d)", ha->x, ha->y, ha->width, ha->height); - _lockWord &= ~0x8000; - return; - } - do { for (i = 0; i != w; ++i) { color = src[i]; - if (getGameType() == GType_ELVIRA1) { - if (color & 1) { - color ^= 2; + if (getGameType() == GType_WW) { + if (!(color & 0xF) || (color & 0xF) == 10) { + color ^= 10; src[i] = color; } } else if (getGameType() == GType_ELVIRA2) { @@ -944,6 +844,11 @@ void AGOSEngine::invertBox(HitArea * ha, byte a, byte b, byte c, byte d) { color ^= 2; src[i] = color; } + } else if (getGameType() == GType_ELVIRA1) { + if (color & 1) { + color ^= 2; + src[i] = color; + } } else { if (a >= color && b < color) { if (c >= color) diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp index 8948aaaba0..eb2d1391ce 100644 --- a/engines/agos/vga.cpp +++ b/engines/agos/vga.cpp @@ -33,7 +33,7 @@ namespace AGOS { // Opcode tables -void AGOSEngine::setupCommonVideoOpcodes(VgaOpcodeProc *op) { +void AGOSEngine::setupVideoOpcodes(VgaOpcodeProc *op) { op[1] = &AGOSEngine::vc1_fadeOut; op[2] = &AGOSEngine::vc2_call; op[3] = &AGOSEngine::vc3_loadSprite; @@ -81,7 +81,7 @@ void AGOSEngine::setupCommonVideoOpcodes(VgaOpcodeProc *op) { op[55] = &AGOSEngine::vc55_moveBox; } -void AGOSEngine::setupElvira1VideoOpcodes(VgaOpcodeProc *op) { +void AGOSEngine_Elvira1::setupVideoOpcodes(VgaOpcodeProc *op) { op[1] = &AGOSEngine::vc1_fadeOut; op[2] = &AGOSEngine::vc2_call; op[3] = &AGOSEngine::vc3_loadSprite; @@ -130,23 +130,13 @@ void AGOSEngine::setupVgaOpcodes() { switch (getGameType()) { case GType_ELVIRA1: - setupElvira1VideoOpcodes(_vga_opcode_table); - break; case GType_ELVIRA2: - setupElvira2VideoOpcodes(_vga_opcode_table); - break; case GType_WW: - setupWaxworksVideoOpcodes(_vga_opcode_table); - break; case GType_SIMON1: - setupSimon1VideoOpcodes(_vga_opcode_table); - break; case GType_SIMON2: - setupSimon2VideoOpcodes(_vga_opcode_table); - break; case GType_FF: case GType_PP: - setupFeebleVideoOpcodes(_vga_opcode_table); + setupVideoOpcodes(_vga_opcode_table); break; default: error("setupVgaOpcodes: Unknown game"); @@ -220,6 +210,17 @@ bool AGOSEngine::vc_maybe_skip_proc_1(uint16 a, int16 b) { return item->state == b; } +void AGOSEngine::dirtyBackGround() { + AnimTable *animTable = _screenAnim1; + while (animTable->srcPtr) { + if (animTable->id == _vgaCurSpriteId) { + animTable->window |= 0x8000; + break; + } + animTable++; + } +} + VgaSprite *AGOSEngine::findCurSprite() { VgaSprite *vsp = _vgaSprites; while (vsp->id) { @@ -402,7 +403,8 @@ void AGOSEngine::vc2_call() { } void AGOSEngine::vc3_loadSprite() { - uint16 windowNum, zoneNum, palette, x, y, vgaSpriteId; + uint16 windowNum, zoneNum, palette, vgaSpriteId; + int16 x, y; byte *old_file_1; if (getGameType() == GType_PP && getBitFlag(100)) { @@ -410,19 +412,22 @@ void AGOSEngine::vc3_loadSprite() { return; } - windowNum = vcReadNextWord(); /* 0 */ + windowNum = vcReadNextWord(); + if (getGameType() == GType_SIMON1 && windowNum == 3) { + _window3Flag = 1; + } if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) { - zoneNum = vcReadNextWord(); /* 0 */ - vgaSpriteId = vcReadNextWord(); /* 2 */ + zoneNum = vcReadNextWord(); + vgaSpriteId = vcReadNextWord(); } else { - vgaSpriteId = vcReadNextWord(); /* 2 */ + vgaSpriteId = vcReadNextWord(); zoneNum = vgaSpriteId / 100; } - x = vcReadNextWord(); /* 4 */ - y = vcReadNextWord(); /* 6 */ - palette = vcReadNextWord(); /* 8 */ + x = vcReadNextWord(); + y = vcReadNextWord(); + palette = vcReadNextWord(); old_file_1 = _curVgaFile1; @@ -578,57 +583,69 @@ byte *AGOSEngine::vc10_flip(const byte *src, uint w, uint h) { } void AGOSEngine::vc10_draw() { - byte *p2; - uint width, height; - byte flags; - VC10_state state; + uint16 palette, x, y, flags; + int16 image; - state.image = (int16)vcReadNextWord(); - if (state.image == 0) - return; + image = (int16)vcReadNextWord(); + palette = 0; if (getGameType() == GType_FF || getGameType() == GType_PP) { - state.palette = (_vcPtr[0] * 16); + palette = _vcPtr[0]; _vcPtr += 2; } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - state.palette = (_vcPtr[1] * 16); + palette = _vcPtr[1]; _vcPtr += 2; - } else { - state.palette = 0; } - state.x = (int16)vcReadNextWord(); - state.x -= _scrollX; - - state.y = (int16)vcReadNextWord(); - state.y -= _scrollY; + x = (int16)vcReadNextWord(); + y = (int16)vcReadNextWord(); if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) { - state.flags = vcReadNextByte(); + flags = vcReadNextByte(); } else { - state.flags = vcReadNextWord(); + flags = vcReadNextWord(); } + drawImage_init(image, palette, x, y, flags); +} + +void AGOSEngine::drawImage_init(int16 image, uint16 palette, int16 x, int16 y, uint16 flags) { + if (image == 0) + return; + + byte *src; + uint width, height; + VC10_state state; + + state.image = image; if (state.image < 0) state.image = vcReadVar(-state.image); - p2 = _curVgaFile2 + state.image * 8; - state.depack_src = _curVgaFile2 + readUint32Wrapper(p2); + state.palette = palette * 16; + state.paletteMod = 0; + + state.x = x - _scrollX; + state.y = y - _scrollY; + + state.flags = flags; + + src = _curVgaFile2 + state.image * 8; + state.srcPtr = _curVgaFile2 + readUint32Wrapper(src); if (getGameType() == GType_FF || getGameType() == GType_PP) { - width = READ_LE_UINT16(p2 + 6); - height = READ_LE_UINT16(p2 + 4) & 0x7FFF; - flags = p2[5]; + width = READ_LE_UINT16(src + 6); + height = READ_LE_UINT16(src + 4) & 0x7FFF; + flags = src[5]; } else { - width = READ_BE_UINT16(p2 + 6) / 16; - height = p2[5]; - flags = p2[4]; + width = READ_BE_UINT16(src + 6) / 16; + height = src[5]; + flags = src[4]; } if (height == 0 || width == 0) return; if (_dumpImages) - dumpSingleBitmap(_vgaCurZoneNum, state.image, state.depack_src, width, height, + dumpSingleBitmap(_vgaCurZoneNum, state.image, state.srcPtr, width, height, state.palette); state.width = state.draw_width = width; /* cl */ state.height = state.draw_height = height; /* ch */ @@ -639,7 +656,7 @@ void AGOSEngine::vc10_draw() { state.y_skip = 0; /* rows to skip = bl */ if (getFeatures() & GF_PLANAR) { - state.depack_src = convertImage(&state, ((flags & 0x80) != 0)); + state.srcPtr = convertImage(&state, ((flags & 0x80) != 0)); // converted planar clip is already uncompressed if (state.flags & kDFCompressedFlip) { @@ -676,9 +693,9 @@ void AGOSEngine::vc10_draw() { if (getGameType() != GType_FF && getGameType() != GType_PP) { if (state.flags & kDFCompressedFlip) { - state.depack_src = vc10_uncompressFlip(state.depack_src, width, height); + state.srcPtr = vc10_uncompressFlip(state.srcPtr, width, height); } else if (state.flags & kDFFlip) { - state.depack_src = vc10_flip(state.depack_src, width, height); + state.srcPtr = vc10_flip(state.srcPtr, width, height); } } @@ -688,49 +705,41 @@ void AGOSEngine::vc10_draw() { state.surf_addr = getBackBuf(); state.surf_pitch = _dxSurfacePitch; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - drawImages_Feeble(&state); - } else if (getFeatures() & GF_32COLOR) { - drawImages_Amiga(&state); - } else if (getGameType() == GType_SIMON1 || getGameType() == GType_SIMON2) { - drawImages_Simon(&state); - } else { - drawImages(&state); - } + drawImage(&state); } void AGOSEngine::vc12_delay() { - VgaSprite *vsp = findCurSprite(); uint16 num; if (getGameType() == GType_FF || getGameType() == GType_PP) { num = vcReadNextByte(); } else if (getGameType() == GType_SIMON2) { - num = vcReadNextByte() * _frameRate; + num = vcReadNextByte() * _frameCount; } else { - num = vcReadVarOrWord() * _frameRate; + num = vcReadVarOrWord() * _frameCount; } - // Work around to allow inventory arrows to be - // shown in some versions of Simon the Sorcerer 1 - if ((getGameType() == GType_SIMON1) && vsp->id == 128) - num = 0; - else - num += _vgaBaseDelay; + num += _vgaBaseDelay; - addVgaEvent(num, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); + addVgaEvent(num, ANIMATE_EVENT, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); _vcPtr = (byte *)&_vc_get_out_of_code; } void AGOSEngine::vc13_addToSpriteX() { VgaSprite *vsp = findCurSprite(); vsp->x += (int16)vcReadNextWord(); + + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } void AGOSEngine::vc14_addToSpriteY() { VgaSprite *vsp = findCurSprite(); vsp->y += (int16)vcReadNextWord(); + + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } @@ -739,7 +748,7 @@ void AGOSEngine::vc15_sync() { uint16 id = vcReadNextWord(); while (vfs->ident != 0) { if (vfs->ident == id) { - addVgaEvent(_vgaBaseDelay, vfs->code_ptr, vfs->sprite_id, vfs->cur_vga_file); + addVgaEvent(_vgaBaseDelay, ANIMATE_EVENT, vfs->code_ptr, vfs->sprite_id, vfs->cur_vga_file); vfs_tmp = vfs; do { memcpy(vfs_tmp, vfs_tmp + 1, sizeof(VgaSleepStruct)); @@ -773,7 +782,7 @@ void AGOSEngine::checkWaitEndTable() { VgaSleepStruct *vfs = _waitEndTable, *vfs_tmp; while (vfs->ident != 0) { if (vfs->ident == _vgaCurSpriteId) { - addVgaEvent(_vgaBaseDelay, vfs->code_ptr, vfs->sprite_id, vfs->cur_vga_file); + addVgaEvent(_vgaBaseDelay, ANIMATE_EVENT, vfs->code_ptr, vfs->sprite_id, vfs->cur_vga_file); vfs_tmp = vfs; do { memcpy(vfs_tmp, vfs_tmp + 1, sizeof(VgaSleepStruct)); @@ -958,6 +967,8 @@ void AGOSEngine::vc24_setSpriteXY() { vsp->flags = vcReadNextWord(); } + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } @@ -970,6 +981,8 @@ void AGOSEngine::vc25_halt_sprite() { vsp++; } _vcPtr = (byte *)&_vc_get_out_of_code; + + dirtyBackGround(); _vgaSpriteChanged++; } @@ -994,8 +1007,8 @@ void AGOSEngine::vc27_resetSprite() { vsp = _vgaSprites; while (vsp->id) { - if ((getGameType() == GType_SIMON1 && vsp->id == 128) || - (getGameType() == GType_ELVIRA2 && vsp->id == 100)) { + // For animated heart in Elvira 2 + if (getGameType() == GType_ELVIRA2 && vsp->id == 100) { memcpy(&bak, vsp, sizeof(VgaSprite)); } vsp->id = 0; @@ -1019,8 +1032,11 @@ void AGOSEngine::vc27_resetSprite() { vte = _vgaTimerList; while (vte->delay) { - if ((getGameType() == GType_SIMON1 && vte->sprite_id == 128) || - (getGameType() == GType_ELVIRA2 && vte->sprite_id == 100)) { + // Skip the animateSprites event in earlier games + if (vte->type == 2) { + vte++; + // For animated heart in Elvira 2 + } else if (getGameType() == GType_ELVIRA2 && vte->sprite_id == 100) { vte++; } else { vte2 = vte; @@ -1031,6 +1047,14 @@ void AGOSEngine::vc27_resetSprite() { } } + if (_lockWord & 0x20) { + AnimTable *animTable = _screenAnim1; + while (animTable->srcPtr) { + animTable->srcPtr = 0; + animTable++; + } + } + if (getGameType() == GType_SIMON2 || getGameType() == GType_FF || getGameType() == GType_PP) vcWriteVar(254, 0); @@ -1082,7 +1106,7 @@ void AGOSEngine::vc29_stopAllSounds() { } void AGOSEngine::vc30_setFrameRate() { - _frameRate = vcReadNextWord(); + _frameCount = vcReadNextWord(); } void AGOSEngine::vc31_setWindow() { @@ -1090,8 +1114,20 @@ void AGOSEngine::vc31_setWindow() { } void AGOSEngine::vc32_saveScreen() { - // TODO - debug(0, "vc32_saveScreen: stub"); + uint xoffs = _videoWindows[4 * 4 + 0] * 16; + uint yoffs = _videoWindows[4 * 4 + 1]; + uint width = _videoWindows[4 * 4 + 2] * 16; + uint height = _videoWindows[4 * 4 + 3]; + + byte *dst = getBackGround() + xoffs + yoffs * _screenWidth; + byte *src = _window4BackScn; + uint srcWidth = _videoWindows[4 * 4 + 2] * 16; + + for (; height > 0; height--) { + memcpy(dst, src, width); + dst += _screenWidth; + src += srcWidth; + } } void AGOSEngine::vc33_setMouseOn() { @@ -1109,33 +1145,70 @@ void AGOSEngine::vc33_setMouseOn() { } void AGOSEngine::vc34_setMouseOff() { - // FIXME - if (getGameType() == GType_ELVIRA1 && !(getFeatures() & GF_DEMO)) - return; - mouseOff(); _mouseHideCount = 200; _leftButtonDown = 0; } -void AGOSEngine::clearWindow(uint num, uint color) { +void AGOSEngine::clearVideoBackGround(uint num, uint color) { + debug(0, "clearVideoBackGround: num %d color %d", num, color); + + const uint16 *vlut = &_videoWindows[num * 4]; + byte *dst = getBackGround() + vlut[0] * 16 + (vlut[1] * (vlut[2] * 16)); + + for (uint h = 0; h < vlut[3]; h++) { + memset(dst, color, vlut[2] * 16); + dst += _screenWidth; + } +} + +void AGOSEngine::clearVideoWindow(uint num, uint color) { if (getGameType() == GType_ELVIRA1) { if (num == 2 || num == 6) return; } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { if (num != 4 && num < 10) return; + } else if (getGameType() == GType_SIMON1) { + if (num != 4) + return; } - if (num == 3) { - memset(getBackBuf(), 0, _screenWidth * _screenHeight); - } else { + debug(0, "clearVideoWindow: num %d color %d", num, color); + + if (getGameType() == GType_SIMON2) { const uint16 *vlut = &_videoWindows[num * 4]; - byte *dst = getBackBuf() + vlut[0] * 16 + vlut[1] * _dxSurfacePitch; + uint xoffs = vlut[0] * 16; + uint yoffs = vlut[1]; + uint dstWidth = _videoWindows[18] * 16; + byte *dst = _window4BackScn + xoffs + yoffs * dstWidth; + + setMoveRect(0, 0, vlut[2] * 16, vlut[3]); for (uint h = 0; h < vlut[3]; h++) { - memset(dst, 0, vlut[2] * 16); - dst += _screenWidth; + memset(dst, color, vlut[2] * 16); + dst += dstWidth; + } + + _window4Flag = 1; + } else { + if (getGameType() == GType_ELVIRA1 && num == 3) { + memset(getFrontBuf(), color, _screenWidth * _screenHeight); + } else if (num == 4) { + const uint16 *vlut = &_videoWindows[num * 4]; + uint xoffs = (vlut[0] - _videoWindows[16]) * 16; + uint yoffs = (vlut[1] - _videoWindows[17]); + uint dstWidth = _videoWindows[18] * 16; + byte *dst = _window4BackScn + xoffs + yoffs * dstWidth; + + setMoveRect(0, 0, vlut[2] * 16, vlut[3]); + + for (uint h = 0; h < vlut[3]; h++) { + memset(dst, color, vlut[2] * 16); + dst += dstWidth; + } + + _window4Flag = 1; } } } @@ -1143,22 +1216,33 @@ void AGOSEngine::clearWindow(uint num, uint color) { void AGOSEngine::vc35_clearWindow() { uint16 num = vcReadNextWord(); uint16 color = vcReadNextWord(); - clearWindow(num, color); + + // Clear video window + clearVideoWindow(num, color); + _vgaSpriteChanged++; + + // Clear video background + if (getGameType() == GType_ELVIRA1) { + if (num == 2 || num == 6) + return; + } else if (getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { + if (num != 4 && num < 10) + return; + } else if (getGameType() == GType_SIMON1) { + if (num != 4) + return; + } + + clearVideoBackGround(num, color); } void AGOSEngine::vc36_setWindowImage() { - _updateScreen = false; + _displayScreen = false; uint16 vga_res = vcReadNextWord(); uint16 windowNum = vcReadNextWord(); if (getGameType() == GType_FF || getGameType() == GType_PP) { _copyPartialMode = 2; - } else if (getGameType() == GType_SIMON1) { - if (windowNum == 16) { - _copyPartialMode = 2; - } else { - setWindowImage(windowNum, vga_res); - } } else { setWindowImage(windowNum, vga_res); } @@ -1204,7 +1288,7 @@ void AGOSEngine::vc40() { uint16 var = vcReadNextWord(); int16 value = vcReadVar(var) + vcReadNextWord(); - if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) { + if (getGameType() == GType_SIMON2 && var == 15 && !getBitFlag(80)) { int16 tmp; if (_scrollCount != 0) { @@ -1221,7 +1305,7 @@ void AGOSEngine::vc40() { tmp = _scrollXMax - _scrollX; if (tmp < 20) _scrollCount = tmp; - addVgaEvent(6, NULL, 0, 0); /* scroll event */ + addVgaEvent(6, SCROLL_EVENT, NULL, 0, 0); } } no_scroll:; @@ -1233,7 +1317,7 @@ void AGOSEngine::vc41() { uint16 var = vcReadNextWord(); int16 value = vcReadVar(var) - vcReadNextWord(); - if ((getGameType() == GType_SIMON2) && var == 15 && !getBitFlag(80)) { + if (getGameType() == GType_SIMON2 && var == 15 && !getBitFlag(80)) { if (_scrollCount != 0) { if (_scrollCount < 0) goto no_scroll; @@ -1247,7 +1331,7 @@ void AGOSEngine::vc41() { _scrollCount = -20; if (_scrollX < 20) _scrollCount = -_scrollX; - addVgaEvent(6, NULL, 0, 0); /* scroll event */ + addVgaEvent(6, SCROLL_EVENT, NULL, 0, 0); } } no_scroll:; @@ -1259,7 +1343,7 @@ void AGOSEngine::vc42_delayIfNotEQ() { uint16 val = vcReadVar(vcReadNextWord()); if (val != vcReadNextWord()) { - addVgaEvent(_frameRate + 1, _vcPtr - 4, _vgaCurSpriteId, _vgaCurZoneNum); + addVgaEvent(_frameCount + 1, ANIMATE_EVENT, _vcPtr - 4, _vgaCurSpriteId, _vgaCurZoneNum); _vcPtr = (byte *)&_vc_get_out_of_code; } } diff --git a/engines/agos/vga.h b/engines/agos/vga.h index fb577e0601..2daa0c02a6 100644 --- a/engines/agos/vga.h +++ b/engines/agos/vga.h @@ -56,7 +56,7 @@ struct AnimationHeader_Feeble { // Simon 1/2 struct ImageHeader_Simon { uint16 id; - uint16 x_1; + uint16 color; uint16 x_2; uint16 scriptOffs; }; @@ -101,7 +101,7 @@ struct VgaFileHeader2_Common { enum DrawFlags { kDFFlip = 0x1, kDFNonTrans = 0x2, - kDFUseFrontBuf = 0x4, + kDFSkipStoreBG = 0x4, kDFCompressed = 0x8, kDFCompressedFlip = 0x10, kDFMasked = 0x20, @@ -113,14 +113,15 @@ enum DrawFlags { }; struct VC10_state { - int image; + int16 image; uint16 flags; byte palette; + byte paletteMod; - int x, y; - int width, height; - uint draw_width, draw_height; - uint x_skip, y_skip; + int16 x, y; + uint16 width, height; + uint16 draw_width, draw_height; + uint16 x_skip, y_skip; byte *surf2_addr; uint surf2_pitch; @@ -130,10 +131,12 @@ struct VC10_state { uint16 dl, dh; - const byte *depack_src; + const byte *srcPtr; int8 depack_cont; byte depack_dest[480]; + + VC10_state() { memset(this, 0, sizeof(*this)); } }; byte *vc10_depackColumn(VC10_state *vs); diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp index fa454db4d9..ee6afd09e6 100644 --- a/engines/agos/vga_e2.cpp +++ b/engines/agos/vga_e2.cpp @@ -31,8 +31,8 @@ namespace AGOS { -void AGOSEngine::setupElvira2VideoOpcodes(VgaOpcodeProc *op) { - setupCommonVideoOpcodes(op); +void AGOSEngine_Elvira2::setupVideoOpcodes(VgaOpcodeProc *op) { + AGOSEngine::setupVideoOpcodes(op); op[17] = &AGOSEngine::vc17_waitEnd; op[19] = &AGOSEngine::vc19_loop; @@ -68,16 +68,37 @@ void AGOSEngine::vc45_setWindowPalette() { uint num = vcReadNextWord(); uint color = vcReadNextWord(); - const uint16 *vlut = &_videoWindows[num * 4]; - uint16 *dst = (uint16 *)getBackBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2; + if (num == 4) { + const uint16 *vlut = &_videoWindows[num * 4]; + uint16 *dst = (uint16 *)_window4BackScn; + uint width = vlut[2] * 16 / 2; + uint height = vlut[3]; + + for (uint h = 0; h < height; h++) { + for (uint w = 0; w < width; w++) { + dst[w] &= 0xF0F; + dst[w] |= color * 16; + } + dst += width; + } + } else { + const uint16 *vlut = &_videoWindows[num * 4]; + uint16 *dst = (uint16 *)getFrontBuf() + vlut[0] * 8 + vlut[1] * _dxSurfacePitch / 2; + uint width = vlut[2] * 16 / 2; + uint height = vlut[3]; + + if (getGameType() == GType_ELVIRA2 && num == 7) { + dst -= 4; + width += 4; + } - for (uint h = 0; h < vlut[3]; h++) { - uint width = vlut[2] * 8; - for (uint w = 0; w < width; w++) { - dst[w] &= 0xF0F; - dst[w] |= color * 16; + for (uint h = 0; h < height; h++) { + for (uint w = 0; w < width; w++) { + dst[w] &= 0xF0F; + dst[w] |= color * 16; + } + dst += _dxSurfacePitch / 2; } - dst += _dxSurfacePitch / 2; } } @@ -169,18 +190,127 @@ void AGOSEngine::vc52_playSound() { } void AGOSEngine::vc53_dissolveIn() { - // TODO - uint num = vcReadNextWord(); - uint speed = vcReadNextWord(); - debug(0, "vc53_dissolveIn: stub (%d, %d)", num, speed); + uint16 num = vcReadNextWord(); + uint16 speed = vcReadNextWord() + 1; + + byte *src, *dst, *srcOffs, *srcOffs2, *dstOffs, *dstOffs2; + uint8 color = 0; + + // Only uses Video Window 4 + num = 4; + + uint16 dissolveX = _videoWindows[num * 4 + 2] * 8; + uint16 dissolveY = (_videoWindows[num * 4 + 3] + 1) / 2; + uint16 dissolveCheck = dissolveY * dissolveX * 4; + uint16 dissolveDelay = dissolveCheck * 2 / speed; + uint16 dissolveCount = dissolveCheck * 2 / speed; + + int16 xoffs = _videoWindows[num * 4 + 0] * 16; + int16 yoffs = _videoWindows[num * 4 + 1]; + byte *dstPtr = getFrontBuf() + xoffs + yoffs * _screenWidth; + + uint16 count = dissolveCheck * 2; + while (count--) { + yoffs = _rnd.getRandomNumber(dissolveY); + dst = dstPtr + yoffs * _screenWidth; + src = _window4BackScn + yoffs * 224; + + xoffs = _rnd.getRandomNumber(dissolveX); + dst += xoffs; + src += xoffs; + + *dst &= color; + *dst |= *src & 0xF; + + dstOffs = dst; + srcOffs = src; + + xoffs = dissolveX * 2 - 1 - (xoffs * 2); + dst += xoffs; + src += xoffs; + + *dst &= color; + *dst |= *src & 0xF; + + srcOffs2 = src; + dstOffs2 = dst; + + yoffs = (dissolveY - 1) * 2 - (yoffs * 2); + src = srcOffs + yoffs * 224; + dst = dstOffs + yoffs * _screenWidth; + + color = 0xF0; + *dst &= color; + *dst |= *src & 0xF; + + dst = dstOffs2 + yoffs * _screenWidth;; + src = srcOffs2 + yoffs * 224; + + *dst &= color; + *dst |= *src & 0xF; + + dissolveCount--; + if (!dissolveCount) { + if (count >= dissolveCheck) + dissolveDelay++; + + dissolveCount = dissolveDelay; + _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); + delay(0); + } + } } void AGOSEngine::vc54_dissolveOut() { - // TODO - uint num = vcReadNextWord(); - uint color = vcReadNextWord(); - uint speed = vcReadNextWord(); - debug(0, "vc54_dissolveOut: stub (%d, %d, %d)", num, color, speed); + uint16 num = vcReadNextWord(); + uint16 color = vcReadNextWord(); + uint16 speed = vcReadNextWord() + 1; + + byte *dst, *dstOffs; + + uint16 dissolveX = _videoWindows[num * 4 + 2] * 8; + uint16 dissolveY = (_videoWindows[num * 4 + 3] + 1) / 2; + uint16 dissolveCheck = dissolveY * dissolveX * 4; + uint16 dissolveDelay = dissolveCheck * 2 / speed; + uint16 dissolveCount = dissolveCheck * 2 / speed; + + int16 xoffs = _videoWindows[num * 4 + 0] * 16; + int16 yoffs = _videoWindows[num * 4 + 1]; + byte *dstPtr = getFrontBuf() + xoffs + yoffs * _screenWidth; + color |= dstPtr[0] & 0xF0; + + uint16 count = dissolveCheck * 2; + while (count--) { + yoffs = _rnd.getRandomNumber(dissolveY); + xoffs = _rnd.getRandomNumber(dissolveX); + dst = dstPtr + xoffs + yoffs * _screenWidth; + *dst = color; + + dstOffs = dst; + + xoffs = dissolveX * 2 - 1 - (xoffs * 2); + dst += xoffs; + *dst = color; + + yoffs = (dissolveY - 1) * 2 - (yoffs * 2); + dst = dstOffs + yoffs * _screenWidth; + *dst = color; + + dst += xoffs; + *dst = color; + + dissolveCount--; + if (!dissolveCount) { + if (count >= dissolveCheck) + dissolveDelay++; + + dissolveCount = dissolveDelay; + _system->copyRectToScreen(getFrontBuf(), _screenWidth, 0, 0, _screenWidth, _screenHeight); + _system->updateScreen(); + delay(0); + } + } } void AGOSEngine::vc55_moveBox() { @@ -206,9 +336,10 @@ void AGOSEngine::vc55_moveBox() { void AGOSEngine::vc56_fullScreen() { byte *src = _curVgaFile2 + 32; - byte *dst = getBackBuf(); + byte *dst = getFrontBuf(); memcpy(dst, src + 768, _screenHeight * _screenWidth); + //fullFade(); uint8 palette[1024]; diff --git a/engines/agos/vga_ff.cpp b/engines/agos/vga_ff.cpp index 3097bc1eef..e5d85743e5 100644 --- a/engines/agos/vga_ff.cpp +++ b/engines/agos/vga_ff.cpp @@ -28,8 +28,8 @@ namespace AGOS { -void AGOSEngine::setupFeebleVideoOpcodes(VgaOpcodeProc *op) { - setupSimon2VideoOpcodes(op); +void AGOSEngine_Feeble::setupVideoOpcodes(VgaOpcodeProc *op) { + AGOSEngine_Simon2::setupVideoOpcodes(op); op[75] = &AGOSEngine::vc75_setScale; op[76] = &AGOSEngine::vc76_setScaleXOffs; diff --git a/engines/agos/vga_s1.cpp b/engines/agos/vga_s1.cpp index b878699038..bbad846727 100644 --- a/engines/agos/vga_s1.cpp +++ b/engines/agos/vga_s1.cpp @@ -29,8 +29,8 @@ namespace AGOS { -void AGOSEngine::setupSimon1VideoOpcodes(VgaOpcodeProc *op) { - setupCommonVideoOpcodes(op); +void AGOSEngine_Simon1::setupVideoOpcodes(VgaOpcodeProc *op) { + AGOSEngine::setupVideoOpcodes(op); op[11] = &AGOSEngine::vc11_clearPathFinder; op[17] = &AGOSEngine::vc17_setPathfinderItem; @@ -103,18 +103,27 @@ void AGOSEngine::vc32_copyVar() { void AGOSEngine::vc37_addToSpriteY() { VgaSprite *vsp = findCurSprite(); vsp->y += vcReadVar(vcReadNextWord()); + + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } void AGOSEngine::vc45_setSpriteX() { VgaSprite *vsp = findCurSprite(); vsp->x = vcReadVar(vcReadNextWord()); + + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } void AGOSEngine::vc46_setSpriteY() { VgaSprite *vsp = findCurSprite(); vsp->y = vcReadVar(vcReadNextWord()); + + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } @@ -207,8 +216,10 @@ void AGOSEngine::vc61_setMaskImage() { vsp->image = vcReadVarOrWord(); vsp->x += vcReadNextWord(); vsp->y += vcReadNextWord(); - vsp->flags = kDFMasked | kDFUseFrontBuf; + vsp->flags = kDFMasked | kDFSkipStoreBG; + vsp->windowNum |= 0x8000; + dirtyBackGround(); _vgaSpriteChanged++; } diff --git a/engines/agos/vga_s2.cpp b/engines/agos/vga_s2.cpp index d251604181..6989e26b46 100644 --- a/engines/agos/vga_s2.cpp +++ b/engines/agos/vga_s2.cpp @@ -28,8 +28,8 @@ namespace AGOS { -void AGOSEngine::setupSimon2VideoOpcodes(VgaOpcodeProc *op) { - setupSimon1VideoOpcodes(op); +void AGOSEngine_Simon2::setupVideoOpcodes(VgaOpcodeProc *op) { + AGOSEngine_Simon1::setupVideoOpcodes(op); op[56] = &AGOSEngine::vc56_delayLong; op[58] = &AGOSEngine::vc58_changePriority; @@ -48,9 +48,9 @@ void AGOSEngine::setupSimon2VideoOpcodes(VgaOpcodeProc *op) { } void AGOSEngine::vc56_delayLong() { - uint16 num = vcReadVarOrWord() * _frameRate; + uint16 num = vcReadVarOrWord() * _frameCount; - addVgaEvent(num + _vgaBaseDelay, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); + addVgaEvent(num + _vgaBaseDelay, ANIMATE_EVENT, _vcPtr, _vgaCurSpriteId, _vgaCurZoneNum); _vcPtr = (byte *)&_vc_get_out_of_code; } diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp index fb688d08aa..3c18fd5a08 100644 --- a/engines/agos/vga_ww.cpp +++ b/engines/agos/vga_ww.cpp @@ -31,8 +31,8 @@ namespace AGOS { -void AGOSEngine::setupWaxworksVideoOpcodes(VgaOpcodeProc *op) { - setupElvira2VideoOpcodes(op); +void AGOSEngine_Waxworks::setupVideoOpcodes(VgaOpcodeProc *op) { + AGOSEngine_Elvira2::setupVideoOpcodes(op); op[58] = &AGOSEngine::vc58_checkCodeWheel; op[60] = &AGOSEngine::vc60_stopAnimation; @@ -72,8 +72,8 @@ void AGOSEngine::vcStopAnimation(uint file, uint sprite) { vc25_halt_sprite(); vte = _vgaTimerList; - while (vte->delay != 0) { - if (vte->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vte->cur_vga_file == _vgaCurZoneNum)) { + while (vte->delay) { + if (vte->sprite_id == _vgaCurSpriteId && (getGameType() == GType_SIMON1 || vte->cur_vga_file == _vgaCurZoneNum)) { deleteVgaEvent(vte); break; } @@ -110,7 +110,7 @@ void AGOSEngine::vc61() { if (a == 6) { src = _curVgaFile2 + 800; - dstPtr = getBackBuf(); + dstPtr = getFrontBuf(); memcpy(dstPtr, src, 64000); tmp = 4 - 1; } else { @@ -176,12 +176,17 @@ void AGOSEngine::vc62_fastFadeOut() { memcpy(_videoBuf1, _currentPalette, _fastFadeCount * 4); - if ((getGameType() == GType_FF || getGameType() == GType_PP) && !getBitFlag(75)) { - fadeCount = 32; - fadeSize = 8; + if (getGameType() == GType_FF || getGameType() == GType_PP) { + if (getGameType() == GType_FF && getBitFlag(75)) { + fadeCount = 4; + fadeSize = 64; + } else { + fadeCount = 32; + fadeSize = 8; + } } else { - fadeCount = 4; - fadeSize = 64; + fadeCount = 64; + fadeSize = 4; } for (i = fadeCount; i != 0; --i) { @@ -190,50 +195,14 @@ void AGOSEngine::vc62_fastFadeOut() { delay(5); } - if (getGameType() == GType_SIMON1) { - uint16 params[5]; /* parameters to vc10_draw */ - VgaSprite *vsp; - VgaPointersEntry *vpe; - const byte *vcPtrOrg = _vcPtr; - - vsp = _vgaSprites; - while (vsp->id != 0) { - if (vsp->id == 128) { - byte *old_file_1 = _curVgaFile1; - byte *old_file_2 = _curVgaFile2; - uint palmode = _windowNum; - - vpe = &_vgaBufferPointers[vsp->zoneNum]; - _curVgaFile1 = vpe->vgaFile1; - _curVgaFile2 = vpe->vgaFile2; - _windowNum = vsp->windowNum; - - params[0] = READ_BE_UINT16(&vsp->image); - params[1] = READ_BE_UINT16(&vsp->palette); - params[2] = READ_BE_UINT16(&vsp->x); - params[3] = READ_BE_UINT16(&vsp->y); - params[4] = READ_BE_UINT16(&vsp->flags); - _vcPtr = (byte *)params; - vc10_draw(); - - _windowNum = palmode; - _curVgaFile1 = old_file_1; - _curVgaFile2 = old_file_2; - break; - } - vsp++; - } - _vcPtr = vcPtrOrg; - } - - // Allow one section of Simon the Sorcerer 1 introduction to be displayed - // in lower half of screen - if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926)) { - clearSurfaces(200); - } else if (getGameType() == GType_FF || getGameType() == GType_PP) { - clearSurfaces(480); + if (getGameType() == GType_FF || getGameType() == GType_PP) { + clearSurfaces(_screenHeight); + } else if (getGameType() == GType_WW) { + memset(getFrontBuf(), 0, _screenWidth * _screenHeight); } else { - clearSurfaces(_windowNum == 4 ? 134 : 200); + if (_windowNum != 4) { + memset(getFrontBuf(), 0, _screenWidth * _screenHeight); + } } } if (getGameType() == GType_SIMON2) { diff --git a/engines/agos/window.cpp b/engines/agos/window.cpp index bf5fb457a5..d3b6c1b8cd 100644 --- a/engines/agos/window.cpp +++ b/engines/agos/window.cpp @@ -123,6 +123,20 @@ void AGOSEngine::colorWindow(WindowBlock *window) { dst += _screenWidth; } } else { + if (getGameType() == GType_ELVIRA2 && window->y == 146) { + if (window->fill_color == 1) { + _displayPalette[33 * 4 + 0] = 48 * 4; + _displayPalette[33 * 4 + 1] = 40 * 4; + _displayPalette[33 * 4 + 2] = 32 * 4; + } else { + _displayPalette[33 * 4 + 0] = 56 * 4; + _displayPalette[33 * 4 + 1] = 56 * 4; + _displayPalette[33 * 4 + 2] = 40 * 4; + } + + _paletteFlag = 2; + } + dst = getFrontBuf() + _dxSurfacePitch * window->y + window->x * 8; h = window->height * 8; w = window->width * 8; @@ -158,8 +172,10 @@ void AGOSEngine::restoreWindow(WindowBlock *window) { } restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8); - } else { + } else if (getGameType() == GType_SIMON1) { restoreBlock(window->y + window->height * 8 + ((window == _windowArray[2]) ? 1 : 0), (window->x + window->width) * 8, window->y, window->x * 8); + } else { + restoreBlock(window->y + window->height * 8, (window->x + window->width) * 8, window->y, window->x * 8); } _lockWord &= ~0x8000; @@ -170,7 +186,7 @@ void AGOSEngine::restoreBlock(uint h, uint w, uint y, uint x) { uint i; dst = getFrontBuf(); - src = _backGroundBuf; + src = getBackGround(); dst += y * _dxSurfacePitch; src += y * _dxSurfacePitch; @@ -197,9 +213,16 @@ void AGOSEngine::setTextColor(uint color) { window->text_color = color; } -void AGOSEngine::windowPutChar(uint a) { - if (_textWindow != _windowArray[0]) +void AGOSEngine::sendWindow(uint a) { + if (_textWindow != _windowArray[0]) { + if (getGameType() == GType_ELVIRA1 || getGameType() == GType_ELVIRA2 || getGameType() == GType_WW) { + if (!(_textWindow->flags & 1)) { + haltAnimation(); + } + } + windowPutChar(_textWindow, a); + } } void AGOSEngine::waitWindow(WindowBlock *window) { @@ -215,8 +238,8 @@ void AGOSEngine::waitWindow(WindowBlock *window) { windowPutChar(window, *message); ha = findEmptyHitArea(); - ha->x = 96; - ha->y = 62; + ha->x = (window->width / 2 + window->x - 3) * 8; + ha->y = window->height * 8 + window->y - 8; ha->width = 48; ha->height = 8; ha->flags = kBFBoxInUse; @@ -243,4 +266,38 @@ void AGOSEngine::waitWindow(WindowBlock *window) { undefineBox(0x7FFF); } +void AGOSEngine::writeChar(WindowBlock *window, int x, int y, int offs, int val) { + int chr; + + // Clear background of first digit + window->textColumnOffset = offs; + window->text_color = 0; + windowDrawChar(window, x * 8, y, 129); + + if (val != -1) { + // Print first digit + chr = val / 10 + 48; + window->text_color = 15; + windowDrawChar(window, x * 8, y, chr); + } + + offs += 6; + if (offs >= 7) { + offs -= 8; + x++; + } + + // Clear background of second digit + window->textColumnOffset = offs; + window->text_color = 0; + windowDrawChar(window, x * 8, y, 129); + + if (val != -1) { + // Print second digit + chr = val % 10 + 48; + window->text_color = 15; + windowDrawChar(window, x * 8, y, chr); + } +} + } // End of namespace AGOS diff --git a/engines/agos/zones.cpp b/engines/agos/zones.cpp index e8d2077f4b..630d85d145 100644 --- a/engines/agos/zones.cpp +++ b/engines/agos/zones.cpp @@ -103,7 +103,21 @@ byte *AGOSEngine::allocBlock(uint32 size) { } } -void AGOSEngine::checkNoOverWrite() { +void AGOSEngine::checkRunningAnims() { + VgaSprite *vsp; + if (getGameType() != GType_FF && getGameType() != GType_PP && + (_lockWord & 0x20)) { + return; + } + + for (vsp = _vgaSprites; vsp->id; vsp++) { + checkAnims(vsp->zoneNum); + if (_rejectBlock == true) + return; + } +} + +void AGOSEngine_Feeble::checkNoOverWrite() { VgaPointersEntry *vpe; if (_noOverWrite == 0xFFFF) @@ -111,40 +125,70 @@ void AGOSEngine::checkNoOverWrite() { vpe = &_vgaBufferPointers[_noOverWrite]; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) { - _rejectBlock = true; - _vgaMemPtr = vpe->vgaFile1End; - } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) { - _rejectBlock = true; - _vgaMemPtr = vpe->vgaFile2End; - } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { - _rejectBlock = true; - _vgaMemPtr = vpe->sfxFileEnd; - } else { - _rejectBlock = false; - } + if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) { + _rejectBlock = true; + _vgaMemPtr = vpe->vgaFile1End; + } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) { + _rejectBlock = true; + _vgaMemPtr = vpe->vgaFile2End; + } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { + _rejectBlock = true; + _vgaMemPtr = vpe->sfxFileEnd; } else { - if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 || - _vgaMemPtr <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) { - _rejectBlock = true; - _vgaMemPtr = vpe->vgaFile1 + 0x5000; - } else { - _rejectBlock = false; - } + _rejectBlock = false; } } -void AGOSEngine::checkRunningAnims() { - VgaSprite *vsp; - if (getGameType() != GType_FF && getGameType() != GType_PP && (_lockWord & 0x20)) { - return; +void AGOSEngine_Feeble::checkAnims(uint a) { + VgaPointersEntry *vpe; + + vpe = &_vgaBufferPointers[a]; + + if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) { + _rejectBlock = true; + _vgaMemPtr = vpe->vgaFile1End; + } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) { + _rejectBlock = true; + _vgaMemPtr = vpe->vgaFile2End; + } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { + _rejectBlock = true; + _vgaMemPtr = vpe->sfxFileEnd; + } else { + _rejectBlock = false; } +} - for (vsp = _vgaSprites; vsp->id; vsp++) { - checkAnims(vsp->zoneNum); - if (_rejectBlock == true) - return; +void AGOSEngine_Feeble::checkZonePtrs() { + uint count = ARRAYSIZE(_vgaBufferPointers); + VgaPointersEntry *vpe = _vgaBufferPointers; + do { + if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block || + vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block || + vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { + vpe->vgaFile1 = NULL; + vpe->vgaFile1End = NULL; + vpe->vgaFile2 = NULL; + vpe->vgaFile2End = NULL; + vpe->sfxFile = NULL; + vpe->sfxFileEnd = NULL; + } + } while (++vpe, --count); +} + +void AGOSEngine::checkNoOverWrite() { + VgaPointersEntry *vpe; + + if (_noOverWrite == 0xFFFF) + return; + + vpe = &_vgaBufferPointers[_noOverWrite]; + + if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 || + _vgaMemPtr <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) { + _rejectBlock = true; + _vgaMemPtr = vpe->vgaFile1 + 0x5000; + } else { + _rejectBlock = false; } } @@ -153,27 +197,12 @@ void AGOSEngine::checkAnims(uint a) { vpe = &_vgaBufferPointers[a]; - if (getGameType() == GType_FF || getGameType() == GType_PP) { - if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block) { - _rejectBlock = true; - _vgaMemPtr = vpe->vgaFile1End; - } else if (vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block) { - _rejectBlock = true; - _vgaMemPtr = vpe->vgaFile2End; - } else if (vpe->sfxFile && vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { - _rejectBlock = true; - _vgaMemPtr = vpe->sfxFileEnd; - } else { - _rejectBlock = false; - } + if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 || + _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) { + _rejectBlock = true; + _vgaMemPtr = vpe->vgaFile1 + 0x5000; } else { - if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 || - _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) { - _rejectBlock = true; - _vgaMemPtr = vpe->vgaFile1 + 0x5000; - } else { - _rejectBlock = false; - } + _rejectBlock = false; } } @@ -181,23 +210,10 @@ void AGOSEngine::checkZonePtrs() { uint count = ARRAYSIZE(_vgaBufferPointers); VgaPointersEntry *vpe = _vgaBufferPointers; do { - if (getGameType() == GType_FF || getGameType() == GType_PP) { - if (vpe->vgaFile1 < _blockEnd && vpe->vgaFile1End > _block || - vpe->vgaFile2 < _blockEnd && vpe->vgaFile2End > _block || - vpe->sfxFile < _blockEnd && vpe->sfxFileEnd > _block) { - vpe->vgaFile1 = NULL; - vpe->vgaFile1End = NULL; - vpe->vgaFile2 = NULL; - vpe->vgaFile2End = NULL; - vpe->sfxFile = NULL; - vpe->sfxFileEnd = NULL; - } - } else { - if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 || - _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) { - vpe->vgaFile1 = NULL; - vpe->vgaFile2 = NULL; - } + if (_block <= vpe->vgaFile1 && _blockEnd >= vpe->vgaFile1 || + _block <= vpe->vgaFile2 && _blockEnd >= vpe->vgaFile2) { + vpe->vgaFile1 = NULL; + vpe->vgaFile2 = NULL; } } while (++vpe, --count); } diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp index 1b452eefc8..a30c2bdff3 100644 --- a/engines/cine/anim.cpp +++ b/engines/cine/anim.cpp @@ -395,6 +395,18 @@ void loadSpl(const char *resourceName) { strcpy(animDataTable[entry].name, currentPartName); } +void loadSplAbs(const char *resourceName, uint16 idx) { + int16 foundFileIdx; + byte *dataPtr; + int16 entry; + + foundFileIdx = findFileInBundle(resourceName); + dataPtr = readBundleFile(foundFileIdx); + + entry = reserveFrame((uint16) partBuffer[foundFileIdx].unpackedSize, 1, 0, idx); + memcpy(animDataTable[entry].ptr1, dataPtr, partBuffer[foundFileIdx].unpackedSize); +} + void loadMsk(const char *resourceName) { int16 foundFileIdx; byte *dataPtr; @@ -877,6 +889,7 @@ void loadAbs(const char *resourceName, uint16 idx) { loadSeqAbs(resourceName, idx); return; } else if (strstr(resourceName, ".SPL")) { + loadSplAbs(resourceName, idx); return; } else if (strstr(resourceName, ".AMI")) { return; diff --git a/engines/cine/bg.cpp b/engines/cine/bg.cpp index badb8bb888..41291dea92 100644 --- a/engines/cine/bg.cpp +++ b/engines/cine/bg.cpp @@ -105,7 +105,7 @@ byte loadBg(const char *bgName) { return 0; } -byte *additionalBgTable[9] = { page2Raw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, page3Raw }; +byte *additionalBgTable[9]; byte currentAdditionalBgIdx = 0; byte currentAdditionalBgIdx2 = 0; diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index 5f2ded13a0..97af6d2df8 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -24,7 +24,7 @@ #include "common/stdafx.h" #include "common/file.h" -#include "common/fs.h" +//#include "common/fs.h" #include "common/savefile.h" #include "common/config-manager.h" #include "common/system.h" @@ -39,15 +39,13 @@ #include "cine/main_loop.h" #include "cine/object.h" #include "cine/texte.h" -#include "cine/sfx_player.h" -#include "cine/sound_driver.h" +#include "cine/sound.h" #include "cine/various.h" namespace Cine { -SoundDriver *g_soundDriver; -SfxPlayer *g_sfxPlayer; +Sound *g_sound; Common::SaveFileManager *g_saveFileMan; CineEngine *g_cine; @@ -95,12 +93,12 @@ int CineEngine::init() { _system->initSize(320, 200); _system->endGFXTransaction(); - if (g_cine->getGameType() == GType_FW) { - g_soundDriver = new AdlibSoundDriverINS(_mixer); + if (g_cine->getPlatform() == Common::kPlatformPC) { + g_sound = new PCSound(_mixer, this); } else { - g_soundDriver = new AdlibSoundDriverADL(_mixer); + // Paula chipset for Amiga and Atari versions + g_sound = new PaulaSound(_mixer, this); } - g_sfxPlayer = new SfxPlayer(g_soundDriver); g_saveFileMan = _saveFileMan; initialize(); @@ -113,11 +111,7 @@ int CineEngine::go() { mainLoop(1); - if (g_cine->getGameType() == Cine::GType_FW) - snd_clearBasesonEntries(); - - delete g_sfxPlayer; - delete g_soundDriver; + delete g_sound; return 0; } @@ -128,7 +122,7 @@ void CineEngine::initialize() { setupOpcodes(); initLanguage(g_cine->getLanguage()); - init_video(); + gfxInit(); textDataPtr = (byte *)malloc(8000); @@ -138,16 +132,9 @@ void CineEngine::initialize() { loadTextData("texte.dat", textDataPtr); - switch (g_cine->getGameType()) { - case Cine::GType_FW: - snd_loadBasesonEntries("BASESON.SND"); - break; - case Cine::GType_OS: - if (!(g_cine->getFeatures() & GF_DEMO)) { - loadPoldatDat("poldat.dat"); - loadErrmessDat("errmess.dat"); - } - break; + if (g_cine->getGameType() == Cine::GType_OS && !(g_cine->getFeatures() & GF_DEMO)) { + loadPoldatDat("poldat.dat"); + loadErrmessDat("errmess.dat"); } for (i = 0; i < NUM_MAX_OBJECT; i++) { diff --git a/engines/cine/cine.h b/engines/cine/cine.h index 4646850a93..061e9ab66b 100644 --- a/engines/cine/cine.h +++ b/engines/cine/cine.h @@ -36,7 +36,6 @@ #include "cine/script.h" #include "cine/part.h" #include "cine/prc.h" -#include "cine/resource.h" #include "cine/msg.h" #include "cine/bg.h" #include "cine/pal.h" diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index b5cdecd7de..71aa33b28b 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -23,6 +23,7 @@ */ #include "cine/cine.h" +#include "cine/bg.h" #include "cine/various.h" #include "common/system.h" @@ -31,18 +32,12 @@ namespace Cine { -byte *screenBuffer; - uint16 c_palette[256]; -byte *page0; -byte *page1; -byte *page2; -byte *page3; - -byte page1Raw[320 * 200]; -byte page2Raw[320 * 200]; -byte page3Raw[320 * 200]; +byte *screenBuffer; +byte *page1Raw; +byte *page2Raw; +byte *page3Raw; static const byte mouseCursorNormal[] = { 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, @@ -92,14 +87,21 @@ static const byte cursorPalette[] = { 0xff, 0xff, 0xff, 0xff }; -void init_video() { - screenBuffer = (byte *)malloc(320 * 200 * 3); - assert(screenBuffer); - - page0 = (byte *)malloc(0x8000); - page1 = (byte *)malloc(0x8000); - page2 = (byte *)malloc(0x8000); - page3 = (byte *)malloc(0x8000); +void gfxInit() { + screenBuffer = (byte *)malloc(320 * 200); + page1Raw = (byte *)malloc(320 * 200); + page2Raw = (byte *)malloc(320 * 200); + page3Raw = (byte *)malloc(320 * 200); + if (!screenBuffer || !page1Raw || !page2Raw || !page3Raw) { + error("Unable to allocate offscreen buffers"); + } + memset(page1Raw, 0, 320 * 200); + memset(page2Raw, 0, 320 * 200); + memset(page3Raw, 0, 320 * 200); + + memset(additionalBgTable, 0, sizeof(additionalBgTable)); + additionalBgTable[0] = page2Raw; + additionalBgTable[8] = page3Raw; } void setMouseCursor(int cursor) { @@ -129,7 +131,7 @@ void setMouseCursor(int cursor) { } } -uint16 transformColor(uint16 baseColor, int8 r, int8 g, int8 b) { +static uint16 transformColor(uint16 baseColor, int8 r, int8 g, int8 b) { int8 oriR = (baseColor & 0x7); int8 oriG = (baseColor & 0x70) >> 4; int8 oriB = (baseColor & 0x700) >> 8; @@ -165,7 +167,7 @@ void transformPaletteRange(byte startColor, byte stopColor, int8 r, int8 g, int8 //gfxFlipPage(page2); } -void gfxFillSprite(byte *spritePtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) { +void gfxFillSprite(byte *spritePtr, uint16 width, uint16 height, byte *page, int16 x, int16 y, uint8 fillColor) { int16 i; int16 j; @@ -177,7 +179,7 @@ void gfxFillSprite(byte *spritePtr, uint16 width, uint16 height, byte *page, int if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200) { if (!*(spritePtr++)) { - *(destPtr++) = 0; + *(destPtr++) = fillColor; } else { destPtr++; } @@ -189,6 +191,84 @@ void gfxFillSprite(byte *spritePtr, uint16 width, uint16 height, byte *page, int } } +// gfxDrawMaskedSprite +void gfxSpriteFunc1(byte *spritePtr, byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) { + int16 i, j; + + for (i = 0; i < height; i++) { + byte *destPtr = page + x + y * 320; + destPtr += i * 320; + + for (j = 0; j < width * 8; j++) { + if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200 && *maskPtr == 0) { + *destPtr = *spritePtr; + } + ++destPtr; + ++spritePtr; + ++maskPtr; + } + } +} + +// gfxUpdateSpriteMask +void gfxSpriteFunc2(byte *spritePtr, byte *spriteMskPtr, int16 width, int16 height, byte *maskPtr, + int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx) { + int16 i, j, d, spritePitch, maskPitch; + + width *= 8; + maskWidth *= 8; + + spritePitch = width; + maskPitch = maskWidth; + + if (maskIdx == 0) { + memcpy(bufferSprPtr, spritePtr, spritePitch * height); + memcpy(bufferMskPtr, spriteMskPtr, spritePitch * height); + } + + if (ys > ym) { + d = ys - ym; + maskPtr += d * maskPitch; + maskHeight -= d; + } + if (maskHeight <= 0) { + return; + } + if (xs > xm) { + d = xs - xm; + maskPtr += d; + maskWidth -= d; + } + if (maskWidth <= 0) { + return; + } + if (ys < ym) { + d = ym - ys; + spriteMskPtr += d * spritePitch; + bufferMskPtr += d * spritePitch; + height -= d; + } + if (height <= 0) { + return; + } + if (xs < xm) { + d = xm - xs; + spriteMskPtr += d; + bufferMskPtr += d; + width -= d; + } + if (width <= 0) { + return; + } + for (j = 0; j < MIN(maskHeight, height); ++j) { + for (i = 0; i < MIN(maskWidth, width); ++i) { + bufferMskPtr[i] |= maskPtr[i] ^ 1; + } + bufferMskPtr += spritePitch; + maskPtr += maskPitch; + } +} + void gfxDrawLine(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page) { if (x1 == x2) { if (y1 > y2) { @@ -392,5 +472,21 @@ void fadeToBlack() { } } +void gfxFuncGen1(byte *param1, byte *param2, byte *param3, byte *param4, int16 param5) { +} + +void ptrGfxFunc13(void) { +} + +void gfxFuncGen2(void) { +} + +void blitRawScreen(byte *frontBuffer) { + gfxFlipRawPage(frontBuffer); +} + +void flip(void) { + blitRawScreen(page1Raw); +} } // End of namespace Cine diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h index 08f7bae640..d46a033363 100644 --- a/engines/cine/gfx.h +++ b/engines/cine/gfx.h @@ -29,14 +29,13 @@ namespace Cine { void gfxDrawSprite(byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy); -extern byte *page0; -extern byte *page1; -extern byte *page2; -extern byte *page3; +extern byte *page1Raw; +extern byte *page2Raw; +extern byte *page3Raw; extern uint16 c_palette[256]; -void init_video(); +void gfxInit(); void setMouseCursor(int cursor); void convertGfx(byte *source, byte *dest, const uint16 width, const uint16 height); void convertGfx2(byte *source, byte *dest, const uint16 width, const uint16 height); @@ -45,11 +44,11 @@ void gfxCopyPage(byte *source, byte *dest); void transformPaletteRange(byte startColor, byte numColor, int8 r, int8 g, int8 b); void gfxFlipPage(void); -void gfxSpriteFunc1(byte *ptr, uint16 width, uint16 height, byte *page, int16 x, int16 y); -void gfxFillSprite(byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy); +void gfxSpriteFunc1(byte *ptr, byte *msk, uint16 width, uint16 height, byte *page, int16 x, int16 y); +void gfxFillSprite(byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy, uint8 fillColor = 0); -void gfxSpriteFunc2(byte *spritePtr, int16 width, int16 height, byte *maskPtr, - int16 maskWidth, int16 maskHeight, byte *bufferPtr, int16 x, int16 y, byte maskIdx); +void gfxSpriteFunc2(byte *spritePtr, byte *spriteMskPtr, int16 width, int16 height, byte *maskPtr, + int16 maskWidth, int16 maskHeight, byte *bufferSprPtr, byte *bufferMskPtr, int16 xs, int16 ys, int16 xm, int16 ym, byte maskIdx); void gfxDrawLine(int16 x1, int16 y1, int16 x2, int16 y2, byte color, byte *page); void gfxDrawPlainBox(int16 x1, int16 y1, int16 x2, int16 y2, byte color); @@ -58,10 +57,6 @@ void gfxResetPage(byte *pagePtr); int16 gfxGetBit(int16 x, int16 y, byte *ptr, int16 width); -extern byte page1Raw[320 * 200]; -extern byte page2Raw[320 * 200]; -extern byte page3Raw[320 * 200]; - void gfxResetRawPage(byte *pageRaw); void gfxConvertSpriteToRaw(byte *dest, byte *source, uint16 width, uint16 height); void gfxCopyRawPage(byte *source, byte * dest); @@ -72,6 +67,14 @@ void drawSpriteRaw2(byte *spritePtr, byte transColor, int16 width, int16 height, void fadeToBlack(void); +void gfxFuncGen1(byte *param1, byte *param2, byte *param3, byte *param4, int16 param5); +void ptrGfxFunc13(void); +void gfxFuncGen2(void); + +void blitScreen(byte *frontBuffer, byte *backbuffer); +void blitRawScreen(byte *frontBuffer); +void flip(void); + } // End of namespace Cine #endif diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp index 7bf537b17c..5f601b8aa7 100644 --- a/engines/cine/main_loop.cpp +++ b/engines/cine/main_loop.cpp @@ -29,9 +29,9 @@ #include "cine/main_loop.h" #include "cine/object.h" -#include "cine/sfx_player.h" #include "cine/various.h" #include "cine/bg_list.h" +#include "cine/sound.h" namespace Cine { @@ -156,6 +156,7 @@ void manageEvents(int count) { if (i % 2) g_system->updateScreen(); g_system->delayMillis(10); + g_sound->update(); manageEvents(0); } } @@ -209,7 +210,7 @@ void CineEngine::mainLoop(int bootScriptIdx) { menuVar = 0; - gfxFuncGen1(page0c, page0, page0c, page0, -1); +// gfxFuncGen1(page0c, page0, page0c, page0, -1); ptrGfxFunc13(); @@ -244,7 +245,7 @@ void CineEngine::mainLoop(int bootScriptIdx) { strcpy(currentCtName, ""); strcpy(currentPartName, ""); - g_sfxPlayer->stop(); + g_sound->stopMusic(); } do { @@ -333,7 +334,7 @@ void CineEngine::mainLoop(int bootScriptIdx) { } while (!exitEngine && !quitFlag && var21 != 7); hideMouse(); - g_sfxPlayer->stop(); + g_sound->stopMusic(); freeAnimDataTable(); unloadAllMasks(); freePrcLinkedList(); diff --git a/engines/cine/module.mk b/engines/cine/module.mk index 929511b1b4..07e267289f 100644 --- a/engines/cine/module.mk +++ b/engines/cine/module.mk @@ -14,10 +14,8 @@ MODULE_OBJS = \ part.o \ prc.o \ rel.o \ - resource.o \ script.o \ - sfx_player.o \ - sound_driver.o \ + sound.o \ texte.o \ unpack.o \ various.o diff --git a/engines/cine/object.cpp b/engines/cine/object.cpp index 80c4b1999c..980bcfe5d7 100644 --- a/engines/cine/object.cpp +++ b/engines/cine/object.cpp @@ -30,7 +30,6 @@ #include "cine/cine.h" #include "cine/object.h" #include "cine/part.h" -#include "cine/resource.h" #include "cine/various.h" namespace Cine { diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp index 99d1109c2b..7ef81f5069 100644 --- a/engines/cine/part.cpp +++ b/engines/cine/part.cpp @@ -68,7 +68,7 @@ void loadPart(const char *partName) { partFileHandle.readUint32BE(); // unused } - if (g_cine->getGameType() == Cine::GType_FW && g_cine->getPlatform() == Common::kPlatformPC) + if (g_cine->getGameType() == Cine::GType_FW && g_cine->getPlatform() == Common::kPlatformPC && strcmp(partName, "BASESON.SND") != 0) loadPal(partName); } @@ -331,7 +331,7 @@ int16 findFileInBundle(const char *fileName) { if (g_cine->getGameType() == Cine::GType_OS) { for (i = 0; i < numElementInPart; i++) { - if (!strcmp(fileName, partBuffer[i].partName)) { + if (!scumm_stricmp(fileName, partBuffer[i].partName)) { return i; } } @@ -374,11 +374,11 @@ int16 findFileInBundle(const char *fileName) { bPtr = bundleNamesAtari; } - while (**bPtr) { + while (*bPtr) { loadPart(*bPtr); for (i = 0; i < numElementInPart; i++) { - if (!strcmp(fileName, partBuffer[i].partName)) { + if (!scumm_stricmp(fileName, partBuffer[i].partName)) { return i; } } @@ -386,7 +386,7 @@ int16 findFileInBundle(const char *fileName) { } } else { for (i = 0; i < numElementInPart; i++) { - if (!strcmp(fileName, partBuffer[i].partName)) { + if (!scumm_stricmp(fileName, partBuffer[i].partName)) { return i; } } @@ -420,6 +420,28 @@ byte *readBundleFile(int16 foundFileIdx) { return dataPtr; } +byte *readBundleSoundFile(const char *entryName, uint32 *size) { + int16 index; + byte *data = 0; + char previousPartName[15] = ""; + + if (g_cine->getGameType() == Cine::GType_FW) { + strcpy(previousPartName, currentPartName); + loadPart("BASESON.SND"); + } + index = findFileInBundle((const char *)entryName); + if (index != -1) { + data = readBundleFile(index); + if (size) { + *size = partBuffer[index].unpackedSize; + } + } + if (g_cine->getGameType() == Cine::GType_FW) { + loadPart(previousPartName); + } + return data; +} + byte *readFile(const char *filename) { Common::File in; @@ -437,6 +459,9 @@ byte *readFile(const char *filename) { return dataPtr; } +void checkDataDisk(int16 param) { +} + void dumpBundle(const char *fileName) { char tmpPart[15]; diff --git a/engines/cine/part.h b/engines/cine/part.h index 17ffd7aeb3..b8abd7620c 100644 --- a/engines/cine/part.h +++ b/engines/cine/part.h @@ -65,8 +65,11 @@ int16 findFileInBundle(const char *fileName); void readFromPart(int16 idx, byte *dataPtr); byte *readBundleFile(int16 foundFileIdx); +byte *readBundleSoundFile(const char *entryName, uint32 *size = 0); byte *readFile(const char *filename); +void checkDataDisk(int16 param); + void dumpBundle(const char *filename); } // End of namespace Cine diff --git a/engines/cine/resource.cpp b/engines/cine/resource.cpp deleted file mode 100644 index fb5fcfb94e..0000000000 --- a/engines/cine/resource.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * cinE Engine is (C) 2004-2005 by CinE Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/file.h" - -#include "cine/cine.h" -#include "cine/resource.h" -#include "cine/unpack.h" -#include "cine/various.h" - -namespace Cine { - -void checkDataDisk(int16 param) { -} - -/* FW specific */ -static Common::File *snd_baseSndFile = NULL; -static uint16 snd_numBasesonEntries = 0; -static BasesonEntry *snd_basesonEntries = NULL; - -int snd_loadBasesonEntries(const char *fileName) { - int i; - - snd_baseSndFile = new Common::File(); - snd_baseSndFile->open(fileName); - if (!snd_baseSndFile->isOpen()) - return -1; - - snd_numBasesonEntries = snd_baseSndFile->readUint16BE(); - snd_baseSndFile->readUint16BE(); /* entry_size */ - snd_basesonEntries = (BasesonEntry *)malloc(snd_numBasesonEntries * sizeof(BasesonEntry)); - if (snd_basesonEntries) { - for (i = 0; i < snd_numBasesonEntries; ++i) { - BasesonEntry *be = &snd_basesonEntries[i]; - snd_baseSndFile->read(be->name, 14); - be->offset = snd_baseSndFile->readUint32BE(); - be->size = snd_baseSndFile->readUint32BE(); - be->unpackedSize = snd_baseSndFile->readUint32BE(); - snd_baseSndFile->readUint32BE(); /* unused */ - } - } - return 0; -} - -void snd_clearBasesonEntries() { - snd_baseSndFile->close(); - delete snd_baseSndFile; - free(snd_basesonEntries); - snd_basesonEntries = NULL; - snd_numBasesonEntries = 0; -} - -static int snd_findBasesonEntry(const char *entryName) { - int i; - char *p; - char basesonEntryName[20]; - - assert(strlen(entryName) < 20); - strcpy(basesonEntryName, entryName); - for (p = basesonEntryName; *p; ++p) { - if (*p >= 'a' && *p <= 'z') - *p += 'A' - 'a'; - } - - for (i = 0; i < snd_numBasesonEntries; ++i) { - if (strcmp(snd_basesonEntries[i].name, basesonEntryName) == 0) - return i; - } - return -1; -} - -byte *snd_loadBasesonEntry(const char *entryName) { - int entryNum; - byte *entryData = NULL; - - if (g_cine->getGameType() == Cine::GType_OS) { - entryNum = findFileInBundle((const char *)entryName); - if (entryNum != -1) - entryData = readBundleFile(entryNum); - } else { - entryNum = snd_findBasesonEntry(entryName); - if (entryNum != -1 && entryNum < snd_numBasesonEntries) { - const BasesonEntry *be = &snd_basesonEntries[entryNum]; - entryData = (byte *)malloc(be->unpackedSize); - if (entryData) { - if (be->unpackedSize > be->size) { - byte *tempData = (byte *)malloc(be->size); - if (tempData) { - snd_baseSndFile->seek(be->offset, SEEK_SET); - snd_baseSndFile->read(tempData, be->size); - delphineUnpack(entryData, tempData, be->size); - free(tempData); - } - } else { - snd_baseSndFile->seek(be->offset, SEEK_SET); - snd_baseSndFile->read(entryData, be->size); - } - } - } - } - - return entryData; -} - -} // End of namespace Cine diff --git a/engines/cine/script.cpp b/engines/cine/script.cpp index c0c1e82b10..738ade2834 100644 --- a/engines/cine/script.cpp +++ b/engines/cine/script.cpp @@ -28,8 +28,7 @@ #include "cine/cine.h" #include "cine/bg_list.h" #include "cine/object.h" -#include "cine/sfx_player.h" -#include "cine/sound_driver.h" +#include "cine/sound.h" #include "cine/various.h" namespace Cine { @@ -41,385 +40,389 @@ uint16 _currentPosition; uint16 _currentLine; uint16 _closeScript; -typedef void (*OpcodeProc) (); -const OpcodeProc *_opcodeTable; +struct Opcode { + void (*proc)(); + const char *args; +}; + +const Opcode *_opcodeTable; int _numOpcodes; void setupOpcodes() { - static const OpcodeProc opcodeTableFW[] = { + static const Opcode opcodeTableFW[] = { /* 00 */ - o1_modifyObjectParam, - o1_getObjectParam, - o1_addObjectParam, - o1_subObjectParam, + { o1_modifyObjectParam, "bbw" }, + { o1_getObjectParam, "bbb" }, + { o1_addObjectParam, "bbw" }, + { o1_subObjectParam, "bbw" }, /* 04 */ - o1_add2ObjectParam, - o1_sub2ObjectParam, - o1_compareObjectParam, - o1_setupObject, + { o1_add2ObjectParam, "bbw" }, + { o1_sub2ObjectParam, "bbw" }, + { o1_compareObjectParam, "bbw" }, + { o1_setupObject, "bwwww" }, /* 08 */ - o1_checkCollision, - o1_loadVar, - o1_addVar, - o1_subVar, + { o1_checkCollision, "bwwww" }, + { o1_loadVar, "bc" }, + { o1_addVar, "bc" }, + { o1_subVar, "bc" }, /* 0C */ - o1_mulVar, - o1_divVar, - o1_compareVar, - o1_modifyObjectParam2, + { o1_mulVar, "bc" }, + { o1_divVar, "bc" }, + { o1_compareVar, "bc" }, + { o1_modifyObjectParam2, "bbb" }, /* 10 */ - NULL, - NULL, - NULL, - o1_loadMask0, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_loadMask0, "b" }, /* 14 */ - o1_unloadMask0, - o1_addToBgList, - o1_loadMask1, - o1_unloadMask1, + { o1_unloadMask0, "b" }, + { o1_addToBgList, "b" }, + { o1_loadMask1, "b" }, + { o1_unloadMask1, "b" }, /* 18 */ - o1_loadMask4, - o1_unloadMask4, - o1_addSpriteFilledToBgList, - o1_op1B, + { o1_loadMask4, "b" }, + { o1_unloadMask4, "b" }, + { o1_addSpriteFilledToBgList, "b" }, + { o1_op1B, "" }, /* 1C */ - NULL, - o1_label, - o1_goto, - o1_gotoIfSup, + { 0, 0 }, + { o1_label, "l" }, + { o1_goto, "b" }, + { o1_gotoIfSup, "b" }, /* 20 */ - o1_gotoIfSupEqu, - o1_gotoIfInf, - o1_gotoIfInfEqu, - o1_gotoIfEqu, + { o1_gotoIfSupEqu, "b" }, + { o1_gotoIfInf, "b" }, + { o1_gotoIfInfEqu, "b" }, + { o1_gotoIfEqu, "b" }, /* 24 */ - o1_gotoIfDiff, - o1_removeLabel, - o1_loop, - NULL, + { o1_gotoIfDiff, "b" }, + { o1_removeLabel, "b" }, + { o1_loop, "bb" }, + { 0, 0 }, /* 28 */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 2C */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 30 */ - NULL, - o1_startGlobalScript, - o1_endGlobalScript, - NULL, + { 0, 0 }, + { o1_startGlobalScript, "b" }, + { o1_endGlobalScript, "b" }, + { 0, 0 }, /* 34 */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 38 */ - NULL, - NULL, - NULL, - o1_loadAnim, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_loadAnim, "s" }, /* 3C */ - o1_loadBg, - o1_loadCt, - NULL, - o1_loadPart, + { o1_loadBg, "s" }, + { o1_loadCt, "s" }, + { 0, 0 }, + { o1_loadPart, "s" }, /* 40 */ - o1_closePart, - o1_loadNewPrcName, - o1_requestCheckPendingDataLoad, - NULL, + { o1_closePart, "" }, + { o1_loadNewPrcName, "bs" }, + { o1_requestCheckPendingDataLoad, "" }, + { 0, 0 }, /* 44 */ - NULL, - o1_blitAndFade, - o1_fadeToBlack, - o1_transformPaletteRange, + { 0, 0 }, + { o1_blitAndFade, "" }, + { o1_fadeToBlack, "" }, + { o1_transformPaletteRange, "bbwww" }, /* 48 */ - NULL, - o1_setDefaultMenuColor2, - o1_palRotate, - NULL, + { 0, 0 }, + { o1_setDefaultMenuColor2, "b" }, + { o1_palRotate, "bbb" }, + { 0, 0 }, /* 4C */ - NULL, - NULL, - NULL, - o1_break, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_break, "" }, /* 50 */ - o1_endScript, - o1_message, - o1_loadGlobalVar, - o1_compareGlobalVar, + { o1_endScript, "x" }, + { o1_message, "bwwww" }, + { o1_loadGlobalVar, "bc" }, + { o1_compareGlobalVar, "bc" }, /* 54 */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 58 */ - NULL, - o1_declareFunctionName, - o1_freePartRange, - o1_unloadAllMasks, + { 0, 0 }, + { o1_declareFunctionName, "s" }, + { o1_freePartRange, "bb" }, + { o1_unloadAllMasks, "" }, // 5C */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 60 */ - NULL, - NULL, - NULL, - o1_op63, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_op63, "wwww" }, /* 64 */ - o1_op64, - o1_initializeZoneData, - o1_setZoneDataEntry, - o1_getZoneDataEntry, + { o1_op64, "" }, + { o1_initializeZoneData, "" }, + { o1_setZoneDataEntry, "bw" }, + { o1_getZoneDataEntry, "bb" }, /* 68 */ - o1_setDefaultMenuColor, - o1_allowPlayerInput, - o1_disallowPlayerInput, - o1_changeDataDisk, + { o1_setDefaultMenuColor, "b" }, + { o1_allowPlayerInput, "" }, + { o1_disallowPlayerInput, "" }, + { o1_changeDataDisk, "b" }, /* 6C */ - NULL, - o1_loadMusic, - o1_playMusic, - o1_fadeOutMusic, + { 0, 0 }, + { o1_loadMusic, "s" }, + { o1_playMusic, "" }, + { o1_fadeOutMusic, "" }, /* 70 */ - o1_stopSample, - o1_op71, - o1_op72, - o1_op73, + { o1_stopSample, "" }, + { o1_op71, "bw" }, + { o1_op72, "wbw" }, + { o1_op73, "wbw" }, /* 74 */ - NULL, - NULL, - NULL, - o1_playSample, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_playSample, "bbwbww" }, /* 78 */ - o1_playSample, - o1_disableSystemMenu, - o1_loadMask5, - o1_unloadMask5 + { o1_playSample, "bbwbww" }, + { o1_disableSystemMenu, "b" }, + { o1_loadMask5, "b" }, + { o1_unloadMask5, "b" } }; // TODO: We need to verify the Operation Stealth opcodes. - static const OpcodeProc opcodeTableOS[] = { + static const Opcode opcodeTableOS[] = { /* 00 */ - o1_modifyObjectParam, - o1_getObjectParam, - o1_addObjectParam, - o1_subObjectParam, + { o1_modifyObjectParam, "bbw" }, + { o1_getObjectParam, "bbb" }, + { o1_addObjectParam, "bbw" }, + { o1_subObjectParam, "bbw" }, /* 04 */ - o1_add2ObjectParam, - o1_sub2ObjectParam, - o1_compareObjectParam, - o1_setupObject, + { o1_add2ObjectParam, "bbw" }, + { o1_sub2ObjectParam, "bbw" }, + { o1_compareObjectParam, "bbw" }, + { o1_setupObject, "bwwww" }, /* 08 */ - o1_checkCollision, - o1_loadVar, - o1_addVar, - o1_subVar, + { o1_checkCollision, "bwwww" }, + { o1_loadVar, "bc" }, + { o1_addVar, "bc" }, + { o1_subVar, "bc" }, /* 0C */ - o1_mulVar, - o1_divVar, - o1_compareVar, - o1_modifyObjectParam2, + { o1_mulVar, "bc" }, + { o1_divVar, "bc" }, + { o1_compareVar, "bc" }, + { o1_modifyObjectParam2, "bbb" }, /* 10 */ - NULL, - NULL, - NULL, - o1_loadMask0, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_loadMask0, "b" }, /* 14 */ - o1_unloadMask0, - o1_addToBgList, - o1_loadMask1, - o1_unloadMask1, + { o1_unloadMask0, "b" }, + { o1_addToBgList, "b" }, + { o1_loadMask1, "b" }, + { o1_unloadMask1, "b" }, /* 18 */ - o1_loadMask4, - o1_unloadMask4, - o1_addSpriteFilledToBgList, - o1_op1B, + { o1_loadMask4, "b" }, + { o1_unloadMask4, "b" }, + { o1_addSpriteFilledToBgList, "b" }, + { o1_op1B, "" }, /* 1C */ - NULL, - o1_label, - o1_goto, - o1_gotoIfSup, + { 0, 0 }, + { o1_label, "l" }, + { o1_goto, "b" }, + { o1_gotoIfSup, "b" }, /* 20 */ - o1_gotoIfSupEqu, - o1_gotoIfInf, - o1_gotoIfInfEqu, - o1_gotoIfEqu, + { o1_gotoIfSupEqu, "b" }, + { o1_gotoIfInf, "b" }, + { o1_gotoIfInfEqu, "b" }, + { o1_gotoIfEqu, "b" }, /* 24 */ - o1_gotoIfDiff, - o1_removeLabel, - o1_loop, - NULL, + { o1_gotoIfDiff, "b" }, + { o1_removeLabel, "b" }, + { o1_loop, "bb" }, + { 0, 0 }, /* 28 */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 2C */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 30 */ - NULL, - o1_startGlobalScript, - o1_endGlobalScript, - NULL, + { 0, 0 }, + { o1_startGlobalScript, "b" }, + { o1_endGlobalScript, "b" }, + { 0, 0 }, /* 34 */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 38 */ - NULL, - NULL, - NULL, - o1_loadAnim, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_loadAnim, "s" }, /* 3C */ - o1_loadBg, - o1_loadCt, - NULL, - o2_loadPart, + { o1_loadBg, "s" }, + { o1_loadCt, "s" }, + { 0, 0 }, + { o2_loadPart, "s" }, /* 40 */ - NULL, - o1_loadNewPrcName, - o1_requestCheckPendingDataLoad, - NULL, + { 0, 0 }, + { o1_loadNewPrcName, "bs" }, + { o1_requestCheckPendingDataLoad, "" }, + { 0, 0 }, /* 44 */ - NULL, - o1_blitAndFade, - o1_fadeToBlack, - o1_transformPaletteRange, + { 0, 0 }, + { o1_blitAndFade, "" }, + { o1_fadeToBlack, "" }, + { o1_transformPaletteRange, "bbwww" }, /* 48 */ - NULL, - o1_setDefaultMenuColor2, - o1_palRotate, - NULL, + { 0, 0 }, + { o1_setDefaultMenuColor2, "b" }, + { o1_palRotate, "bbb" }, + { 0, 0 }, /* 4C */ - NULL, - NULL, - NULL, - o1_break, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_break, "" }, /* 50 */ - o1_endScript, - o1_message, - o1_loadGlobalVar, - o1_compareGlobalVar, + { o1_endScript, "x" }, + { o1_message, "bwwww" }, + { o1_loadGlobalVar, "bc" }, + { o1_compareGlobalVar, "bc" }, /* 54 */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 58 */ - NULL, - o1_declareFunctionName, - o1_freePartRange, - o1_unloadAllMasks, + { 0, 0 }, + { o1_declareFunctionName, "s" }, + { o1_freePartRange, "bb" }, + { o1_unloadAllMasks, "" }, // 5C */ - NULL, - NULL, - NULL, - NULL, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, /* 60 */ - NULL, - NULL, - NULL, - o1_op63, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o1_op63, "wwww" }, /* 64 */ - o1_op64, - o1_initializeZoneData, - o1_setZoneDataEntry, - o1_getZoneDataEntry, + { o1_op64, "" }, + { o1_initializeZoneData, "" }, + { o1_setZoneDataEntry, "bw" }, + { o1_getZoneDataEntry, "bb" }, /* 68 */ - o1_setDefaultMenuColor, - o1_allowPlayerInput, - o1_disallowPlayerInput, - o1_changeDataDisk, + { o1_setDefaultMenuColor, "b" }, + { o1_allowPlayerInput, "" }, + { o1_disallowPlayerInput, "" }, + { o1_changeDataDisk, "b" }, /* 6C */ - NULL, - o1_loadMusic, - o1_playMusic, - o1_fadeOutMusic, + { 0, 0 }, + { o1_loadMusic, "s" }, + { o1_playMusic, "" }, + { o1_fadeOutMusic, "" }, /* 70 */ - o1_stopSample, - o1_op71, - o1_op72, - o1_op72, + { o1_stopSample, "" }, + { o1_op71, "bw" }, + { o1_op72, "wbw" }, + { o1_op72, "wbw" }, /* 74 */ - NULL, - NULL, - NULL, - o1_playSample, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o2_playSample, "bbwbww" }, /* 78 */ - o2_op78, - o1_disableSystemMenu, - o1_loadMask5, - o1_unloadMask5, + { o2_playSampleAlt, "bbwbww" }, + { o1_disableSystemMenu, "b" }, + { o1_loadMask5, "b" }, + { o1_unloadMask5, "b" }, /* 7C */ - NULL, - NULL, - NULL, - o2_addSeqListElement, + { 0, 0 }, + { 0, 0 }, + { 0, 0 }, + { o2_addSeqListElement, "bbbbwww" }, /* 80 */ - o2_removeSeq, - o2_op81, - o2_op82, - o2_isSeqRunning, + { o2_removeSeq, "bb" }, + { o2_op81, "" }, + { o2_op82, "bbw" }, + { o2_isSeqRunning, "bb" }, /* 84 */ - o2_gotoIfSupNearest, - o2_gotoIfSupEquNearest, - o2_gotoIfInfNearest, - o2_gotoIfInfEquNearest, + { o2_gotoIfSupNearest, "b" }, + { o2_gotoIfSupEquNearest, "b" }, + { o2_gotoIfInfNearest, "b" }, + { o2_gotoIfInfEquNearest, "b" }, /* 88 */ - o2_gotoIfEquNearest, - o2_gotoIfDiffNearest, - NULL, - o2_startObjectScript, + { o2_gotoIfEquNearest, "b" }, + { o2_gotoIfDiffNearest, "b" }, + { 0, 0 }, + { o2_startObjectScript, "b" }, /* 8C */ - o2_stopObjectScript, - o2_op8D, - o2_addBackground, - o2_removeBackground, + { o2_stopObjectScript, "b" }, + { o2_op8D, "wwwwwwww" }, + { o2_addBackground, "bs" }, + { o2_removeBackground, "b" }, /* 90 */ - o2_loadAbs, - o2_loadBg, - NULL, - NULL, + { o2_loadAbs, "bs" }, + { o2_loadBg, "b" }, + { 0, 0 }, + { 0, 0 }, /* 94 */ - NULL, - o1_changeDataDisk, - NULL, - NULL, + { 0, 0 }, + { o1_changeDataDisk, "b" }, + { 0, 0 }, + { 0, 0 }, /* 98 */ - NULL, - NULL, - o2_wasZoneChecked, - o2_op9B, + { 0, 0 }, + { 0, 0 }, + { o2_wasZoneChecked, "" }, + { o2_op9B, "wwwwwwww" }, /* 9C */ - o2_op9C, - o2_useBgScroll, - o2_setAdditionalBgVScroll, - o2_op9F, + { o2_op9C, "wwww" }, + { o2_useBgScroll, "b" }, + { o2_setAdditionalBgVScroll, "c" }, + { o2_op9F, "ww" }, /* A0 */ - o2_addGfxElementA0, - o2_opA1, - o2_opA2, - o2_opA3, + { o2_addGfxElementA0, "ww" }, + { o2_opA1, "ww" }, + { o2_opA2, "ww" }, + { o2_opA3, "ww" }, /* A4 */ - o2_loadMask22, - o2_unloadMask22, - NULL, - NULL, + { o2_loadMask22, "b" }, + { o2_unloadMask22, "b" }, + { 0, 0 }, + { 0, 0 }, /* A8 */ - NULL, - o1_changeDataDisk + { 0, 0 }, + { o1_changeDataDisk, "b" } }; if (g_cine->getGameType() == Cine::GType_FW) { @@ -445,7 +448,7 @@ uint16 getNextWord() { const char *getNextString() { const char *val = (const char *)(_currentScriptPtr + _currentPosition); - _currentPosition += strlen(val); + _currentPosition += strlen(val) + 1; return val; } @@ -545,269 +548,74 @@ void stopGlobalScript(uint16 scriptIdx) { currentHead->scriptIdx = -1; } -uint16 computeScriptStackSub(byte mode, byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, byte param1, uint16 startOffset) { - byte *localScriptPtr = scriptPtr; - uint16 exitScript; - uint16 i; +uint16 computeScriptStackSub(bool computeAllLabels, byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, byte labelIndex, uint16 startOffset) { uint16 position; - uint16 di; - assert(scriptPtr); - assert(stackPtr); - - if (mode == 1) { - for (i = 0; i < SCRIPT_STACK_SIZE; i++) { + if (computeAllLabels) { + for (int i = 0; i < SCRIPT_STACK_SIZE; i++) { stackPtr[i] = -1; } - position = 0; } else { position = startOffset; } - - exitScript = 0; - - do { - uint16 opcode = *(localScriptPtr + position); + while (position < scriptSize) { + uint8 opcode = scriptPtr[position]; position++; - - //printf("Opcode: %X\n",opcode-1); - - switch (opcode - 1) { - case -1: - case 0x1B: - { - break; - } - case 0x89: - case 0x32: - case 0x7A: - case 0x91: - case 0x9D: - case 0x8F: - case 0x7B: - case 0x8C: - case 0x8B: - case 0x85: - case 0x86: - case 0x84: - case 0x88: - { + if (opcode == 0 || opcode > _numOpcodes) { + continue; + } + if (!_opcodeTable[opcode - 1].args) { + warning("Undefined opcode 0x%02X in computeScriptStackSub", opcode - 1); + continue; + } + for (const char *p = _opcodeTable[opcode - 1].args; *p; ++p) { + switch (*p) { + case 'b': // byte position++; break; - } - case 0x80: - case 0x83: - case 0x26: - { + case 'w': // word position += 2; break; - } - case 0xF: - case 0x1: - case 0x66: - case 0x4A: - { - position += 3; - break; - } - case 0x0: - case 0x2: - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0xA0: - case 0xA1: - case 0xA2: - case 0xA3: - { - position += 4; - break; - } - case 0x9: - case 0xA: - case 0xB: - case 0xC: - case 0xD: - case 0xE: - case 0x52: - case 0x53: - { - byte param; - position++; - - param = *(localScriptPtr + position); - position++; - - if (param) { + case 'c': { // byte != 0 ? byte : word + uint8 test = scriptPtr[position]; position++; - } else { - position += 2; + if (test) { + position++; + } else { + position += 2; + } } break; - } - case 0x9E: - { - byte param; - - param = *(localScriptPtr + position); - position++; - - if (param) { + case 'l': { // label + uint8 index = scriptPtr[position]; position++; - } else { - position += 2; - } - break; - } - case 0x82: - { - position += 7; - break; - } - case 0x47: - { - position += 8; - break; - } - case 0x51: - case 0x7: - case 0x77: - case 0x78: - case 0x8: - { - position += 9; - break; - } - case 0x7F: - { - position += 10; - break; - } - case 0x1D: - { - di = *(localScriptPtr + position); - position++; - - if (mode == 1) { - stackPtr[di] = position; - } else { - if (param1 == di) { - return position; + if (computeAllLabels) { + stackPtr[index] = position; + } else { + if (labelIndex == index) { + return position; + } } } - break; - } - case 0x59: - case 0x3B: - case 0x3C: - case 0x3D: - case OP_loadPart: // skipString - case 0x6D: - case 0x8E: - { - do { - position++; - } while (*(localScriptPtr + position)); + case 's': // string + while (scriptPtr[position++] != 0); break; - } - case 0x90: - case OP_loadNewPrcName: //skipVarAndString - { - di = *(localScriptPtr + position); - position++; - - do { - position++; - } while (*(localScriptPtr + position)); - - break; - } - case 0x46: - case 0x65: - case 0x4F: - case 0x40: - case 0x6A: - case 0x69: - case 0x45: - case 0x6E: - case 0x6F: - case 0x70: - { - break; - } - case 0x1E: - case 0x1F: - case 0x20: - case 0x21: - case 0x22: - case 0x23: - case 0x24: - case 0x25: - case 0x68: - case 0x49: - case 0x31: - case 0x13: - case 0x14: - case 0x15: - case 0x16: - case 0x17: - case 0x18: - case 0x19: - case 0x1A: - { - position++; - break; - } - case 0x5A: - { - position += 2; - break; - } - case 0x5B: - { - break; - } - case OP_changeDataDisk: // skipVar - case OP_79: - { - di = *(localScriptPtr + position); - position++; - - break; - } - case OP_endScript: // end - { - exitScript = 1; - break; - } - case OP_requestCheckPendingDataLoad: // nop - { - break; - } - default: - { - error("Unsupported opcode %X in computeScriptStack", opcode - 1); + case 'x': // exit script + return position; } } - - if (position > scriptSize) { - exitScript = 1; - } - - } while (!exitScript); - + } return position; } void computeScriptStack(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize) { - computeScriptStackSub(1, scriptPtr, stackPtr, scriptSize, 0, 0); + computeScriptStackSub(true, scriptPtr, stackPtr, scriptSize, 0, 0); } uint16 computeScriptStackFromScript(byte *scriptPtr, uint16 currentPosition, uint16 labelIdx, uint16 scriptSize) { - return computeScriptStackSub(0, scriptPtr, (int16 *)&dummyU16, (uint16)scriptSize, labelIdx, currentPosition); + return computeScriptStackSub(false, scriptPtr, (int16 *)&dummyU16, (uint16)scriptSize, labelIdx, currentPosition); } void palRotate(byte a, byte b, byte c) { @@ -1024,10 +832,16 @@ void o1_subObjectParam() { } void o1_add2ObjectParam() { + getNextByte(); + getNextByte(); + getNextWord(); warning("STUB: o1_add2ObjectParam()"); } void o1_sub2ObjectParam() { + getNextByte(); + getNextByte(); + getNextWord(); warning("STUB: o1_sub2ObjectParam()"); } @@ -1379,7 +1193,6 @@ void o1_gotoIfDiff() { } void o1_removeLabel() { - // TODO: verify this byte labelIdx = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: removeLabel(%d)", _currentLine, labelIdx); @@ -1659,7 +1472,10 @@ void o1_setZoneDataEntry() { } void o1_getZoneDataEntry() { - warning("STUB: o1_getZoneDataEntry()"); + byte zoneIdx = getNextByte(); + byte var = getNextByte(); + + _currentScriptElement->localVars[var] = zoneData[zoneIdx]; } void o1_setDefaultMenuColor() { @@ -1690,29 +1506,22 @@ void o1_loadMusic() { const char *param = getNextString(); debugC(5, kCineDebugScript, "Line: %d: loadMusic(%s)", _currentLine, param); - - if (g_cine->getPlatform() == Common::kPlatformAmiga || - g_cine->getPlatform() == Common::kPlatformAtariST) { - warning("STUB: o1_loadMusic"); - return; - } - - g_sfxPlayer->load(param); + g_sound->loadMusic(param); } void o1_playMusic() { debugC(5, kCineDebugScript, "Line: %d: playMusic()", _currentLine); - g_sfxPlayer->play(); + g_sound->playMusic(); } void o1_fadeOutMusic() { debugC(5, kCineDebugScript, "Line: %d: fadeOutMusic()", _currentLine); - g_sfxPlayer->fadeOut(); + g_sound->fadeOutMusic(); } void o1_stopSample() { debugC(5, kCineDebugScript, "Line: %d: stopSample()", _currentLine); - g_sfxPlayer->stop(); + g_sound->stopMusic(); } void o1_op71() { @@ -1743,37 +1552,53 @@ void o1_playSample() { byte anim = getNextByte(); byte channel = getNextByte(); - getNextWord(); - getNextByte(); + uint16 freq = getNextWord(); + byte repeat = getNextByte(); int16 volume = getNextWord(); - uint16 flag = getNextWord(); + uint16 size = getNextWord(); - if (g_cine->getPlatform() == Common::kPlatformAmiga || - g_cine->getPlatform() == Common::kPlatformAtariST) { - warning("STUB: o1_playSample"); + if (!animDataTable[anim].ptr1) { return; } - if (volume > 63) - volume = 63; - if (volume < 0) - volume = 63; - - if (animDataTable[anim].ptr1) { + if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) { + if (size == 0xFFFF) { + size = animDataTable[anim].width * animDataTable[anim].height; + } + if (channel < 10) { // || _currentOpcode == 0x78 + int channel1, channel2; + if (channel == 0) { + channel1 = 0; + channel2 = 1; + } else { + channel1 = 2; + channel2 = 3; + } + g_sound->playSound(channel1, freq, animDataTable[anim].ptr1, size, -1, volume, 63, repeat); + g_sound->playSound(channel2, freq, animDataTable[anim].ptr1, size, 1, volume, 0, repeat); + } else { + channel -= 10; + if (volume > 63) { + volume = 63; + } + g_sound->playSound(channel, freq, animDataTable[anim].ptr1, size, 0, 0, volume, repeat); + } + } else { + if (volume > 63 || volume < 0) { + volume = 63; + } if (channel >= 10) { channel -= 10; } if (volume < 50) { volume = 50; } - - g_sfxPlayer->stop(); - - if (flag == 0xFFFF) { - g_soundDriver->playSound(animDataTable[anim].ptr1, channel, volume); + g_sound->stopMusic(); + if (size == 0xFFFF) { + g_sound->playSound(channel, 0, animDataTable[anim].ptr1, 0, 0, 0, volume, 0); } else { - g_soundDriver->resetChannel(channel); + g_sound->stopSound(channel); } } } @@ -1809,12 +1634,41 @@ void o2_loadPart() { debugC(5, kCineDebugScript, "Line: %d: loadPart(\"%s\")", _currentLine, param); } -void o2_op78() { - warning("STUB: o2_op78()"); - // This is probably wrong, but preserve the old behaviour for now. +void o2_playSample() { + if (g_cine->getPlatform() == Common::kPlatformAmiga || g_cine->getPlatform() == Common::kPlatformAtariST) { + // no-op in these versions + getNextByte(); + getNextByte(); + getNextWord(); + getNextByte(); + getNextWord(); + getNextWord(); + return; + } o1_playSample(); } +void o2_playSampleAlt() { + byte num = getNextByte(); + byte channel = getNextByte(); + uint16 frequency = getNextWord(); + getNextByte(); + getNextWord(); + uint16 size = getNextWord(); + + if (size == 0xFFFF) { + size = animDataTable[num].width * animDataTable[num].height; + } + if (animDataTable[num].ptr1) { + if (g_cine->getPlatform() == Common::kPlatformPC) { + // if speaker output is enabled, play sound on it + // if it's another device, don't play anything + } else { + g_sound->playSound(channel, frequency, animDataTable[num].ptr1, size, 0, 0, 63, 0); + } + } +} + void o2_addSeqListElement() { byte param1 = getNextByte(); byte param2 = getNextByte(); @@ -2145,10 +1999,10 @@ void executeScript(prcLinkedListStruct *scriptElement, uint16 params) { byte opcode = getNextByte(); if (opcode && opcode < _numOpcodes) { - if (_opcodeTable[opcode - 1]) - (_opcodeTable[opcode - 1]) (); + if (_opcodeTable[opcode - 1].proc) + (_opcodeTable[opcode - 1].proc) (); else - warning("Undefined opcode 0x%02X", opcode - 1); + warning("Undefined opcode 0x%02X in executeScript", opcode - 1); } } } diff --git a/engines/cine/script.h b/engines/cine/script.h index e777c1fb6f..91e403d701 100644 --- a/engines/cine/script.h +++ b/engines/cine/script.h @@ -146,7 +146,8 @@ void o1_unloadMask5(); void o2_loadPart(); void o2_addSeqListElement(); void o2_removeSeq(); -void o2_op78(); +void o2_playSample(); +void o2_playSampleAlt(); void o2_op81(); void o2_op82(); void o2_isSeqRunning(); diff --git a/engines/cine/sfx_player.cpp b/engines/cine/sfx_player.cpp deleted file mode 100644 index 59b9c61041..0000000000 --- a/engines/cine/sfx_player.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * cinE Engine is (C) 2004-2005 by CinE Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/endian.h" -#include "common/system.h" - -#include "cine/cine.h" -#include "cine/sfx_player.h" -#include "cine/sound_driver.h" -#include "cine/unpack.h" -#include "cine/various.h" - -namespace Cine { - -SfxPlayer::SfxPlayer(SoundDriver *driver) - : _playing(false), _driver(driver) { - memset(_instrumentsData, 0, sizeof(_instrumentsData)); - _sfxData = NULL; - _fadeOutCounter = 0; - _driver->setUpdateCallback(updateCallback, this); -} - -SfxPlayer::~SfxPlayer() { - _driver->setUpdateCallback(NULL, NULL); - if (_playing) { - stop(); - } -} - -bool SfxPlayer::load(const char *song) { - debug(9, "SfxPlayer::load('%s')", song); - - /* stop (w/ fade out) the previous song */ - while (_fadeOutCounter != 0 && _fadeOutCounter < 100) { - g_system->delayMillis(50); - } - _fadeOutCounter = 0; - - if (_playing) { - stop(); - } - - /* like the original PC version, skip introduction song (file doesn't exist) */ - if (g_cine->getGameType() == Cine::GType_OS && strncmp(song, "INTRO", 5) == 0) { - return 0; - } - - _sfxData = snd_loadBasesonEntry(song); - if (!_sfxData) { - warning("Unable to load soundfx module '%s'", song); - return 0; - } - - for (int i = 0; i < NUM_INSTRUMENTS; ++i) { - _instrumentsData[i] = NULL; - - char instrument[13]; - memcpy(instrument, _sfxData + 20 + i * 30, 12); - instrument[12] = '\0'; - - if (strlen(instrument) != 0) { - char *dot = strrchr(instrument, '.'); - if (dot) { - *dot = '\0'; - } - strcat(instrument, _driver->getInstrumentExtension()); - _instrumentsData[i] = snd_loadBasesonEntry(instrument); - if (!_instrumentsData[i]) { - warning("Unable to load soundfx instrument '%s'", instrument); - } - } - } - return 1; -} - -void SfxPlayer::play() { - debug(9, "SfxPlayer::play()"); - if (_sfxData) { - for (int i = 0; i < NUM_CHANNELS; ++i) { - _instrumentsChannelTable[i] = -1; - } - _currentPos = 0; - _currentOrder = 0; - _numOrders = _sfxData[470]; - _eventsDelay = (252 - _sfxData[471]) * 50 / 1060; - _updateTicksCounter = 0; - _playing = true; - } -} - -void SfxPlayer::stop() { - _fadeOutCounter = 0; - _playing = false; - for (int i = 0; i < NUM_CHANNELS; ++i) { - _driver->stopChannel(i); - } - _driver->stopSound(); - unload(); -} - -void SfxPlayer::fadeOut() { - if (_playing) { - _fadeOutCounter = 1; - _playing = false; - } -} - -void SfxPlayer::updateCallback(void *ref) { - ((SfxPlayer *)ref)->update(); -} - -void SfxPlayer::update() { - if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) { - ++_updateTicksCounter; - if (_updateTicksCounter > _eventsDelay) { - handleEvents(); - _updateTicksCounter = 0; - } - } -} - -void SfxPlayer::handleEvents() { - const byte *patternData = _sfxData + 600; - const byte *orderTable = _sfxData + 472; - uint16 patternNum = orderTable[_currentOrder] * 1024; - - for (int i = 0; i < 4; ++i) { - handlePattern(i, patternData + patternNum + _currentPos); - patternData += 4; - } - - if (_fadeOutCounter != 0 && _fadeOutCounter < 100) { - _fadeOutCounter += 2; - } - _currentPos += 16; - if (_currentPos >= 1024) { - _currentPos = 0; - ++_currentOrder; - if (_currentOrder == _numOrders) { - _currentOrder = 0; - } - } - debug(7, "_currentOrder=%d/%d _currentPos=%d", _currentOrder, _numOrders, _currentPos); -} - -void SfxPlayer::handlePattern(int channel, const byte *patternData) { - int instrument = patternData[2] >> 4; - if (instrument != 0) { - --instrument; - if (_instrumentsChannelTable[channel] != instrument || _fadeOutCounter != 0) { - _instrumentsChannelTable[channel] = instrument; - const int volume = _sfxData[instrument] - _fadeOutCounter; - _driver->setupChannel(channel, _instrumentsData[instrument], instrument, volume); - } - } - int16 freq = (int16)READ_BE_UINT16(patternData); - if (freq > 0) { - _driver->stopChannel(channel); - _driver->setChannelFrequency(channel, freq); - } -} - -void SfxPlayer::unload() { - for (int i = 0; i < NUM_INSTRUMENTS; ++i) { - free(_instrumentsData[i]); - _instrumentsData[i] = NULL; - } - free(_sfxData); - _sfxData = NULL; -} - -} // End of namespace Cine diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp new file mode 100644 index 0000000000..a17433f176 --- /dev/null +++ b/engines/cine/sound.cpp @@ -0,0 +1,861 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" +#include "common/file.h" +#include "common/system.h" + +#include "cine/cine.h" +#include "cine/sound.h" + +#include "sound/audiostream.h" +#include "sound/fmopl.h" +#include "sound/mods/soundfx.h" + +namespace Cine { + +class PCSoundDriver { +public: + typedef void (*UpdateCallback)(void *); + + virtual ~PCSoundDriver() {} + + virtual void setupChannel(int channel, const byte *data, int instrument, int volume) = 0; + virtual void setChannelFrequency(int channel, int frequency) = 0; + virtual void stopChannel(int channel) = 0; + virtual void playSample(const byte *data, int size, int channel, int volume) = 0; + virtual void stopAll() = 0; + virtual const char *getInstrumentExtension() const { return ""; } + + void setUpdateCallback(UpdateCallback upCb, void *ref); + void resetChannel(int channel); + void findNote(int freq, int *note, int *oct) const; + +protected: + UpdateCallback _upCb; + void *_upRef; + + static const int _noteTable[]; + static const int _noteTableCount; +}; + +const int PCSoundDriver::_noteTable[] = { + 0xEEE, 0xE17, 0xD4D, 0xC8C, 0xBD9, 0xB2F, 0xA8E, 0x9F7, + 0x967, 0x8E0, 0x861, 0x7E8, 0x777, 0x70B, 0x6A6, 0x647, + 0x5EC, 0x597, 0x547, 0x4FB, 0x4B3, 0x470, 0x430, 0x3F4, + 0x3BB, 0x385, 0x353, 0x323, 0x2F6, 0x2CB, 0x2A3, 0x27D, + 0x259, 0x238, 0x218, 0x1FA, 0x1DD, 0x1C2, 0x1A9, 0x191, + 0x17B, 0x165, 0x151, 0x13E, 0x12C, 0x11C, 0x10C, 0x0FD, + 0x0EE, 0x0E1, 0x0D4, 0x0C8, 0x0BD, 0x0B2, 0x0A8, 0x09F, + 0x096, 0x08E, 0x086, 0x07E, 0x077, 0x070, 0x06A, 0x064, + 0x05E, 0x059, 0x054, 0x04F, 0x04B, 0x047, 0x043, 0x03F, + 0x03B, 0x038, 0x035, 0x032, 0x02F, 0x02C, 0x02A, 0x027, + 0x025, 0x023, 0x021, 0x01F, 0x01D, 0x01C, 0x01A, 0x019, + 0x017, 0x016, 0x015, 0x013, 0x012, 0x011, 0x010, 0x00F +}; + +const int PCSoundDriver::_noteTableCount = ARRAYSIZE(_noteTable); + +struct AdlibRegisterSoundInstrument { + uint16 vibrato; + uint16 attackDecay; + uint16 sustainRelease; + uint16 feedbackStrength; + uint16 keyScaling; + uint16 outputLevel; + uint16 freqMod; +}; + +struct AdlibSoundInstrument { + byte mode; + byte channel; + AdlibRegisterSoundInstrument regMod; + AdlibRegisterSoundInstrument regCar; + byte waveSelectMod; + byte waveSelectCar; + byte amDepth; +}; + +class AdlibSoundDriver : public PCSoundDriver, Audio::AudioStream { +public: + AdlibSoundDriver(Audio::Mixer *mixer); + virtual ~AdlibSoundDriver(); + + // PCSoundDriver interface + virtual void setupChannel(int channel, const byte *data, int instrument, int volume); + virtual void stopChannel(int channel); + virtual void stopAll(); + + // AudioStream interface + virtual int readBuffer(int16 *buffer, const int numSamples); + virtual bool isStereo() const { return false; } + virtual bool endOfData() const { return false; } + virtual int getRate() const { return _sampleRate; } + + void initCard(); + void update(int16 *buf, int len); + void setupInstrument(const byte *data, int channel); + void loadRegisterInstrument(const byte *data, AdlibRegisterSoundInstrument *reg); + virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi) = 0; + +protected: + FM_OPL *_opl; + int _sampleRate; + Audio::Mixer *_mixer; + Audio::SoundHandle _soundHandle; + + byte _vibrato; + int _channelsVolumeTable[4]; + AdlibSoundInstrument _instrumentsTable[4]; + + static const int _freqTable[]; + static const int _freqTableCount; + static const int _operatorsTable[]; + static const int _operatorsTableCount; + static const int _voiceOperatorsTable[]; + static const int _voiceOperatorsTableCount; +}; + +const int AdlibSoundDriver::_freqTable[] = { + 0x157, 0x16C, 0x181, 0x198, 0x1B1, 0x1CB, + 0x1E6, 0x203, 0x222, 0x243, 0x266, 0x28A +}; + +const int AdlibSoundDriver::_freqTableCount = ARRAYSIZE(_freqTable); + +const int AdlibSoundDriver::_operatorsTable[] = { + 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 +}; + +const int AdlibSoundDriver::_operatorsTableCount = ARRAYSIZE(_operatorsTable); + +const int AdlibSoundDriver::_voiceOperatorsTable[] = { + 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 16, 16, 14, 14, 17, 17, 13, 13 +}; + +const int AdlibSoundDriver::_voiceOperatorsTableCount = ARRAYSIZE(_voiceOperatorsTable); + +// Future Wars Adlib driver +class AdlibSoundDriverINS : public AdlibSoundDriver { +public: + AdlibSoundDriverINS(Audio::Mixer *mixer) : AdlibSoundDriver(mixer) {} + virtual const char *getInstrumentExtension() const { return ".INS"; } + virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi); + virtual void setChannelFrequency(int channel, int frequency); + virtual void playSample(const byte *data, int size, int channel, int volume); +}; + +// Operation Stealth Adlib driver +class AdlibSoundDriverADL : public AdlibSoundDriver { +public: + AdlibSoundDriverADL(Audio::Mixer *mixer) : AdlibSoundDriver(mixer) {} + virtual const char *getInstrumentExtension() const { return ".ADL"; } + virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi); + virtual void setChannelFrequency(int channel, int frequency); + virtual void playSample(const byte *data, int size, int channel, int volume); +}; + +class PCSoundFxPlayer { +public: + + PCSoundFxPlayer(PCSoundDriver *driver); + ~PCSoundFxPlayer(); + + bool load(const char *song); + void play(); + void stop(); + void fadeOut(); + + static void updateCallback(void *ref); + + enum { + NUM_INSTRUMENTS = 15, + NUM_CHANNELS = 4 + }; + +private: + + void update(); + void handleEvents(); + void handlePattern(int channel, const byte *patternData); + void unload(); + + bool _playing; + int _currentPos; + int _currentOrder; + int _numOrders; + int _eventsDelay; + int _fadeOutCounter; + int _updateTicksCounter; + int _instrumentsChannelTable[NUM_CHANNELS]; + byte *_sfxData; + byte *_instrumentsData[NUM_INSTRUMENTS]; + PCSoundDriver *_driver; +}; + + +void PCSoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) { + _upCb = upCb; + _upRef = ref; +} + +void PCSoundDriver::findNote(int freq, int *note, int *oct) const { + *note = _noteTableCount - 1; + for (int i = 0; i < _noteTableCount; ++i) { + if (_noteTable[i] <= freq) { + *note = i; + break; + } + } + *oct = *note / 12; +} + +void PCSoundDriver::resetChannel(int channel) { + stopChannel(channel); + stopAll(); +} + +AdlibSoundDriver::AdlibSoundDriver(Audio::Mixer *mixer) + : _mixer(mixer) { + _sampleRate = _mixer->getOutputRate(); + _opl = makeAdlibOPL(_sampleRate); + memset(_channelsVolumeTable, 0, sizeof(_channelsVolumeTable)); + memset(_instrumentsTable, 0, sizeof(_instrumentsTable)); + initCard(); + _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true); +} + +AdlibSoundDriver::~AdlibSoundDriver() { + _mixer->stopHandle(_soundHandle); +} + +void AdlibSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) { + assert(channel < 4); + if (data) { + if (volume > 80) { + volume = 80; + } else if (volume < 0) { + volume = 0; + } + volume += volume / 4; + if (volume > 127) { + volume = 127; + } + _channelsVolumeTable[channel] = volume; + setupInstrument(data, channel); + } +} + +void AdlibSoundDriver::stopChannel(int channel) { + assert(channel < 4); + AdlibSoundInstrument *ins = &_instrumentsTable[channel]; + if (ins->mode != 0 && ins->channel == 6) { + channel = 6; + } + if (ins->mode == 0 || channel == 6) { + OPLWriteReg(_opl, 0xB0 | channel, 0); + } + if (ins->mode != 0) { + _vibrato &= ~(1 << (10 - ins->channel)); + OPLWriteReg(_opl, 0xBD, _vibrato); + } +} + +void AdlibSoundDriver::stopAll() { + int i; + for (i = 0; i < 18; ++i) { + OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 63); + } + for (i = 0; i < 9; ++i) { + OPLWriteReg(_opl, 0xB0 | i, 0); + } + OPLWriteReg(_opl, 0xBD, 0); +} + +int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) { + update(buffer, numSamples); + return numSamples; +} + +void AdlibSoundDriver::initCard() { + _vibrato = 0x20; + OPLWriteReg(_opl, 0xBD, _vibrato); + OPLWriteReg(_opl, 0x08, 0x40); + + int i; + for (i = 0; i < 18; ++i) { + OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 0); + } + for (i = 0; i < 9; ++i) { + OPLWriteReg(_opl, 0xB0 | i, 0); + } + for (i = 0; i < 9; ++i) { + OPLWriteReg(_opl, 0xC0 | i, 0); + } + for (i = 0; i < 18; ++i) { + OPLWriteReg(_opl, 0x60 | _operatorsTable[i], 0); + } + for (i = 0; i < 18; ++i) { + OPLWriteReg(_opl, 0x80 | _operatorsTable[i], 0); + } + for (i = 0; i < 18; ++i) { + OPLWriteReg(_opl, 0x20 | _operatorsTable[i], 0); + } + for (i = 0; i < 18; ++i) { + OPLWriteReg(_opl, 0xE0 | _operatorsTable[i], 0); + } + + OPLWriteReg(_opl, 1, 0x20); + OPLWriteReg(_opl, 1, 0); +} + +void AdlibSoundDriver::update(int16 *buf, int len) { + static int samplesLeft = 0; + while (len != 0) { + int count = samplesLeft; + if (count > len) { + count = len; + } + samplesLeft -= count; + len -= count; + YM3812UpdateOne(_opl, buf, count); + if (samplesLeft == 0) { + if (_upCb) { + (*_upCb)(_upRef); + } + samplesLeft = _sampleRate / 50; + } + buf += count; + } +} + +void AdlibSoundDriver::setupInstrument(const byte *data, int channel) { + assert(channel < 4); + AdlibSoundInstrument *ins = &_instrumentsTable[channel]; + loadInstrument(data, ins); + + int mod, car, tmp; + const AdlibRegisterSoundInstrument *reg; + + if (ins->mode != 0) { + mod = _operatorsTable[_voiceOperatorsTable[2 * ins->channel + 0]]; + car = _operatorsTable[_voiceOperatorsTable[2 * ins->channel + 1]]; + } else { + mod = _operatorsTable[_voiceOperatorsTable[2 * channel + 0]]; + car = _operatorsTable[_voiceOperatorsTable[2 * channel + 1]]; + } + + if (ins->mode == 0 || ins->channel == 6) { + reg = &ins->regMod; + OPLWriteReg(_opl, 0x20 | mod, reg->vibrato); + if (reg->freqMod) { + tmp = reg->outputLevel & 0x3F; + } else { + tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel]; + tmp = 63 - (2 * tmp + 127) / (2 * 127); + } + OPLWriteReg(_opl, 0x40 | mod, tmp | (reg->keyScaling << 6)); + OPLWriteReg(_opl, 0x60 | mod, reg->attackDecay); + OPLWriteReg(_opl, 0x80 | mod, reg->sustainRelease); + if (ins->mode != 0) { + OPLWriteReg(_opl, 0xC0 | ins->channel, reg->feedbackStrength); + } else { + OPLWriteReg(_opl, 0xC0 | channel, reg->feedbackStrength); + } + OPLWriteReg(_opl, 0xE0 | mod, ins->waveSelectMod); + } + + reg = &ins->regCar; + OPLWriteReg(_opl, 0x20 | car, reg->vibrato); + tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel]; + tmp = 63 - (2 * tmp + 127) / (2 * 127); + OPLWriteReg(_opl, 0x40 | car, tmp | (reg->keyScaling << 6)); + OPLWriteReg(_opl, 0x60 | car, reg->attackDecay); + OPLWriteReg(_opl, 0x80 | car, reg->sustainRelease); + OPLWriteReg(_opl, 0xE0 | car, ins->waveSelectCar); +} + +void AdlibSoundDriver::loadRegisterInstrument(const byte *data, AdlibRegisterSoundInstrument *reg) { + reg->vibrato = 0; + if (READ_LE_UINT16(data + 18)) { // amplitude vibrato + reg->vibrato |= 0x80; + } + if (READ_LE_UINT16(data + 20)) { // frequency vibrato + reg->vibrato |= 0x40; + } + if (READ_LE_UINT16(data + 10)) { // sustaining sound + reg->vibrato |= 0x20; + } + if (READ_LE_UINT16(data + 22)) { // envelope scaling + reg->vibrato |= 0x10; + } + reg->vibrato |= READ_LE_UINT16(data + 2) & 0xF; // frequency multiplier + + reg->attackDecay = READ_LE_UINT16(data + 6) << 4; // attack rate + reg->attackDecay |= READ_LE_UINT16(data + 12) & 0xF; // decay rate + + reg->sustainRelease = READ_LE_UINT16(data + 8) << 4; // sustain level + reg->sustainRelease |= READ_LE_UINT16(data + 14) & 0xF; // release rate + + reg->feedbackStrength = READ_LE_UINT16(data + 4) << 1; // feedback + if (READ_LE_UINT16(data + 24) == 0) { // frequency modulation + reg->feedbackStrength |= 1; + } + + reg->keyScaling = READ_LE_UINT16(data); + reg->outputLevel = READ_LE_UINT16(data + 16); + reg->freqMod = READ_LE_UINT16(data + 24); +} + +void AdlibSoundDriverINS::loadInstrument(const byte *data, AdlibSoundInstrument *asi) { + asi->mode = *data++; + asi->channel = *data++; + loadRegisterInstrument(data, &asi->regMod); data += 26; + loadRegisterInstrument(data, &asi->regCar); data += 26; + asi->waveSelectMod = data[0] & 3; data += 2; + asi->waveSelectCar = data[0] & 3; data += 2; + asi->amDepth = data[0]; data += 2; +} + +void AdlibSoundDriverINS::setChannelFrequency(int channel, int frequency) { + assert(channel < 4); + AdlibSoundInstrument *ins = &_instrumentsTable[channel]; + if (ins->mode != 0 && ins->channel == 6) { + channel = 6; + } + if (ins->mode == 0 || ins->channel == 6) { + int freq, note, oct; + findNote(frequency, ¬e, &oct); + if (channel == 6) { + note %= 12; + } + freq = _freqTable[note % 12]; + OPLWriteReg(_opl, 0xA0 | channel, freq); + freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); + if (ins->mode == 0) { + freq |= 0x20; + } + OPLWriteReg(_opl, 0xB0 | channel, freq); + } + if (ins->mode != 0) { + _vibrato |= 1 << (10 - ins->channel); + OPLWriteReg(_opl, 0xBD, _vibrato); + } +} + +void AdlibSoundDriverINS::playSample(const byte *data, int size, int channel, int volume) { + assert(channel < 4); + _channelsVolumeTable[channel] = 127; + resetChannel(channel); + setupInstrument(data + 257, channel); + AdlibSoundInstrument *ins = &_instrumentsTable[channel]; + if (ins->mode != 0 && ins->channel == 6) { + channel = 6; + } + if (ins->mode == 0 || channel == 6) { + uint16 note = 12; + int freq = _freqTable[note % 12]; + OPLWriteReg(_opl, 0xA0 | channel, freq); + freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); + if (ins->mode == 0) { + freq |= 0x20; + } + OPLWriteReg(_opl, 0xB0 | channel, freq); + } + if (ins->mode != 0) { + _vibrato |= 1 << (10 - ins->channel); + OPLWriteReg(_opl, 0xBD, _vibrato); + } +} + +void AdlibSoundDriverADL::loadInstrument(const byte *data, AdlibSoundInstrument *asi) { + asi->mode = *data++; + asi->channel = *data++; + asi->waveSelectMod = *data++ & 3; + asi->waveSelectCar = *data++ & 3; + asi->amDepth = *data++; + ++data; + loadRegisterInstrument(data, &asi->regMod); data += 26; + loadRegisterInstrument(data, &asi->regCar); data += 26; +} + +void AdlibSoundDriverADL::setChannelFrequency(int channel, int frequency) { + assert(channel < 4); + AdlibSoundInstrument *ins = &_instrumentsTable[channel]; + if (ins->mode != 0) { + channel = ins->channel; + if (channel == 9) { + channel = 8; + } else if (channel == 10) { + channel = 7; + } + } + int freq, note, oct; + findNote(frequency, ¬e, &oct); + + note += oct * 12; + if (ins->amDepth) { + note = ins->amDepth; + } + if (note < 0) { + note = 0; + } + + freq = _freqTable[note % 12]; + OPLWriteReg(_opl, 0xA0 | channel, freq); + freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); + if (ins->mode == 0) { + freq |= 0x20; + } + OPLWriteReg(_opl, 0xB0 | channel, freq); + if (ins->mode != 0) { + _vibrato |= 1 << (10 - channel); + OPLWriteReg(_opl, 0xBD, _vibrato); + } +} + +void AdlibSoundDriverADL::playSample(const byte *data, int size, int channel, int volume) { + assert(channel < 4); + _channelsVolumeTable[channel] = 127; + setupInstrument(data, channel); + AdlibSoundInstrument *ins = &_instrumentsTable[channel]; + if (ins->mode != 0 && ins->channel == 6) { + OPLWriteReg(_opl, 0xB0 | channel, 0); + } + if (ins->mode != 0) { + _vibrato &= ~(1 << (10 - ins->channel)); + OPLWriteReg(_opl, 0xBD, _vibrato); + } + if (ins->mode != 0) { + channel = ins->channel; + if (channel == 9) { + channel = 8; + } else if (channel == 10) { + channel = 7; + } + } + uint16 note = 48; + if (ins->amDepth) { + note = ins->amDepth; + } + int freq = _freqTable[note % 12]; + OPLWriteReg(_opl, 0xA0 | channel, freq); + freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); + if (ins->mode == 0) { + freq |= 0x20; + } + OPLWriteReg(_opl, 0xB0 | channel, freq); + if (ins->mode != 0) { + _vibrato |= 1 << (10 - channel); + OPLWriteReg(_opl, 0xBD, _vibrato); + } +} + +PCSoundFxPlayer::PCSoundFxPlayer(PCSoundDriver *driver) + : _playing(false), _driver(driver) { + memset(_instrumentsData, 0, sizeof(_instrumentsData)); + _sfxData = NULL; + _fadeOutCounter = 0; + _driver->setUpdateCallback(updateCallback, this); +} + +PCSoundFxPlayer::~PCSoundFxPlayer() { + _driver->setUpdateCallback(NULL, NULL); + if (_playing) { + stop(); + } +} + +bool PCSoundFxPlayer::load(const char *song) { + debug(9, "PCSoundFxPlayer::load('%s')", song); + + /* stop (w/ fade out) the previous song */ + while (_fadeOutCounter != 0 && _fadeOutCounter < 100) { + g_system->delayMillis(50); + } + _fadeOutCounter = 0; + + if (_playing) { + stop(); + } + + _sfxData = readBundleSoundFile(song); + if (!_sfxData) { + warning("Unable to load soundfx module '%s'", song); + return 0; + } + + for (int i = 0; i < NUM_INSTRUMENTS; ++i) { + _instrumentsData[i] = NULL; + + char instrument[13]; + memcpy(instrument, _sfxData + 20 + i * 30, 12); + instrument[12] = '\0'; + + if (strlen(instrument) != 0) { + char *dot = strrchr(instrument, '.'); + if (dot) { + *dot = '\0'; + } + strcat(instrument, _driver->getInstrumentExtension()); + _instrumentsData[i] = readBundleSoundFile(instrument); + if (!_instrumentsData[i]) { + warning("Unable to load soundfx instrument '%s'", instrument); + } + } + } + return 1; +} + +void PCSoundFxPlayer::play() { + debug(9, "PCSoundFxPlayer::play()"); + if (_sfxData) { + for (int i = 0; i < NUM_CHANNELS; ++i) { + _instrumentsChannelTable[i] = -1; + } + _currentPos = 0; + _currentOrder = 0; + _numOrders = _sfxData[470]; + _eventsDelay = (252 - _sfxData[471]) * 50 / 1060; + _updateTicksCounter = 0; + _playing = true; + } +} + +void PCSoundFxPlayer::stop() { + if (_playing || _fadeOutCounter != 0) { + _fadeOutCounter = 0; + _playing = false; + for (int i = 0; i < NUM_CHANNELS; ++i) { + _driver->stopChannel(i); + } + _driver->stopAll(); + unload(); + } +} + +void PCSoundFxPlayer::fadeOut() { + if (_playing) { + _fadeOutCounter = 1; + _playing = false; + } +} + +void PCSoundFxPlayer::updateCallback(void *ref) { + ((PCSoundFxPlayer *)ref)->update(); +} + +void PCSoundFxPlayer::update() { + if (_playing || (_fadeOutCounter != 0 && _fadeOutCounter < 100)) { + ++_updateTicksCounter; + if (_updateTicksCounter > _eventsDelay) { + handleEvents(); + _updateTicksCounter = 0; + } + } +} + +void PCSoundFxPlayer::handleEvents() { + const byte *patternData = _sfxData + 600; + const byte *orderTable = _sfxData + 472; + uint16 patternNum = orderTable[_currentOrder] * 1024; + + for (int i = 0; i < 4; ++i) { + handlePattern(i, patternData + patternNum + _currentPos); + patternData += 4; + } + + if (_fadeOutCounter != 0 && _fadeOutCounter < 100) { + _fadeOutCounter += 2; + } + _currentPos += 16; + if (_currentPos >= 1024) { + _currentPos = 0; + ++_currentOrder; + if (_currentOrder == _numOrders) { + _currentOrder = 0; + } + } + debug(7, "_currentOrder=%d/%d _currentPos=%d", _currentOrder, _numOrders, _currentPos); +} + +void PCSoundFxPlayer::handlePattern(int channel, const byte *patternData) { + int instrument = patternData[2] >> 4; + if (instrument != 0) { + --instrument; + if (_instrumentsChannelTable[channel] != instrument || _fadeOutCounter != 0) { + _instrumentsChannelTable[channel] = instrument; + const int volume = _sfxData[instrument] - _fadeOutCounter; + _driver->setupChannel(channel, _instrumentsData[instrument], instrument, volume); + } + } + int16 freq = (int16)READ_BE_UINT16(patternData); + if (freq > 0) { + _driver->stopChannel(channel); + _driver->setChannelFrequency(channel, freq); + } +} + +void PCSoundFxPlayer::unload() { + for (int i = 0; i < NUM_INSTRUMENTS; ++i) { + free(_instrumentsData[i]); + _instrumentsData[i] = NULL; + } + free(_sfxData); + _sfxData = NULL; +} + + +PCSound::PCSound(Audio::Mixer *mixer, CineEngine *vm) + : Sound(mixer, vm) { + if (_vm->getGameType() == GType_FW) { + _soundDriver = new AdlibSoundDriverINS(_mixer); + } else { + _soundDriver = new AdlibSoundDriverADL(_mixer); + } + _player = new PCSoundFxPlayer(_soundDriver); +} + +PCSound::~PCSound() { + delete _player; + delete _soundDriver; +} + +void PCSound::loadMusic(const char *name) { + _player->load(name); +} + +void PCSound::playMusic() { + _player->play(); +} + +void PCSound::stopMusic() { + _player->stop(); +} + +void PCSound::fadeOutMusic() { + _player->fadeOut(); +} + +void PCSound::playSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat) { + _soundDriver->playSample(data, size, channel, volume); +} + +void PCSound::stopSound(int channel) { + _soundDriver->resetChannel(channel); +} + +PaulaSound::PaulaSound(Audio::Mixer *mixer, CineEngine *vm) + : Sound(mixer, vm) { + memset(_soundChannelsTable, 0, sizeof(_soundChannelsTable)); + _moduleStream = 0; +} + +PaulaSound::~PaulaSound() { +} + +void PaulaSound::loadMusic(const char *name) { + if (_vm->getGameType() == GType_FW) { + // look for separate files + Common::File f; + if (f.open(name)) { + _moduleStream = Audio::makeSoundFxStream(&f, 0, _mixer->getOutputRate()); + } + } else { + // look in bundle files + uint32 size; + byte *buf = readBundleSoundFile(name, &size); + if (buf) { + Common::MemoryReadStream s(buf, size); + _moduleStream = Audio::makeSoundFxStream(&s, readBundleSoundFile, _mixer->getOutputRate()); + free(buf); + } + } +} + +void PaulaSound::playMusic() { + _mixer->stopHandle(_moduleHandle); + if (_moduleStream) { + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_moduleHandle, _moduleStream); + } +} + +void PaulaSound::stopMusic() { + _mixer->stopHandle(_moduleHandle); +} + +void PaulaSound::fadeOutMusic() { + // TODO + stopMusic(); +} + +void PaulaSound::playSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat) { + SoundChannel *ch = &_soundChannelsTable[channel]; + ch->frequency = frequency; + ch->data = data; + ch->size = size; + ch->volumeStep = volumeStep; + ch->stepCount = stepCount; + ch->step = stepCount; + ch->repeat = repeat != 0; + ch->volume = volume; +} + +void PaulaSound::stopSound(int channel) { + _mixer->stopHandle(_channelsTable[channel]); +} + +void PaulaSound::update() { + // process volume slides and start sound playback + for (int i = 0; i < NUM_CHANNELS; ++i) { + SoundChannel *ch = &_soundChannelsTable[i]; + if (ch->data) { + if (ch->step) { + --ch->step; + continue; + } + ch->step = ch->stepCount; + ch->volume = CLIP(ch->volume + ch->volumeStep, 0, 63); + playSoundChannel(i, ch->frequency, ch->data, ch->size, ch->volume); + if (!ch->repeat) { + ch->data = 0; + } + } + } +} + +void PaulaSound::playSoundChannel(int channel, int frequency, const uint8 *data, int size, int volume) { + stopSound(channel); + assert(frequency > 0); + frequency = PAULA_FREQ / frequency; + size = MIN<int>(size - SPL_HDR_SIZE, READ_BE_UINT16(data + 4)); + data += SPL_HDR_SIZE; + if (size > 0) { + _mixer->playRaw(Audio::Mixer::kSFXSoundType, &_channelsTable[channel], const_cast<byte *>(data), size, frequency, 0); + _mixer->setChannelVolume(_channelsTable[channel], volume * Audio::Mixer::kMaxChannelVolume / 63); + } +} + +} // End of namespace Cine diff --git a/engines/cine/sound.h b/engines/cine/sound.h new file mode 100644 index 0000000000..584cdab62f --- /dev/null +++ b/engines/cine/sound.h @@ -0,0 +1,129 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CINE_SOUND_H_ +#define CINE_SOUND_H_ + +#include "common/util.h" +#include "sound/mixer.h" + +namespace Audio { + class AudioStream; +} + +namespace Cine { + +class CineEngine; + +class Sound { +public: + + Sound(Audio::Mixer *mixer, CineEngine *vm) : _mixer(mixer), _vm(vm) {} + virtual ~Sound() {} + + virtual void loadMusic(const char *name) = 0; + virtual void playMusic() = 0; + virtual void stopMusic() = 0; + virtual void fadeOutMusic() = 0; + + virtual void playSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat) = 0; + virtual void stopSound(int channel) = 0; + virtual void update() {} + +protected: + + Audio::Mixer *_mixer; + CineEngine *_vm; +}; + +class PCSoundDriver; +class PCSoundFxPlayer; + +class PCSound : public Sound { +public: + + PCSound(Audio::Mixer *mixer, CineEngine *vm); + virtual ~PCSound(); + + virtual void loadMusic(const char *name); + virtual void playMusic(); + virtual void stopMusic(); + virtual void fadeOutMusic(); + + virtual void playSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat); + virtual void stopSound(int channel); + +protected: + + PCSoundDriver *_soundDriver; + PCSoundFxPlayer *_player; +}; + +class PaulaSound : public Sound { +public: + + PaulaSound(Audio::Mixer *mixer, CineEngine *vm); + virtual ~PaulaSound(); + + virtual void loadMusic(const char *name); + virtual void playMusic(); + virtual void stopMusic(); + virtual void fadeOutMusic(); + + virtual void playSound(int channel, int frequency, const uint8 *data, int size, int volumeStep, int stepCount, int volume, int repeat); + virtual void stopSound(int channel); + virtual void update(); + + enum { + PAULA_FREQ = 7093789, + NUM_CHANNELS = 4, + SPL_HDR_SIZE = 22 + }; + + struct SoundChannel { + int frequency; + const uint8 *data; + int size; + int volumeStep; + int stepCount; + int step; + bool repeat; + int volume; + }; + +protected: + + void playSoundChannel(int channel, int frequency, const uint8 *data, int size, int volume); + + Audio::SoundHandle _channelsTable[NUM_CHANNELS]; + SoundChannel _soundChannelsTable[NUM_CHANNELS]; + Audio::SoundHandle _moduleHandle; + Audio::AudioStream *_moduleStream; +}; + +extern Sound *g_sound; + +} // End of namespace Cine + +#endif /* CINE_SOUND_H_ */ diff --git a/engines/cine/sound_driver.cpp b/engines/cine/sound_driver.cpp deleted file mode 100644 index 0bc7c8c33f..0000000000 --- a/engines/cine/sound_driver.cpp +++ /dev/null @@ -1,433 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * cinE Engine is (C) 2004-2005 by CinE Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/endian.h" - -#include "cine/cine.h" -#include "cine/sound_driver.h" - -#include "sound/mixer.h" - -namespace Cine { - -void SoundDriver::setUpdateCallback(UpdateCallback upCb, void *ref) { - _upCb = upCb; - _upRef = ref; -} - -void SoundDriver::findNote(int freq, int *note, int *oct) const { - *note = _noteTableCount - 1; - for (int i = 0; i < _noteTableCount; ++i) { - if (_noteTable[i] <= freq) { - *note = i; - break; - } - } - *oct = *note / 12; -} - -void SoundDriver::resetChannel(int channel) { - stopChannel(channel); - stopSound(); -} - -AdlibSoundDriver::AdlibSoundDriver(Audio::Mixer *mixer) - : _mixer(mixer) { - _sampleRate = _mixer->getOutputRate(); - _opl = makeAdlibOPL(_sampleRate); - memset(_channelsVolumeTable, 0, sizeof(_channelsVolumeTable)); - memset(_instrumentsTable, 0, sizeof(_instrumentsTable)); - initCard(); - _mixer->playInputStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, false, true); -} - -AdlibSoundDriver::~AdlibSoundDriver() { - _mixer->stopHandle(_soundHandle); -} - -void AdlibSoundDriver::setupChannel(int channel, const byte *data, int instrument, int volume) { - assert(channel < 4); - if (data) { - if (volume > 80) { - volume = 80; - } else if (volume < 0) { - volume = 0; - } - volume += volume / 4; - if (volume > 127) { - volume = 127; - } - _channelsVolumeTable[channel] = volume; - setupInstrument(data, channel); - } -} - -void AdlibSoundDriver::stopChannel(int channel) { - assert(channel < 4); - AdlibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins) { - if (ins->mode != 0 && ins->channel == 6) { - channel = 6; - } - if (ins->mode == 0 || ins->channel == 6) { - OPLWriteReg(_opl, 0xB0 | channel, 0); - } - if (ins->mode != 0) { - _vibrato &= (1 << (10 - ins->channel)) ^ 0xFF; - OPLWriteReg(_opl, 0xBD, _vibrato); - } - } -} - -void AdlibSoundDriver::stopSound() { - int i; - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 63); - } - for (i = 0; i < 9; ++i) { - OPLWriteReg(_opl, 0xB0 | i, 0); - } - OPLWriteReg(_opl, 0xBD, 0); -} - -int AdlibSoundDriver::readBuffer(int16 *buffer, const int numSamples) { - update(buffer, numSamples); - return numSamples; -} - -void AdlibSoundDriver::initCard() { - _vibrato = 0x20; - OPLWriteReg(_opl, 0xBD, _vibrato); - OPLWriteReg(_opl, 0x08, 0x40); - - int i; - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0x40 | _operatorsTable[i], 0); - } - for (i = 0; i < 9; ++i) { - OPLWriteReg(_opl, 0xB0 | i, 0); - } - for (i = 0; i < 9; ++i) { - OPLWriteReg(_opl, 0xC0 | i, 0); - } - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0x60 | _operatorsTable[i], 0); - } - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0x80 | _operatorsTable[i], 0); - } - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0x20 | _operatorsTable[i], 0); - } - for (i = 0; i < 18; ++i) { - OPLWriteReg(_opl, 0xE0 | _operatorsTable[i], 0); - } - - OPLWriteReg(_opl, 1, 0x20); - OPLWriteReg(_opl, 1, 0); -} - -void AdlibSoundDriver::update(int16 *buf, int len) { - static int samplesLeft = 0; - while (len != 0) { - int count = samplesLeft; - if (count > len) { - count = len; - } - samplesLeft -= count; - len -= count; - YM3812UpdateOne(_opl, buf, count); - if (samplesLeft == 0) { - if (_upCb) { - (*_upCb)(_upRef); - } - samplesLeft = _sampleRate / 50; - } - buf += count; - } -} - -void AdlibSoundDriver::setupInstrument(const byte *data, int channel) { - assert(channel < 4); - AdlibSoundInstrument *ins = &_instrumentsTable[channel]; - loadInstrument(data, ins); - - int mod, car, tmp; - const AdlibRegisterSoundInstrument *reg; - - if (ins->mode != 0) { - mod = _operatorsTable[_voiceOperatorsTable[2 * ins->channel + 0]]; - car = _operatorsTable[_voiceOperatorsTable[2 * ins->channel + 1]]; - } else { - mod = _operatorsTable[_voiceOperatorsTable[2 * channel + 0]]; - car = _operatorsTable[_voiceOperatorsTable[2 * channel + 1]]; - } - - if (ins->mode == 0 || ins->channel == 6) { - reg = &ins->regMod; - OPLWriteReg(_opl, 0x20 | mod, reg->vibrato); - if (reg->freqMod) { - tmp = reg->outputLevel & 0x3F; - } else { - tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel]; - tmp = 63 - (2 * tmp + 127) / (2 * 127); - } - OPLWriteReg(_opl, 0x40 | mod, tmp | (reg->keyScaling << 6)); - OPLWriteReg(_opl, 0x60 | mod, reg->attackDecay); - OPLWriteReg(_opl, 0x80 | mod, reg->sustainRelease); - if (ins->mode != 0) { - OPLWriteReg(_opl, 0xC0 | ins->channel, reg->feedbackStrength); - } else { - OPLWriteReg(_opl, 0xC0 | channel, reg->feedbackStrength); - } - OPLWriteReg(_opl, 0xE0 | mod, ins->waveSelectMod); - } - - reg = &ins->regCar; - OPLWriteReg(_opl, 0x20 | car, reg->vibrato); - tmp = (63 - (reg->outputLevel & 0x3F)) * _channelsVolumeTable[channel]; - tmp = 63 - (2 * tmp + 127) / (2 * 127); - OPLWriteReg(_opl, 0x40 | car, tmp | (reg->keyScaling << 6)); - OPLWriteReg(_opl, 0x60 | car, reg->attackDecay); - OPLWriteReg(_opl, 0x80 | car, reg->sustainRelease); - OPLWriteReg(_opl, 0xE0 | car, ins->waveSelectCar); -} - -void AdlibSoundDriver::loadRegisterInstrument(const byte *data, AdlibRegisterSoundInstrument *reg) { - reg->vibrato = 0; - if (READ_LE_UINT16(data + 18)) { // amplitude vibrato - reg->vibrato |= 0x80; - } - if (READ_LE_UINT16(data + 20)) { // frequency vibrato - reg->vibrato |= 0x40; - } - if (READ_LE_UINT16(data + 10)) { // sustaining sound - reg->vibrato |= 0x20; - } - if (READ_LE_UINT16(data + 22)) { // envelope scaling - reg->vibrato |= 0x10; - } - reg->vibrato |= READ_LE_UINT16(data + 2) & 0xF; // frequency multiplier - - reg->attackDecay = READ_LE_UINT16(data + 6) << 4; // attack rate - reg->attackDecay |= READ_LE_UINT16(data + 12) & 0xF; // decay rate - - reg->sustainRelease = READ_LE_UINT16(data + 8) << 4; // sustain level - reg->sustainRelease |= READ_LE_UINT16(data + 14) & 0xF; // release rate - - reg->feedbackStrength = READ_LE_UINT16(data + 4) << 1; // feedback - if (READ_LE_UINT16(data + 24) == 0) { // frequency modulation - reg->feedbackStrength |= 1; - } - - reg->keyScaling = READ_LE_UINT16(data); - reg->outputLevel = READ_LE_UINT16(data + 16); - reg->freqMod = READ_LE_UINT16(data + 24); -} - -void AdlibSoundDriverINS::loadInstrument(const byte *data, AdlibSoundInstrument *asi) { - asi->mode = *data++; - asi->channel = *data++; - loadRegisterInstrument(data, &asi->regMod); data += 26; - loadRegisterInstrument(data, &asi->regCar); data += 26; - asi->waveSelectMod = data[0] & 3; data += 2; - asi->waveSelectCar = data[0] & 3; data += 2; - asi->amDepth = data[0]; data += 2; -} - -void AdlibSoundDriverINS::setChannelFrequency(int channel, int frequency) { - assert(channel < 4); - AdlibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins) { - if (ins->mode != 0 && ins->channel == 6) { - channel = 6; - } - if (ins->mode == 0 || ins->channel == 6) { - int freq, note, oct; - findNote(frequency, ¬e, &oct); - if (channel == 6) { - note %= 12; - } - freq = _freqTable[note % 12]; - OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); - if (ins->mode == 0) { - freq |= 0x20; - } - OPLWriteReg(_opl, 0xB0 | channel, freq); - } - if (ins->mode != 0) { - _vibrato |= 1 << (10 - ins->channel); - OPLWriteReg(_opl, 0xBD, _vibrato); - } - } -} - -void AdlibSoundDriverINS::playSound(const byte *data, int channel, int volume) { - assert(channel < 4); - _channelsVolumeTable[channel] = 127; - resetChannel(channel); - setupInstrument(data + 257, channel); - AdlibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins->mode != 0 && ins->channel == 6) { - channel = 6; - } - if (ins->mode == 0 || channel == 6) { - int freq = _freqTable[0]; - OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = 4 | ((freq & 0x300) >> 8); - if (ins->mode == 0) { - freq |= 0x20; - } - OPLWriteReg(_opl, 0xB0 | channel, freq); - } - if (ins->mode != 0) { - _vibrato = 1 << (10 - ins->channel); - OPLWriteReg(_opl, 0xBD, _vibrato); - } -} - -void AdlibSoundDriverADL::loadInstrument(const byte *data, AdlibSoundInstrument *asi) { - asi->mode = *data++; - asi->channel = *data++; - asi->waveSelectMod = *data++ & 3; - asi->waveSelectCar = *data++ & 3; - asi->amDepth = *data++; - ++data; - loadRegisterInstrument(data, &asi->regMod); data += 26; - loadRegisterInstrument(data, &asi->regCar); data += 26; -} - -void AdlibSoundDriverADL::setChannelFrequency(int channel, int frequency) { - assert(channel < 4); - AdlibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins) { - if (ins->mode != 0) { - channel = ins->channel; - if (channel == 9) { - channel = 8; - } else if (channel == 10) { - channel = 7; - } - } - int freq, note, oct; - findNote(frequency, ¬e, &oct); - - note += oct * 12; - if (ins->amDepth) { - note = ins->amDepth; - } - if (note < 0) { - note = 0; - } - - freq = _freqTable[note % 12]; - OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); - if (ins->mode == 0) { - freq |= 0x20; - } - OPLWriteReg(_opl, 0xB0 | channel, freq); - if (ins->mode != 0) { - _vibrato = 1 << (10 - channel); - OPLWriteReg(_opl, 0xBD, _vibrato); - } - } -} - -void AdlibSoundDriverADL::playSound(const byte *data, int channel, int volume) { - assert(channel < 4); - _channelsVolumeTable[channel] = 127; - setupInstrument(data, channel); - AdlibSoundInstrument *ins = &_instrumentsTable[channel]; - if (ins->mode != 0 && ins->channel == 6) { - OPLWriteReg(_opl, 0xB0 | channel, 0); - } - if (ins->mode != 0) { - _vibrato = (1 << (10 - ins->channel)) ^ 0xFF; - OPLWriteReg(_opl, 0xBD, _vibrato); - } - if (ins->mode != 0) { - channel = ins->channel; - if (channel == 9) { - channel = 8; - } else if (channel == 10) { - channel = 7; - } - } - uint16 note = 48; - if (ins->amDepth) { - note = ins->amDepth; - } - int freq = _freqTable[note % 12]; - OPLWriteReg(_opl, 0xA0 | channel, freq); - freq = ((note / 12) << 2) | ((freq & 0x300) >> 8); - if (ins->mode == 0) { - freq |= 0x20; - } - OPLWriteReg(_opl, 0xB0 | channel, freq); - if (ins->mode != 0) { - _vibrato = 1 << (10 - channel); - OPLWriteReg(_opl, 0xBD, _vibrato); - } -} - -const int SoundDriver::_noteTable[] = { - 0xEEE, 0xE17, 0xD4D, 0xC8C, 0xBD9, 0xB2F, 0xA8E, 0x9F7, - 0x967, 0x8E0, 0x861, 0x7E8, 0x777, 0x70B, 0x6A6, 0x647, - 0x5EC, 0x597, 0x547, 0x4FB, 0x4B3, 0x470, 0x430, 0x3F4, - 0x3BB, 0x385, 0x353, 0x323, 0x2F6, 0x2CB, 0x2A3, 0x27D, - 0x259, 0x238, 0x218, 0x1FA, 0x1DD, 0x1C2, 0x1A9, 0x191, - 0x17B, 0x165, 0x151, 0x13E, 0x12C, 0x11C, 0x10C, 0x0FD, - 0x0EE, 0x0E1, 0x0D4, 0x0C8, 0x0BD, 0x0B2, 0x0A8, 0x09F, - 0x096, 0x08E, 0x086, 0x07E, 0x077, 0x070, 0x06A, 0x064, - 0x05E, 0x059, 0x054, 0x04F, 0x04B, 0x047, 0x043, 0x03F, - 0x03B, 0x038, 0x035, 0x032, 0x02F, 0x02C, 0x02A, 0x027, - 0x025, 0x023, 0x021, 0x01F, 0x01D, 0x01C, 0x01A, 0x019, - 0x017, 0x016, 0x015, 0x013, 0x012, 0x011, 0x010, 0x00F -}; - -const int SoundDriver::_noteTableCount = ARRAYSIZE(_noteTable); - -const int AdlibSoundDriver::_freqTable[] = { - 0x157, 0x16C, 0x181, 0x198, 0x1B1, 0x1CB, - 0x1E6, 0x203, 0x222, 0x243, 0x266, 0x28A -}; - -const int AdlibSoundDriver::_freqTableCount = ARRAYSIZE(_freqTable); - -const int AdlibSoundDriver::_operatorsTable[] = { - 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21 -}; - -const int AdlibSoundDriver::_operatorsTableCount = ARRAYSIZE(_operatorsTable); - -const int AdlibSoundDriver::_voiceOperatorsTable[] = { - 0, 3, 1, 4, 2, 5, 6, 9, 7, 10, 8, 11, 12, 15, 16, 16, 14, 14, 17, 17, 13, 13 -}; - -const int AdlibSoundDriver::_voiceOperatorsTableCount = ARRAYSIZE(_voiceOperatorsTable); - -} // End of namespace Cine diff --git a/engines/cine/sound_driver.h b/engines/cine/sound_driver.h deleted file mode 100644 index c6fc571f89..0000000000 --- a/engines/cine/sound_driver.h +++ /dev/null @@ -1,143 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * cinE Engine is (C) 2004-2005 by CinE Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef CINE_SOUNDDRIVER_H -#define CINE_SOUNDDRIVER_H - -#include "sound/audiostream.h" -#include "sound/fmopl.h" -#include "sound/mixer.h" - -namespace Cine { - -class SoundDriver { -public: - typedef void (*UpdateCallback)(void *); - - virtual ~SoundDriver() {} - - virtual void setupChannel(int channel, const byte *data, int instrument, int volume) = 0; - virtual void setChannelFrequency(int channel, int frequency) = 0; - virtual void stopChannel(int channel) = 0; - virtual void playSound(const byte *data, int channel, int volume) = 0; - virtual void stopSound() = 0; - virtual const char *getInstrumentExtension() const = 0; - - void setUpdateCallback(UpdateCallback upCb, void *ref); - void resetChannel(int channel); - void findNote(int freq, int *note, int *oct) const; - -protected: - UpdateCallback _upCb; - void *_upRef; - - static const int _noteTable[]; - static const int _noteTableCount; -}; - -struct AdlibRegisterSoundInstrument { - uint16 vibrato; - uint16 attackDecay; - uint16 sustainRelease; - uint16 feedbackStrength; - uint16 keyScaling; - uint16 outputLevel; - uint16 freqMod; -}; - -struct AdlibSoundInstrument { - byte mode; - byte channel; - AdlibRegisterSoundInstrument regMod; - AdlibRegisterSoundInstrument regCar; - byte waveSelectMod; - byte waveSelectCar; - byte amDepth; -}; - -class AdlibSoundDriver : public SoundDriver, Audio::AudioStream { -public: - AdlibSoundDriver(Audio::Mixer *mixer); - virtual ~AdlibSoundDriver(); - - // SoundDriver interface - virtual void setupChannel(int channel, const byte *data, int instrument, int volume); - virtual void stopChannel(int channel); - virtual void stopSound(); - - // AudioStream interface - virtual int readBuffer(int16 *buffer, const int numSamples); - virtual bool isStereo() const { return false; } - virtual bool endOfData() const { return false; } - virtual int getRate() const { return _sampleRate; } - - void initCard(); - void update(int16 *buf, int len); - void setupInstrument(const byte *data, int channel); - void loadRegisterInstrument(const byte *data, AdlibRegisterSoundInstrument *reg); - virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi) = 0; - -protected: - FM_OPL *_opl; - int _sampleRate; - Audio::Mixer *_mixer; - Audio::SoundHandle _soundHandle; - - byte _vibrato; - int _channelsVolumeTable[4]; - AdlibSoundInstrument _instrumentsTable[4]; - - static const int _freqTable[]; - static const int _freqTableCount; - static const int _operatorsTable[]; - static const int _operatorsTableCount; - static const int _voiceOperatorsTable[]; - static const int _voiceOperatorsTableCount; -}; - -// Future Wars adlib driver -class AdlibSoundDriverINS : public AdlibSoundDriver { -public: - AdlibSoundDriverINS(Audio::Mixer *mixer) : AdlibSoundDriver(mixer) {} - virtual const char *getInstrumentExtension() const { return ".INS"; } - virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi); - virtual void setChannelFrequency(int channel, int frequency); - virtual void playSound(const byte *data, int channel, int volume); -}; - -// Operation Stealth adlib driver -class AdlibSoundDriverADL : public AdlibSoundDriver { -public: - AdlibSoundDriverADL(Audio::Mixer *mixer) : AdlibSoundDriver(mixer) {} - virtual const char *getInstrumentExtension() const { return ".ADL"; } - virtual void loadInstrument(const byte *data, AdlibSoundInstrument *asi); - virtual void setChannelFrequency(int channel, int frequency); - virtual void playSound(const byte *data, int channel, int volume); -}; - -extern SoundDriver *g_soundDriver; // TEMP - -} // End of namespace Cine - -#endif /* CINE_SOUNDDRIVER_H_ */ diff --git a/engines/cine/unpack.cpp b/engines/cine/unpack.cpp index 597d412123..f15c46a84e 100644 --- a/engines/cine/unpack.cpp +++ b/engines/cine/unpack.cpp @@ -29,6 +29,14 @@ namespace Cine { +struct UnpackCtx { + int size, datasize; + uint32 crc; + uint32 chk; + byte *dst; + const byte *src; +}; + static int rcr(UnpackCtx *uc, int CF) { int rCF = (uc->chk & 1); uc->chk >>= 1; diff --git a/engines/cine/unpack.h b/engines/cine/unpack.h index eadf19d947..5a57f836a0 100644 --- a/engines/cine/unpack.h +++ b/engines/cine/unpack.h @@ -30,14 +30,6 @@ namespace Cine { -struct UnpackCtx { - int size, datasize; - uint32 crc; - uint32 chk; - byte *dst; - const byte *src; -}; - bool delphineUnpack(byte *dst, const byte *src, int len); } // End of namespace Cine diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index 92a38f969b..f6bf1197ea 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -29,7 +29,7 @@ #include "cine/cine.h" #include "cine/main_loop.h" #include "cine/object.h" -#include "cine/sfx_player.h" +#include "cine/sound.h" #include "cine/bg_list.h" #include "cine/various.h" @@ -56,10 +56,6 @@ int16 buildObjectListCommand(void); void drawString(const char *string, byte param) { } -void blitRawScreen(byte *frontBuffer) { - gfxFlipRawPage(frontBuffer); -} - Common::File *partFileHandleP = NULL; void waitPlayerInput(void) { @@ -74,17 +70,6 @@ void setTextWindow(uint16 param1, uint16 param2, uint16 param3, uint16 param4) { uint16 errorVar; byte menuVar; -void gfxFuncGen1(byte *param1, byte *param2, byte *param3, byte *param4, int16 param5) { -} - -byte *page0c; - -void ptrGfxFunc13(void) { -} - -void gfxFuncGen2(void) { -} - uint16 allowPlayerInput; uint16 checkForPendingDataLoadSwitch; @@ -453,7 +438,7 @@ bool CineEngine::makeLoad(char *saveName) { return false; } - g_sfxPlayer->stop(); + g_sound->stopMusic(); freeAnimDataTable(); unloadAllMasks(); // if (g_cine->getGameType() == Cine::GType_OS) { @@ -2188,13 +2173,18 @@ uint16 executePlayerInput(void) { void drawSprite(overlayHeadElement *currentOverlay, byte *spritePtr, byte *maskPtr, uint16 width, uint16 height, byte *page, int16 x, int16 y) { -#if 0 byte *ptr = NULL; + byte *msk = NULL; byte i = 0; uint16 si = 0; overlayHeadElement *pCurrentOverlay = currentOverlay; - while (pCurrentOverlay) { // unfinished, probably for mask handling.. + if (g_cine->getGameType() == Cine::GType_OS) { + drawSpriteRaw2(spritePtr, objectTable[currentOverlay->objIdx].part, width, height, page, x, y); + return; + } + + while (pCurrentOverlay) { if (pCurrentOverlay->type == 5) { int16 maskX; int16 maskY; @@ -2203,7 +2193,8 @@ void drawSprite(overlayHeadElement *currentOverlay, byte *spritePtr, uint16 maskSpriteIdx; if (!si) { - ptr = (byte *)malloc(width * height); + ptr = (byte *)malloc(width * 8 * height); + msk = (byte *)malloc(width * 8 * height); si = 1; } @@ -2214,25 +2205,22 @@ void drawSprite(overlayHeadElement *currentOverlay, byte *spritePtr, maskWidth = animDataTable[maskSpriteIdx].width / 2; maskHeight = animDataTable[maskSpriteIdx].height; - - gfxSpriteFunc2(spritePtr, width, height, animDataTable[maskSpriteIdx].ptr1, maskWidth, maskHeight, ptr, maskX - x,maskY - y, i++); + gfxSpriteFunc2(spritePtr, maskPtr, width, height, animDataTable[maskSpriteIdx].ptr1, maskWidth, maskHeight, ptr, msk, x, y, maskX, maskY, i++); +#ifdef DEBUG_SPRITE_MASK + gfxFillSprite(animDataTable[maskSpriteIdx].ptr1, maskWidth, maskHeight, page, maskX, maskY, 1); +#endif } pCurrentOverlay = pCurrentOverlay->next; } if (si) { - gfxSpriteFunc1(ptr, width, height, page, x, y); + gfxSpriteFunc1(ptr, msk, width, height, page, x, y); free(ptr); - } else -#endif - - if (g_cine->getGameType() == Cine::GType_OS) { - drawSpriteRaw2(spritePtr, objectTable[currentOverlay->objIdx].part, width, height, page, x, y); + free(msk); } else { - drawSpriteRaw(spritePtr, maskPtr, width, height, page, x, y); + gfxSpriteFunc1(spritePtr, maskPtr, width, height, page, x, y); } - } int16 additionalBgVScroll = 0; @@ -2650,10 +2638,6 @@ void drawOverlays(void) { } } -void flip(void) { - blitRawScreen(page1Raw); -} - uint16 processKeyboard(uint16 param) { return 0; } diff --git a/engines/cine/various.h b/engines/cine/various.h index c50941d8e5..bb95657f1c 100644 --- a/engines/cine/various.h +++ b/engines/cine/various.h @@ -93,14 +93,6 @@ void setTextWindow(uint16 param1, uint16 param2, uint16 param3, uint16 param4); extern uint16 errorVar; extern byte menuVar; -void gfxFuncGen1(byte *param1, byte *param2, byte *param3, byte *param4, int16 param5); - -extern byte *page0; -extern byte *page0c; - -void ptrGfxFunc13(void); -void gfxFuncGen2(void); - extern uint16 allowPlayerInput; extern uint16 checkForPendingDataLoadSwitch; @@ -137,7 +129,6 @@ void mainLoopSub3(void); uint16 executePlayerInput(void); void drawOverlays(void); -void flip(void); extern uint16 mouseUpdateStatus; extern uint16 dummyU16; @@ -170,8 +161,6 @@ extern uint16 zoneData[NUM_MAX_ZONE]; void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5); -void blitScreen(byte *frontBuffer, byte *backbuffer); - extern int16 additionalBgVScroll; void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8); diff --git a/engines/cruise/actor.cpp b/engines/cruise/actor.cpp new file mode 100644 index 0000000000..cf7ef4b176 --- /dev/null +++ b/engines/cruise/actor.cpp @@ -0,0 +1,1103 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise.h" + +namespace Cruise { + +int16 mainProc13(int overlayIdx, int param1, actorStruct *pStartEntry, + int param2) { + actorStruct *pCurrentEntry = pStartEntry->next; + + while (pCurrentEntry) { + if ((pCurrentEntry->overlayNumber == overlayIdx + || overlayIdx == -1) && (pCurrentEntry->idx == param1 + || param1 == -1) && (pCurrentEntry->type == param2 + || param2 == -1) && (pCurrentEntry->pathId != -2)) { + return 0; + } + + pCurrentEntry = pCurrentEntry->next; + } + + return 1; +} + +actorStruct *findActor(int overlayIdx, int param1, actorStruct *pStartEntry, + int param2) { + actorStruct *pCurrentEntry = pStartEntry->next; + + while (pCurrentEntry) { + if ((pCurrentEntry->overlayNumber == overlayIdx + || overlayIdx == -1) && (pCurrentEntry->idx == param1 + || param1 == -1) && (pCurrentEntry->type == param2 + || param2 == -1)) { + return pCurrentEntry; + } + + pCurrentEntry = pCurrentEntry->next; + } + + return NULL; +} + +int nclick_noeud; +int flag_aff_chemin; + +void getPixel(int x, int y) { + int x_min, x_max, y_min, y_max; + + ctpVar19Struct *polygone; + ctpVar19SubStruct *tableau; + + polygone = ctpVar19; /* adr structure polygone */ + + while (polygone->field_0 != (ctpVar19Struct *) - 1) { + tableau = &polygone->subStruct; + + x_min = tableau->minX; + x_max = tableau->maxX; + y_min = tableau->minY; + y_max = tableau->maxY; + + computedVar14 = tableau->boxIdx; /* numero polygone */ + + if (walkboxChange[computedVar14] == 0 && ((x >= x_min + && x <= x_max) && (y >= y_min && y <= y_max))) { + // click was in given box + /* u = y-y_min; + * + * //tableau+=u; + * tableau = &polygone[u].subStruct; + * + * x_min = tableau->minX; + * x_max = tableau->maxX; + * + * if ( (x>=x_min && x<=x_max) ) */ + { + flag_obstacle = walkboxType[computedVar14]; /* sa couleur */ + + return; + } + } + polygone = polygone->field_0; + } + + flag_obstacle = 0; +} + +int x_mouse; +int y_mouse; + +int point_select; + +int table_ptselect[2][2]; + +int X; +int Y; + +int modelVar9; +int modelVar10; + +void polydroite(int x1, int y1, int x2, int y2) { + int dx; + int dy; + + int mD0; + int mD1; + + int mA0; + int mA1; + + int bp; + int cx; + int si; + + int ax; + int bx; + + modelVar9 = x1; + modelVar10 = y1; + + dx = x2 - x1; + dy = y2 - y1; + + mD0 = mD1 = 1; + + if (dx < 0) { + dx = -dx; + mD0 = -1; + } + + if (dy < 0) { + dy = -dy; + mD1 = -1; + } + + if (dx < dy) { + mA0 = 0; + bp = dx; + cx = dy; + + mA1 = mD1; + } else { + mA1 = 0; + bp = dy; + cx = dx; + + mA0 = mD0; + } + + bp = bp * 2; + dx = bp - cx; + si = dx - cx; + + ax = modelVar9; + bx = modelVar10; + + getPixel(modelVar9, modelVar10); + + X = modelVar9; + Y = modelVar10; + + if (flag_obstacle == 0) { + flag_obstacle = 1; + return; + } + + while (--cx) { + if (dx > 0) { + ax += mD0; + bx += mD1; + dx += si; + } else { + ax += mA0; + bx += mA1; + dx += bp; + } + + getPixel(ax, bx); + + X = ax; + Y = bx; + + if (flag_obstacle == 0) { + flag_obstacle = 1; + return; + } + } + + flag_obstacle = 0; +} + +void poly2(int x1, int y1, int x2, int y2) { + int dx; + int dy; + + int mD0; + int mD1; + + int mA0; + int mA1; + + int bp; + int cx; + int si; + + int ax; + int bx; + + modelVar9 = x1; + modelVar10 = y1; + + dx = x2 - x1; + dy = y2 - y1; + + mD0 = mD1 = 1; + + if (dx < 0) { + dx = -dx; + mD0 = -1; + } + + if (dy < 0) { + dy = -dy; + mD1 = -1; + } + + if (dx < dy) { + mA0 = 0; + bp = dx; + cx = dy; + + mA1 = mD1; + } else { + mA1 = 0; + bp = dy; + cx = dx; + + mA0 = mD0; + } + + bp = bp * 2; + dx = bp - cx; + si = dx - cx; + + ax = modelVar9; + bx = modelVar10; + + getPixel(modelVar9, modelVar10); + + X = modelVar9; + Y = modelVar10; + + if (flag_obstacle != 0) { + flag_obstacle = 1; + return; + } + + while (--cx) { + if (dx > 0) { + ax += mD0; + bx += mD1; + dx += si; + } else { + ax += mA0; + bx += mA1; + dx += bp; + } + + getPixel(ax, bx); + + X = ax; + Y = bx; + + if (flag_obstacle != 0) { + flag_obstacle = 1; + return; + } + } + + flag_obstacle = 0; +} + +int point_proche(int16 table[][2]) { + int x1, y1, i, x, y, p; + int d1 = 1000; + + ctpVar19 = ctpVar11; + + if (nclick_noeud == 1) { + x = x_mouse; + y = y_mouse; + x1 = table_ptselect[0][0]; + y1 = table_ptselect[0][1]; + + ctpVar19 = ctpVar15; + + getPixel(x, y); + + if (!flag_obstacle) { + ctpVar19 = ctpVar11; + + getPixel(x, y); + + if (flag_obstacle) { + polydroite(x1, y1, x, y); + } + ctpVar19 = ctpVar15; + } + if (!flag_obstacle) { /* dans flag_obstacle --> couleur du point */ + x1 = table_ptselect[0][0]; + y1 = table_ptselect[0][1]; + + poly2(x, y, x1, y1); + + x_mouse = X; + y_mouse = Y; + } + } + ctpVar19 = ctpVar11; + + p = -1; + for (i = 0; i < ctp_routeCoordCount; i++) { + x = table[i][0]; + y = table[i][1]; + + ctpProc2(x_mouse, y_mouse, x, y); + if (ctpVar14 < d1) { + polydroite(x_mouse, y_mouse, x, y); + + if (!flag_obstacle && ctp_routes[i][0] > 0) { + d1 = ctpVar14; + p = i; + } + } + } + + return (p); +} + +#define NBNOEUD 20 + +int16 select_noeud[3]; +char solution[20 + 1]; + +int prem; +int prem2; +int dist_chemin; +int idsol; +int solmax; + +char fl[NBNOEUD + 1]; +char sol[NBNOEUD + 1]; +char Fsol[NBNOEUD + 1]; + +int D; + +void explore(int depart, int arrivee) { + int id1, id2, i; + + id1 = depart; + + fl[id1]++; + sol[idsol++] = (char)id1; + + if (idsol > solmax) { + fl[id1] = -1; + idsol--; + + return; + } + + while ((i = fl[id1]) < 20) { + id2 = ctp_routes[id1][i + 1]; + + if (id2 == arrivee) { + if (idsol < solmax) { + sol[idsol] = (char)arrivee; + D = 0; + for (i = 0; i < idsol; i++) { + D = D + + ctp_routeCoords[(int)sol[i]][(int) + sol[i + 1]]; + Fsol[i] = sol[i]; + } + prem2 = 0; + if (!prem) { + dist_chemin = D; + prem = 1; + for (i = 0; i <= idsol; i++) { + solution[i] = sol[i]; + } + solution[i++] = -1; + solution[i] = -1; + } else if (D < dist_chemin) { + dist_chemin = D; + for (i = 0; i <= idsol; i++) { + solution[i] = sol[i]; + } + solution[i++] = -1; + solution[i] = -1; + } + } + fl[id1] = -1; + idsol--; + + return; + } else if ((id2 != -1) && ((int)fl[id2] == -1)) + explore(id2, arrivee); + else if (id2 == -1) { + fl[id1] = -1; + idsol--; + + return; + } + fl[id1]++; + } + + fl[id1] = -1; + idsol--; +} + +void chemin0(int depart, int arrivee) { + int i; + //int y=30; + + prem = 0; + prem2 = 0; + dist_chemin = 0; + idsol = 0; + solmax = 999; + + for (i = 0; i < 20 + 1; i++) + fl[i] = -1; + + X = 0, Y = 30; + + explore(depart, arrivee); +} + +void valide_noeud(int16 table[], int16 p, int *nclick, int16 solution0[20 + 3][2]) { + int a, b, d, i, p1, x1, x2, y1, y2; + //int y=30; + + table[*nclick] = p; + table[(*nclick) + 1] = -1; + table_ptselect[*nclick][0] = x_mouse; + table_ptselect[*nclick][1] = y_mouse; + (*nclick)++; + ctpVar19 = ctpVar11; + + if (*nclick == 2) // second point + { + x1 = table_ptselect[0][0]; + y1 = table_ptselect[0][1]; + x2 = table_ptselect[1][0]; + y2 = table_ptselect[1][1]; + if ((x1 == x2) && (y1 == y2)) { + return; + } + flag_aff_chemin = 1; + ctpVar19 = ctpVar15; + + // can we go there directly ? + polydroite(x1, y1, x2, y2); + //////////////// + flag_obstacle = 0; + //////////////// + if (!flag_obstacle) { + solution0[0][0] = x1; + solution0[0][1] = y1; + ctpVar19 = ctpVar15; + + poly2(x2, y2, ctp_routeCoords[select_noeud[1]][0], + ctp_routeCoords[select_noeud[1]][1]); + + solution0[1][0] = table_ptselect[1][0] = X; + solution0[1][1] = table_ptselect[1][1] = Y; + solution0[2][0] = -1; + + if ((x1 == X) && (y1 == Y)) { + flag_aff_chemin = 0; + return; + } + } else { + // no, we take the fastest way + solution[0] = -1; + if (ctp_routes[select_noeud[0]][0] > 0) + chemin0(table[0], table[1]); + + if (solution[0] == -1) { + x1 = table_ptselect[0][0]; + y1 = table_ptselect[0][1]; + polydroite(x1, y1, x_mouse, y_mouse); + solution0[0][0] = x1; + solution0[0][1] = y1; + solution0[1][0] = X; + solution0[1][1] = Y; + + solution0[2][0] = -1; + if ((x1 == X) && (y1 == Y)) { + flag_aff_chemin = 0; + return; + } + } else { + solution0[0][0] = x1; + solution0[0][1] = y1; + i = 0; + while (solution[i] != -1) { + p1 = solution[i]; + solution0[i + 1][0] = + ctp_routeCoords[p1][0]; + solution0[++i][1] = + ctp_routeCoords[p1][1]; + } + ctpVar19 = ctpVar15; + poly2(x2, y2, + ctp_routeCoords[select_noeud[1]][0], + ctp_routeCoords[select_noeud[1]][1]); + solution0[i + 1][0] = table_ptselect[1][0] = X; + solution0[i + 1][1] = table_ptselect[1][1] = Y; + solution0[i + 2][0] = -1; + if ((x1 == X) && (y1 == Y)) { + flag_aff_chemin = 0; + return; + } + + /****** COUPE LE CHEMIN ******/ + + i++; + d = 0; + a = i; + flag_obstacle = 1; + while (d != a) { + x1 = solution0[d][0]; + y1 = solution0[d][1]; + + while (flag_obstacle && i != d) { + x2 = solution0[i][0]; + y2 = solution0[i][1]; + ctpVar19 = ctpVar15; + polydroite(x1, y1, x2, y2); + i--; + } + flag_obstacle = 1; + if (d != i) { + i++; + for (b = d + 1; b < i; b++) { + solution0[b][0] = -2; + } + } else + i++; + d = i; + i = a; + } + flag_obstacle = 0; + } + } + } +} + +//computePathfinding(returnVar2, params.X, params.Y, var34, var35, currentActor->stepX, currentActor->stepY); +int16 computePathfinding(int16 *pSolution, int16 x, int16 y, int16 destX, + int16 destY, int16 stepX, int16 stepY, int16 oldPathId) { + persoStruct *perso; + int num; + + if (!polyStruct) { + pSolution[0] = -1; + pSolution[1] = -1; + + return -1; + } + + if (oldPathId >= 0) { + if (persoTable[oldPathId]) { + freePerso(oldPathId); + } + } + + if (!flagCt) { + int i; + int16 *ptr; + + for (i = 0; i < NUM_PERSONS; i++) { // 10 = num perso + if (!persoTable[i]) { + break; + } + } + + if (i == NUM_PERSONS) { + pSolution[0] = -1; + pSolution[1] = -1; + + return -1; + } + + perso = persoTable[i] = + (persoStruct *) malloc(sizeof(persoStruct)); + + ptr = perso->solution[0]; + + perso->inc_jo1 = stepX; + perso->inc_jo2 = stepY; + + *(ptr++) = x; + *(ptr++) = y; + *(ptr++) = pSolution[0] = destX; + *(ptr++) = pSolution[1] = destY; + *(ptr++) = -1; + + pSolution[4] = computedVar14; + + perso->inc_droite = 0; + perso->inc_chemin = 0; + + return i; + } + + nclick_noeud = 0; + ctpVar19 = ctpVar11; + flag_aff_chemin = 0; + + if (x == destX && y == destY) { + pSolution[0] = -1; + pSolution[1] = -1; + + return (-1); + } + +/******* cherche le premier noeud ******/ + + getPixel(x, y); + + pSolution[4] = computedVar14; + + x_mouse = x; + y_mouse = y; + + if (!flag_obstacle + || (point_select = point_proche(ctp_routeCoords)) == -1) { + pSolution[0] = -1; + pSolution[1] = -1; + + return (-1); + } + + valide_noeud(select_noeud, point_select, &nclick_noeud, NULL); + + flag_aff_chemin = 0; + +/******* cherche le deuxieme noeud ******/ + + num = 0; + while (num < NUM_PERSONS && persoTable[num] != NULL) + num++; + + if (num == NUM_PERSONS) { + pSolution[0] = -1; + pSolution[1] = -1; + return (-1); + } + + perso = persoTable[num] = (persoStruct *) malloc(sizeof(persoStruct)); + + perso->inc_jo1 = stepX; + perso->inc_jo2 = stepY; + + x_mouse = destX; + y_mouse = destY; + + if ((point_select = point_proche(ctp_routeCoords)) != -1) + valide_noeud(select_noeud, point_select, &nclick_noeud, + perso->solution); + + if ((!flag_aff_chemin) + || ((table_ptselect[0][0] == table_ptselect[1][0]) + && (table_ptselect[0][1] == table_ptselect[1][1]))) { + pSolution[0] = -1; + pSolution[1] = -1; + freePerso(num); + + return (-1); + } + + pSolution[0] = table_ptselect[1][0]; + pSolution[1] = table_ptselect[1][1]; + pSolution[4] = computedVar14; + perso->inc_chemin = 0; + perso->inc_droite = 0; + + return (num); +} + +void set_anim(int ovl, int obj, int start, int x, int y, int mat, int state) { + int newf, zoom; + + newf = ABS(mat) - 1; + + zoom = computeZoom(y); + if (mat < 0) + zoom = -zoom; + + setObjectPosition(ovl, obj, 0, x); + setObjectPosition(ovl, obj, 1, y); + setObjectPosition(ovl, obj, 2, y); + setObjectPosition(ovl, obj, 4, zoom); + setObjectPosition(ovl, obj, 3, newf + start); + setObjectPosition(ovl, obj, 5, state); +} + +int raoul_move[][13] = { + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0}, /* dos */ + {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 0}, /* droite */ + {25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0}, /* face */ + {-13, -14, -15, -16, -17, -18, -19, -20, -21, -22, -23, -24, 0} /* gauche */ +}; + +int raoul_end[][13] = { + {37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* stat dos */ + {38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* stat droite */ + {39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* stat face */ + {-38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* stat gauche */ +}; + +int raoul_stat[][13] = { + {53, 54, 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0}, /* ret dos-dr */ + {59, 60, 62, 63, 78, 0, 0, 0, 0, 0, 0, 0, 0}, /* ret dr-face */ + {-78, -63, -62, -60, -59, 0, 0, 0, 0, 0, 0, 0, 0}, /* ret face-ga */ + {-57, -56, -55, -54, -53, 0, 0, 0, 0, 0, 0, 0, 0} /* ret ga-dos */ +}; + +int raoul_invstat[][13] = { + {-53, -54, -55, -56, -57, 0, 0, 0, 0, 0, 0, 0, 0}, /* ret dos-dr */ + {57, 56, 55, 54, 53, 0, 0, 0, 0, 0, 0, 0, 0}, /* ret ga-dos */ + {78, 63, 62, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0}, /* ret face-ga */ + {-59, -60, -62, -63, -78, 0, 0, 0, 0, 0, 0, 0, 0} /* ret dr-face */ + +}; + +void processAnimation(void) { + objectParamsQuery params; + int16 returnVar2[5]; + actorStruct *currentActor = &actorHead; + actorStruct *nextActor; + + while (currentActor) { + nextActor = currentActor->next; + + if (!currentActor->freeze && ((currentActor->type == 0) + || (currentActor->type == 1))) { + getMultipleObjectParam(currentActor->overlayNumber, + currentActor->idx, ¶ms); + + if (((animationStart && !currentActor->flag) || (!animationStart && currentActor->x_dest != -1 && currentActor->y_dest != -1)) && (currentActor->type == 0)) { + // mouse animation + if (!animationStart) { + var34 = currentActor->x_dest; + var35 = currentActor->y_dest; + + currentActor->x_dest = -1; + currentActor->y_dest = -1; + + currentActor->flag = 1; + } + + currentActor->pathId = computePathfinding(returnVar2, params.X, params.Y, var34, var35, currentActor->stepX, currentActor->stepY, currentActor->pathId); + + if (currentActor->pathId == -1) { + if ((currentActor->endDirection != -1) && (currentActor->endDirection != currentActor->startDirection)) { + currentActor->phase = ANIM_PHASE_STATIC_END; + currentActor->nextDirection = currentActor->endDirection; + currentActor->endDirection = -1; + currentActor->counter = 0; + } else { + currentActor->pathId = -2; + currentActor->flag = 0; + currentActor->endDirection = -1; + currentActor->phase = ANIM_PHASE_WAIT; + } + } else { + currentActor->phase = ANIM_PHASE_STATIC; + currentActor->counter = -1; + } + } else + if ((currentActor->type == 1) && (currentActor->x_dest != -1) && (currentActor->y_dest != -1)) { + // track animation + currentActor->pathId = computePathfinding(returnVar2, params.X, params.Y, currentActor->x_dest, currentActor->y_dest, currentActor->stepX, currentActor->stepY, currentActor->pathId); + + currentActor->x_dest = -1; + currentActor->y_dest = -1; + + if (currentActor->pathId == -1) { + if ((currentActor->endDirection != -1) && (currentActor->endDirection != currentActor->startDirection)) { + currentActor->phase = ANIM_PHASE_STATIC_END; + currentActor->nextDirection = currentActor->endDirection; + currentActor->endDirection = -1; + currentActor->counter = 0; + } else { + currentActor->pathId = -2; + currentActor->flag = 0; + currentActor->endDirection = -1; + currentActor->phase = ANIM_PHASE_WAIT; + } + } else { + currentActor->phase = ANIM_PHASE_STATIC; + currentActor->counter = -1; + } + } + + animationStart = false; + + if ((currentActor->pathId >= 0) || (currentActor->phase == ANIM_PHASE_STATIC_END)) { + switch (currentActor->phase) { + case ANIM_PHASE_STATIC_END: + case ANIM_PHASE_STATIC: + { + if ((currentActor->counter == -1) && (currentActor->phase == ANIM_PHASE_STATIC)) { + affiche_chemin(currentActor->pathId, returnVar2); + + if (returnVar2[0] == -1) { + currentActor->pathId = -2; + currentActor->flag = 0; + currentActor->endDirection = -1; + currentActor->phase = ANIM_PHASE_WAIT; + break; + } + + currentActor->x = returnVar2[0]; + currentActor->y = returnVar2[1]; + currentActor->nextDirection = returnVar2[2]; + currentActor->poly = returnVar2[4]; + currentActor->counter = 0; + + if (currentActor->startDirection == currentActor->nextDirection) + currentActor->phase = ANIM_PHASE_MOVE; + } + + if ((currentActor->counter >= + 0) + && ((currentActor->phase == + ANIM_PHASE_STATIC_END) + || (currentActor-> + phase == + ANIM_PHASE_STATIC))) + { + int newA; + int inc = 1; + int t_inc = + currentActor-> + startDirection - 1; + + if (t_inc < 0) + t_inc = 3; + + if (currentActor-> + nextDirection == + t_inc) + inc = -1; + + if (inc > 0) + newA = + raoul_stat + [currentActor-> + startDirection] + [currentActor-> + counter++]; + else + newA = + raoul_invstat + [currentActor-> + startDirection] + [currentActor-> + counter++]; + + if (newA == 0) { + currentActor-> + startDirection + = + currentActor-> + startDirection + + inc; + + if (currentActor->startDirection > 3) + currentActor-> + startDirection + = + 0; + + if (currentActor->startDirection < 0) + currentActor-> + startDirection + = + 3; + + currentActor-> + counter = + 0; + + if (currentActor->startDirection == currentActor->nextDirection) { + if (currentActor->phase == ANIM_PHASE_STATIC) + currentActor-> + phase + = + ANIM_PHASE_MOVE; + else + currentActor-> + phase + = + ANIM_PHASE_END; + } else { + newA = + raoul_stat + [currentActor-> + startDirection] + [currentActor-> + counter++]; + + if (inc + == + -1) + newA = -newA; + + set_anim + (currentActor-> + overlayNumber, + currentActor-> + idx, + currentActor-> + start, + params. + X, + params. + Y, + newA, + currentActor-> + poly); + break; + } + } else { + set_anim + (currentActor-> + overlayNumber, + currentActor-> + idx, + currentActor-> + start, + params.X, + params.Y, + newA, + currentActor-> + poly); + break; + } + } + break; + } + case ANIM_PHASE_MOVE: + { + if (currentActor->counter >= 1) { + affiche_chemin + (currentActor-> + pathId, + returnVar2); + if (returnVar2[0] == + -1) { + if ((currentActor->endDirection == -1) || (currentActor->endDirection == currentActor->nextDirection)) { + currentActor-> + phase + = + ANIM_PHASE_END; + } else { + currentActor-> + phase + = + ANIM_PHASE_STATIC_END; + currentActor-> + nextDirection + = + currentActor-> + endDirection; + } + currentActor-> + counter = + 0; + break; + } else { + currentActor-> + x = + returnVar2 + [0]; + currentActor-> + y = + returnVar2 + [1]; + currentActor-> + nextDirection + = + returnVar2 + [2]; + currentActor-> + poly = + returnVar2 + [4]; + + /* + * if (pl->next_dir!=pl->start_dir) + * { + * pl->phase=PHASE_STATIC; + * pl->cnt=0; + * break; + * } + */ + } + } + + if (currentActor->phase == + ANIM_PHASE_MOVE) { + int newA; + + currentActor-> + startDirection = + currentActor-> + nextDirection; + + newA = + raoul_move + [currentActor-> + startDirection] + [currentActor-> + counter++]; + if (!newA) { + currentActor-> + counter = + 0; + newA = + raoul_move + [currentActor-> + startDirection] + [currentActor-> + counter++]; + } + set_anim(currentActor-> + overlayNumber, + currentActor->idx, + currentActor-> + start, + currentActor->x, + currentActor->y, + newA, + currentActor-> + poly); + break; + } + + break; + } + case ANIM_PHASE_END: + { + int newA = raoul_end[currentActor->startDirection][0]; + + set_anim(currentActor->overlayNumber, currentActor->idx, currentActor->start, currentActor->x, currentActor->y, newA, currentActor->poly); + + currentActor->pathId = -2; + currentActor->phase = ANIM_PHASE_WAIT; + currentActor->flag = 0; + currentActor->endDirection = -1; + break; + } + default: + { + printf("Unimplemented currentActor->phase=%d in processAnimation()\n", currentActor->phase); + // exit(1); + } + } + } + } + currentActor = nextActor; + } +} + +} // End of namespace Cruise diff --git a/engines/cruise/actor.h b/engines/cruise/actor.h new file mode 100644 index 0000000000..0485fcc003 --- /dev/null +++ b/engines/cruise/actor.h @@ -0,0 +1,75 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_ACTOR_H +#define CRUISE_ACTOR_H + +namespace Cruise { + +enum animPhase { + ANIM_PHASE_WAIT = 0, + ANIM_PHASE_STATIC = 1, + ANIM_PHASE_MOVE = 2, + ANIM_PHASE_STATIC_END = 3, + ANIM_PHASE_END = 4 +}; + +struct actorStruct { + struct actorStruct *next; + struct actorStruct *prev; + + int16 idx; + int16 type; + int16 overlayNumber; + int16 x_dest; + int16 y_dest; + int16 x; + int16 y; + int16 startDirection; + int16 nextDirection; + int16 endDirection; + int16 stepX; + int16 stepY; + int16 pathId; + animPhase phase; + int16 counter; + int16 poly; + int16 flag; + int16 start; + int16 freeze; +}; + +extern int raoul_move[][13]; +extern int raoul_end[][13]; +extern int raoul_stat[][13]; +extern int raoul_invstat[][13]; + +int16 mainProc13(int overlayIdx, int param1, actorStruct * pStartEntry, int param2); +actorStruct *findActor(int overlayIdx, int param1, actorStruct * pStartEntry, int param2); +void processAnimation(void); +void getPixel(int x, int y); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/background.cpp b/engines/cruise/background.cpp new file mode 100644 index 0000000000..0d5b8d4fbb --- /dev/null +++ b/engines/cruise/background.cpp @@ -0,0 +1,193 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +uint8 colorMode = 0; + +uint8 *backgroundPtrtable[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; // wasn't initialized in original, but it's probably better +backgroundTableStruct backgroundTable[8]; + +char hwPage[64000]; + +char *hwMemAddr[] = { + hwPage, +}; + +short int cvtPalette[0x20]; + +int loadMEN(uint8 **ptr) { + char *localPtr = (char *)*ptr; + + if (!strcmp(localPtr, "MEN")) { + localPtr += 4; + + video4 = *(localPtr++); + video3 = *(localPtr++); + video2 = *(localPtr++); + colorOfSelectedSaveDrive = *(localPtr++); + + *ptr = (uint8 *) localPtr; + + return 1; + } else { + return 0; + } +} + +int CVTLoaded; + +int loadCVT(uint8 **ptr) { + char *localPtr = (char *)*ptr; + + if (!strcmp(localPtr, "CVT")) { + int i; + localPtr += 4; + + for (i = 0; i < 0x20; i++) { + cvtPalette[i] = *(localPtr++); + } + + *ptr = (uint8 *) localPtr; + + CVTLoaded = 1; + + return 1; + } else { + CVTLoaded = 0; + return 0; + } +} + +extern int lastFileSize; + +int loadBackground(char *name, int idx) { + uint8 *ptr; + uint8 *ptr2; + uint8 *ptrToFree; + + printf("Loading BG: %s\n", name); + + if (!backgroundPtrtable[idx]) { + //if(!gfxModuleData.useEGA && !gfxModuleData.useVGA) + { + backgroundPtrtable[idx] = + (uint8 *) mallocAndZero(320 * 200 /*64000 */ ); + } +/* else + { + backgroundPtrtable[idx] = hwMemAddr[idx]; + } */ + } + + if (!backgroundPtrtable[idx]) { + backgroundTable[idx].name[0] = 0; + return (-2); + } + + ptrToFree = gfxModuleData.pPage10; + if (loadFileSub1(&ptrToFree, (uint8 *) name, NULL) < 0) { + if (ptrToFree != gfxModuleData.pPage10) + free(ptrToFree); + + return (-18); + } + + if (lastFileSize == 32078 || lastFileSize == 32080 + || lastFileSize == 32034) { + colorMode = 0; + } else { + colorMode = 1; + } + + ptr = ptrToFree; + ptr2 = ptrToFree; + + if (!strcmpuint8(name, "LOGO.PI1")) { + bgVar3 = bgVar2; + bgVar1 = 1; + bgVar2 = 1; + } else { + if (bgVar1) { + bgVar2 = bgVar3; + bgVar1 = 0; + } + } + + if (!strcmpuint8(ptr, "PAL")) { + printf("Pal loading unsupported !\n"); + exit(1); + } else { + if (!colorMode || ptr2[1] == 5) { + ptr2 += 2; + + memcpy(palette, ptr2, 0x20); + ptr2 += 0x20; + flipGen(palette, 0x20); + ptr2 += 0x7D00; + + loadMEN(&ptr2); + loadCVT(&ptr2); + + gfxModuleData_gfxClearFrameBuffer(backgroundPtrtable + [idx]); + gfxModuleData_field_60((char *)ptrToFree + 34, 20, 200, + (char *)backgroundPtrtable[idx], 0, 0); + + gfxModuleData_setPal((uint8 *) (palette + (idx << 6))); + } else if (ptr2[1] == 8) { + int i; + ptr2 += 2; + + for (i = 0; i < 256 * 3; i++) { + palette[i] = ptr2[i]; + } + //memcpy(palette,ptr2,256*3); + ptr2 += 256 * 3; + + memcpy(backgroundPtrtable[idx], ptr2, 320 * 200); + + gfxModuleData_setPal256(palette); + } + } + + //if(ptrToFree != gfxModuleData.pPage10) + // free(ptrToFree); + + if (gfxModuleData.useEGA || gfxModuleData.useTandy) { + ASSERT(0); + } + + if (gfxModuleData.useEGA || gfxModuleData.useTandy) { + ASSERT(0); + } + + strcpy(backgroundTable[idx].name, name); + + return (0); +} + +} // End of namespace Cruise diff --git a/engines/cine/resource.h b/engines/cruise/background.h index 9f3f5bb927..07364a947f 100644 --- a/engines/cine/resource.h +++ b/engines/cruise/background.h @@ -22,26 +22,23 @@ * */ -#ifndef CINE_RESOURCE_H -#define CINE_RESOURCE_H +#ifndef CRUISE_BACKGROUND_H +#define CRUISE_BACKGROUND_H -#include "common/stdafx.h" -#include "common/scummsys.h" +namespace Cruise { -namespace Cine { - -struct BasesonEntry { - char name[14]; - uint32 offset; - uint32 size; - uint32 unpackedSize; +struct backgroundTableStruct { + char name[9]; + char extention[6]; }; -void checkDataDisk(int16 param); -extern int snd_loadBasesonEntries(const char *fileName); -extern void snd_clearBasesonEntries(); -extern byte *snd_loadBasesonEntry(const char *entryName); +extern short int cvtPalette[0x20]; +extern int CVTLoaded; +extern uint8 *backgroundPtrtable[8]; +extern backgroundTableStruct backgroundTable[8]; + +int loadBackground(char *name, int idx); -} // End of namespace Cine +} // End of namespace Cruise #endif diff --git a/engines/cruise/backgroundIncrust.cpp b/engines/cruise/backgroundIncrust.cpp new file mode 100644 index 0000000000..99c2fda8c3 --- /dev/null +++ b/engines/cruise/backgroundIncrust.cpp @@ -0,0 +1,275 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +backgroundIncrustStruct backgroundIncrustHead; + +void resetBackgroundIncrustList(backgroundIncrustStruct *pHead) { + pHead->next = NULL; + pHead->prev = NULL; +} + +// blit background to another one +void addBackgroundIncrustSub1(int fileIdx, int X, int Y, char *ptr2, + int16 scale, char *destBuffer, char *dataPtr) { + if (*dataPtr == 0) { + ASSERT(0); + } + + buildPolyModel(X, Y, scale, ptr2, destBuffer, dataPtr); +} + +backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, + int16 objectIdx, backgroundIncrustStruct *pHead, int16 scriptNumber, + int16 scriptOverlay, int16 backgroundIdx, int16 param4) { + uint8 *backgroundPtr; + uint8 *ptr; + objectParamsQuery params; + backgroundIncrustStruct *newElement; + backgroundIncrustStruct *currentHead; + backgroundIncrustStruct *currentHead2; + + getMultipleObjectParam(overlayIdx, objectIdx, ¶ms); + + ptr = filesDatabase[params.fileIdx].subData.ptr; + + if (!ptr) { + return NULL; + } + + if (filesDatabase[params.fileIdx].subData.resourceType != 4 + && filesDatabase[params.fileIdx].subData.resourceType != 8) { + return NULL; + } + + backgroundPtr = backgroundPtrtable[backgroundIdx]; + + if (!backgroundPtr) { + ASSERT(0); + return NULL; + } + + currentHead = pHead; + currentHead2 = currentHead->next; + + while (currentHead2) { + currentHead = currentHead2; + currentHead2 = currentHead->next; + } + + newElement = + (backgroundIncrustStruct *) + mallocAndZero(sizeof(backgroundIncrustStruct)); + + if (!newElement) + return NULL; + + newElement->next = currentHead->next; + currentHead->next = newElement; + + if (!currentHead2) { + currentHead2 = pHead; + } + + newElement->prev = currentHead2->prev; + currentHead2->prev = newElement; + + newElement->objectIdx = objectIdx; + newElement->type = param4; + newElement->backgroundIdx = backgroundIdx; + newElement->overlayIdx = overlayIdx; + newElement->scriptNumber = scriptNumber; + newElement->scriptOverlayIdx = scriptOverlay; + newElement->X = params.X; + newElement->Y = params.Y; + newElement->scale = params.scale; + newElement->field_E = params.fileIdx; + newElement->var34 = filesDatabase[params.fileIdx].subData.index; + newElement->ptr = NULL; + strcpy(newElement->name, filesDatabase[params.fileIdx].subData.name); + + if (filesDatabase[params.fileIdx].subData.resourceType == 4) // sprite + { + int width = filesDatabase[params.fileIdx].width; + int height = filesDatabase[params.fileIdx].height; + + currentTransparent = + filesDatabase[params.fileIdx].subData.transparency; + mainDrawSub4(width, height, NULL, + (char *)filesDatabase[params.fileIdx].subData.ptr, + newElement->Y, newElement->X, (char *)backgroundPtr, + (char *)filesDatabase[params.fileIdx].subData.ptr); + // ASSERT(0); + } else // poly + { + /* if(param4 == 1) + * { + * int var_A; + * int var_8; + * int var_6; + * char* var_10; + * + * mainDrawSub1Sub1(lvar[3], newElement->X, newElement->Y, &var_A, &var_8, &var_6, &var_10, lvar[4], filesDatabase[lvar[3]].subData.ptr); + * ASSERT(0); + * } */ + + addBackgroundIncrustSub1(params.fileIdx, newElement->X, newElement->Y, NULL, params.scale, (char *)backgroundPtr, (char *)filesDatabase[params.fileIdx].subData.ptr); + } + + return newElement; +} + +void loadBackgroundIncrustFromSave(FILE *fileHandle) { + int16 numEntry; + backgroundIncrustStruct *ptr1; + backgroundIncrustStruct *ptr2; + int32 i; + + fread(&numEntry, 2, 1, fileHandle); + + ptr1 = &backgroundIncrustHead; + ptr2 = &backgroundIncrustHead; + + for (i = 0; i < numEntry; i++) { + backgroundIncrustStruct *current = + (backgroundIncrustStruct *) + mallocAndZero(sizeof(backgroundIncrustStruct)); + + fseek(fileHandle, 4, SEEK_CUR); + + fread(¤t->objectIdx, 2, 1, fileHandle); + fread(¤t->type, 2, 1, fileHandle); + fread(¤t->overlayIdx, 2, 1, fileHandle); + fread(¤t->X, 2, 1, fileHandle); + fread(¤t->Y, 2, 1, fileHandle); + fread(¤t->field_E, 2, 1, fileHandle); + fread(¤t->scale, 2, 1, fileHandle); + fread(¤t->backgroundIdx, 2, 1, fileHandle); + fread(¤t->scriptNumber, 2, 1, fileHandle); + fread(¤t->scriptOverlayIdx, 2, 1, fileHandle); + fread(¤t->ptr, 4, 1, fileHandle); + fread(¤t->field_1C, 4, 1, fileHandle); + fread(¤t->size, 2, 1, fileHandle); + fread(¤t->field_22, 2, 1, fileHandle); + fread(¤t->field_24, 2, 1, fileHandle); + fread(current->name, 14, 1, fileHandle); + fread(¤t->var34, 2, 1, fileHandle); + + if (current->size) { + current->ptr = (uint8 *) mallocAndZero(current->size); + fread(current->ptr, current->size, 1, fileHandle); + } + + current->next = NULL; + ptr2 = current; + current->prev = backgroundIncrustHead.prev; + backgroundIncrustHead.prev = current; + ptr2 = current->next; + } +} + +void regenerateBackgroundIncrust(backgroundIncrustStruct *pHead) { + printf("Need to regenerate backgroundIncrust\n"); +} + +void freeBackgroundIncrustList(backgroundIncrustStruct *pHead) { + backgroundIncrustStruct *pCurrent = pHead->next; + + while (pCurrent) { + backgroundIncrustStruct *pNext = pCurrent->next; + + if (pCurrent->ptr) { + free(pCurrent->ptr); + } + + free(pCurrent); + + pCurrent = pNext; + } + + resetBackgroundIncrustList(pHead); +} + +void removeBackgroundIncrust(int overlay, int idx, backgroundIncrustStruct * pHead) { + objectParamsQuery params; + int var_4; + int var_6; + + backgroundIncrustStruct *pCurrent; + backgroundIncrustStruct *pCurrentHead; + + getMultipleObjectParam(overlay, idx, ¶ms); + + var_4 = params.X; + var_6 = params.Y; + + pCurrent = pHead->next; + + while (pCurrent) { + if ((pCurrent->overlayIdx == overlay || overlay == -1) && + (pCurrent->objectIdx == idx || idx == -1) && + (pCurrent->X == var_4) && (pCurrent->Y == var_6)) { + pCurrent->type = - 1; + } + + pCurrent = pCurrent->next; + } + + pCurrentHead = pHead; + pCurrent = pHead->next; + + while (pCurrent) { + if (pCurrent->type == - 1) { + backgroundIncrustStruct *pNext = pCurrent->next; + backgroundIncrustStruct *bx = pCurrentHead; + backgroundIncrustStruct *cx; + + bx->next = pNext; + cx = pNext; + + if (!pNext) { + cx = pHead; + } + + bx = cx; + bx->prev = pCurrent->next; + + if (pCurrent->ptr) { + free(pCurrent->ptr); + } + + free(pCurrent); + + pCurrent = pNext; + } else { + pCurrentHead = pCurrent; + pCurrent = pCurrent->next; + } + } +} + +} // End of namespace Cruise diff --git a/engines/cruise/backgroundIncrust.h b/engines/cruise/backgroundIncrust.h new file mode 100644 index 0000000000..abbe837ad7 --- /dev/null +++ b/engines/cruise/backgroundIncrust.h @@ -0,0 +1,66 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_BACKGROUNDINCRUST_H +#define CRUISE_BACKGROUNDINCRUST_H + +namespace Cruise { + +struct backgroundIncrustStruct { + struct backgroundIncrustStruct *next; + struct backgroundIncrustStruct *prev; + + uint16 objectIdx; + int16 type; + uint16 overlayIdx; + uint16 X; + uint16 Y; + uint16 field_E; + uint16 scale; + uint16 backgroundIdx; + uint16 scriptNumber; + uint16 scriptOverlayIdx; + uint8 *ptr; + int32 field_1C; + int16 size; + uint16 field_22; + uint16 field_24; + char name[14]; + uint16 var34; +}; + +extern backgroundIncrustStruct backgroundIncrustHead; + +void resetBackgroundIncrustList(backgroundIncrustStruct * pHead); +backgroundIncrustStruct *addBackgroundIncrust(int16 overlayIdx, int16 param2, + backgroundIncrustStruct * pHead, int16 scriptNumber, int16 scriptOverlay, + int16 backgroundIdx, int16 param4); +void loadBackgroundIncrustFromSave(FILE * fileHandle); +void regenerateBackgroundIncrust(backgroundIncrustStruct * pHead); +void freeBackgroundIncrustList(backgroundIncrustStruct * pHead); +void removeBackgroundIncrust(int overlay, int idx, backgroundIncrustStruct * pHead); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/cell.cpp b/engines/cruise/cell.cpp new file mode 100644 index 0000000000..2c9589f744 --- /dev/null +++ b/engines/cruise/cell.cpp @@ -0,0 +1,362 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cell.h" +#include "cruise/cruise_main.h" + +namespace Cruise { + +cellStruct cellHead; + +void resetPtr(cellStruct *ptr) { + ptr->next = NULL; + ptr->prev = NULL; +} + +void freeMessageList(cellStruct *objPtr) { +/* if (objPtr) { + if(objPtr->next) + free(objPtr->next); + + free(objPtr); + } */ +} + +void loadSavegameDataSub2(FILE *f) { + unsigned short int n_chunks; + int i; + cellStruct *p; + cellStruct *t; + + cellHead.next = NULL; // Not in ASM code, but I guess the variable is defaulted + // to this value in the .exe + + fread(&n_chunks, 2, 1, f); + // BIG ENDIAN MACHINES, PLEASE SWAP IT + + p = &cellHead; + + for (i = 0; i < n_chunks; i++) { + t = (cellStruct *) mallocAndZero(sizeof(cellStruct)); + + fseek(f, 4, SEEK_CUR); + fread(&t->idx, 1, 0x30, f); + + t->next = NULL; + p->next = t; + t->prev = cellHead.prev; + cellHead.prev = t; + p = t; + } +} + +cellStruct *addCell(cellStruct *pHead, int16 overlayIdx, int16 objIdx, int16 type, int16 backgroundPlane, int16 scriptOverlay, int16 scriptNumber, int16 scriptType) { + int16 var; + + cellStruct *newElement; + cellStruct *currentHead = pHead; + cellStruct *currentHead2; + cellStruct *currentHead3; + + if (getSingleObjectParam(overlayIdx, objIdx, 2, &var) < 0) { + return 0; + } + + currentHead3 = currentHead; + currentHead2 = currentHead->next; + + while (currentHead2) { + if (currentHead2->type == 3) { + break; + } + + if (currentHead2->type != 5) { + int16 lvar2; + + getSingleObjectParam(currentHead2->overlay, currentHead2->idx, 2, &lvar2); + + if (lvar2 > var) + break; + } + + currentHead3 = currentHead2; + currentHead2 = currentHead2->next; + } + + if (currentHead2) { + if ((currentHead2->overlay == overlayIdx) && + (currentHead2->backgroundPlane == backgroundPlane) && + (currentHead2->idx == objIdx) && + (currentHead2->type == type)) + + return NULL; + } + + currentHead = currentHead2; + + newElement = (cellStruct *) mallocAndZero(sizeof(cellStruct)); + + if (!newElement) + return 0; + + newElement->next = currentHead3->next; + currentHead3->next = newElement; + + newElement->idx = objIdx; + newElement->type = type; + newElement->backgroundPlane = backgroundPlane; + newElement->overlay = overlayIdx; + newElement->freeze = 0; + newElement->parent = scriptNumber; + newElement->parentOverlay = scriptOverlay; + newElement->gfxPtr = NULL; + newElement->followObjectIdx = objIdx; + newElement->followObjectOverlayIdx = overlayIdx; + newElement->parentType = scriptType; + + newElement->animStart = 0; + newElement->animEnd = 0; + newElement->animWait = 0; + newElement->animSignal = 0; + newElement->animCounter = 0; + newElement->animType = 0; + newElement->animStep = 0; + newElement->animLoop = 0; + + if (currentHead) { + newElement->prev = currentHead->prev; + currentHead->prev = newElement; + } else { + newElement->prev = pHead->prev; + pHead->prev = newElement; + } + + return newElement; +} + +void createTextObject(int overlayIdx, int oldVar8, cellStruct *pObject, int scriptNumber, int scriptOverlayNumber, int backgroundPlane, int16 color, int oldVar2, int oldVar4, int oldVar6) { + + char *ax; + cellStruct *savePObject = pObject; + cellStruct *cx; + + cellStruct *pNewElement; + cellStruct *si = pObject->next; + cellStruct *var_2; + + while (si) { + pObject = si; + si = si->next; + } + + var_2 = si; + + pNewElement = (cellStruct *) malloc(sizeof(cellStruct)); + + pNewElement->next = pObject->next; + pObject->next = pNewElement; + + pNewElement->idx = oldVar8; + pNewElement->type = 5; + pNewElement->backgroundPlane = backgroundPlane; + pNewElement->overlay = overlayIdx; + pNewElement->x = oldVar6; + pNewElement->field_C = oldVar4; + pNewElement->spriteIdx = oldVar2; + pNewElement->color = color; + pNewElement->freeze = 0; + pNewElement->parent = scriptNumber; + pNewElement->parentOverlay = scriptOverlayNumber; + pNewElement->gfxPtr = NULL; + + if (var_2) { + cx = var_2; + } else { + cx = savePObject; + } + + pNewElement->prev = cx->prev; + cx->prev = pNewElement; + + ax = getText(oldVar8, overlayIdx); + + if (ax) { + pNewElement->gfxPtr = renderText(oldVar2, (uint8 *) ax); + } +} + +void removeCell(cellStruct *objPtr, int ovlNumber, int objectIdx, int objType, int backgroundPlane ) { + cellStruct *currentObj = objPtr->next; + cellStruct *previous; + + while (currentObj) { + if (((currentObj->overlay == ovlNumber) || (ovlNumber == -1)) && + ((currentObj->idx == objectIdx) || (objectIdx == -1)) && + ((currentObj->type == objType) || (objType == -1)) && + ((currentObj->backgroundPlane == backgroundPlane) || (backgroundPlane == -1))) { + currentObj->type = -1; + } + + currentObj = currentObj->next; + } + + previous = objPtr; + currentObj = objPtr->next; + + while (currentObj) { + cellStruct *si; + + si = currentObj; + + if (si->type == -1) { + cellStruct *dx; + previous->next = si->next; + + dx = si->next; + + if (!si->next) { + dx = objPtr; + } + + dx->prev = si->prev; + + // TODO: complelty wrong + //freeMessageList(si); + + free(si); + + currentObj = dx; + } else { + currentObj = si->next; + previous = si; + } + } +} + +void freezeCell(cellStruct * pObject, int overlayIdx, int objIdx, int objType, int backgroundPlane, int oldFreeze, int newFreeze ) { + while (pObject) { + if ((pObject->overlay == overlayIdx) || (overlayIdx == -1)) { + if ((pObject->idx == objIdx) || (objIdx == -1)) { + if ((pObject->type == objType) || (objType == -1)) { + if ((pObject->backgroundPlane == backgroundPlane) || (backgroundPlane == -1)) { + if ((pObject->freeze == oldFreeze) || (oldFreeze == -1)) { + pObject->freeze = newFreeze; + } + } + } + } + } + + pObject = pObject->next; + } +} + +void sortCells(int16 param1, int16 param2, cellStruct *objPtr) { + int16 var; + cellStruct *var8_; + cellStruct *var40; + cellStruct *var3E; + cellStruct *currentObjPtrPrevious; + cellStruct *currentObjPtr2; + cellStruct *match; + + getSingleObjectParam(param1, param2, 2, &var); + + currentObjPtrPrevious = objPtr; + currentObjPtr2 = objPtr->next; + + match = NULL; + var40 = NULL; + var3E = NULL; + var8_ = objPtr; + + while (currentObjPtr2) { + if ((currentObjPtr2->overlay == param1) && (currentObjPtr2->idx == param2)) {// found + currentObjPtrPrevious->next = currentObjPtr2->next; + + if (currentObjPtr2->next) { + currentObjPtr2->next->prev = + currentObjPtr2->prev; + } else { + objPtr->prev = currentObjPtr2->prev; + } + + if (var40) { + var40->prev = currentObjPtr2; + } else { + var3E = currentObjPtr2; + } + + currentObjPtr2->prev = NULL; + + currentObjPtr2->next = var40; + + var40 = currentObjPtr2; + + if (match == NULL) { + match = currentObjPtr2; + } + } else { + if (currentObjPtr2->type == 5) { + var2 = 32000; + } else { + int16 varC; + + getSingleObjectParam(currentObjPtr2->overlay, + currentObjPtr2->idx, 2, &varC); + + var2 = varC; + } + + if (var > var2) { + var8_ = currentObjPtr2; + } + + currentObjPtrPrevious = currentObjPtrPrevious->next; + } + + currentObjPtr2 = currentObjPtr2->next; + } + + if (match) { + cellStruct *temp; + + temp = var8_->next; + + var8_->next = var40; + match->next = temp; + + if (objPtr != var8_) { + var40->prev = var8_; + } + + if (!temp) { + temp = match; + } + + temp->prev = match; + } +} + +} // End of namespace Cruise diff --git a/engines/cruise/cell.h b/engines/cruise/cell.h new file mode 100644 index 0000000000..2664d3421f --- /dev/null +++ b/engines/cruise/cell.h @@ -0,0 +1,76 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_CELL_H +#define CRUISE_CELL_H + +#include "common/stdafx.h" +#include "common/scummsys.h" + +namespace Cruise { + +struct gfxEntryStruct; + +struct cellStruct { + struct cellStruct *next; + struct cellStruct *prev; + int16 idx; + int16 type; + int16 overlay; + int16 x; + int16 field_C; + int16 spriteIdx; + int16 color; + int16 backgroundPlane; + int16 freeze; + int16 parent; + int16 parentOverlay; + int16 parentType; + int16 followObjectOverlayIdx; + int16 followObjectIdx; + int16 animStart; + int16 animEnd; + int16 animWait; + int16 animStep; + int16 animChange; + int16 animType; + int16 animSignal; + int16 animCounter; + int16 animLoop; + gfxEntryStruct *gfxPtr; +}; + +extern cellStruct cellHead; + +void resetPtr(cellStruct * ptr); +void loadSavegameDataSub2(FILE * f); +cellStruct *addCell(cellStruct *pHead, int16 overlayIdx, int16 objIdx, int16 type, int16 backgroundPlane, int16 scriptOverlay, int16 scriptNumber, int16 scriptType); +void createTextObject(int overlayIdx, int oldVar8, cellStruct * pObject, int scriptNumber, int scriptOverlayNumber, int backgroundPlane, int16 color, int oldVar2, int oldVar4, int oldVar6); +void removeCell(cellStruct *objPtr, int ovlNumber, int objectIdx, int objType, int backgroundPlane ); +void freezeCell(cellStruct * pObject, int overlayIdx, int objIdx, int objType, int backgroundPlane, int oldFreeze, int newFreeze ); +void sortCells(int16 param1, int16 param2, cellStruct *objPtr); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp new file mode 100644 index 0000000000..3704842019 --- /dev/null +++ b/engines/cruise/cruise.cpp @@ -0,0 +1,122 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/file.h" +#include "common/fs.h" +#include "common/savefile.h" +#include "common/config-manager.h" +#include "common/system.h" + +#include "graphics/cursorman.h" + +#include "sound/mididrv.h" +#include "sound/mixer.h" + +#include "cruise/cruise.h" + +namespace Cruise { + +//SoundDriver *g_soundDriver; +//SfxPlayer *g_sfxPlayer; +Common::SaveFileManager * g_saveFileMan; + +CruiseEngine *g_cruise; + +CruiseEngine::CruiseEngine(OSystem * syst) : Engine(syst) { + +#ifdef PALMOS_MODE + _currentVolumeFile = new Common::File(); +#endif + + Common::addSpecialDebugLevel(kCruiseDebugScript, "Script", + "Script debug level"); + + // Setup mixer + if (!_mixer->isReady()) { + warning("Sound initialization failed."); + } + + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, + ConfMan.getInt("sfx_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, + ConfMan.getInt("music_volume")); + + g_cruise = this; +} + +CruiseEngine::~CruiseEngine() { +#ifdef PALMOS_MODE + delete _currentVolumeFile; +#endif +} + +int CruiseEngine::init() { + // Detect game + if (!initGame()) { + GUIErrorMessage + ("No valid games were found in the specified directory."); + return -1; + } + // Initialize backend + _system->beginGFXTransaction(); + initCommonGFX(false); + _system->initSize(320, 200); + _system->endGFXTransaction(); + + initialize(); + + return 0; +} + +int CruiseEngine::go() { + CursorMan.showMouse(true); + + Cruise::mainLoop(); + + return 0; +} + +void CruiseEngine::initialize() { + + fadeVar = 0; + ptr_something = + (ctpVar19Struct *) mallocAndZero(sizeof(ctpVar19Struct) * 0x200); + + /*volVar1 = 0; + * fileData1 = 0; */ + + /*PAL_fileHandle = -1; */ + + // video init stuff + + loadSystemFont(); + + // another bit of video init + + readVolCnf(); + +} + +} // End of namespace Cruise diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h new file mode 100644 index 0000000000..144a7fdd12 --- /dev/null +++ b/engines/cruise/cruise.h @@ -0,0 +1,106 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CruisE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_CRUISE_H +#define CRUISE_CRUISE_H + +#include "common/stdafx.h" +#include "common/scummsys.h" +#include "common/util.h" + +#include "engines/engine.h" + +#include "cruise/cruise_main.h" + +namespace Cruise { + +enum CruiseGameType { + GType_CRUISE = 1 +}; + +struct CRUISEGameDescription; + +class CruiseEngine:public Engine { + + protected: + int init(); + int go(); + void shutdown(); + + bool initGame(); + + public: + CruiseEngine(OSystem * syst); + virtual ~ CruiseEngine(); + + int getGameType() const; + uint32 getFeatures() const; + Common::Language getLanguage() const; + Common::Platform getPlatform() const; + + bool loadSaveDirectory(void); + void makeSystemMenu(void); + + const CRUISEGameDescription *_gameDescription; + + private: + void initialize(void); + bool makeLoad(char *saveName); + void mainLoop(int bootScriptIdx); + + bool _preLoad; +}; + +extern CruiseEngine *g_cruise; + +#define BOOT_PRC_NAME "AUTO00.PRC" + +enum { + VAR_MOUSE_X_MODE = 253, + VAR_MOUSE_X_POS = 249, + VAR_MOUSE_Y_MODE = 251, + VAR_MOUSE_Y_POS = 250 +}; + +enum { + MOUSE_CURSOR_NORMAL = 0, + MOUSE_CURSOR_DISK, + MOUSE_CURSOR_CROSS +}; + +enum { + kCruiseDebugScript = 1 << 0 +}; + +enum { + kCmpEQ = (1 << 0), + kCmpGT = (1 << 1), + kCmpLT = (1 << 2) +}; + +extern Common::SaveFileManager * g_saveFileMan; // TEMP + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp new file mode 100644 index 0000000000..dcc8777bad --- /dev/null +++ b/engines/cruise/cruise_main.cpp @@ -0,0 +1,1682 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" +#include "common/events.h" + +#include "cruise/cruise_main.h" +#include "cruise/cell.h" + +namespace Cruise { + +unsigned int timer = 0; + +void drawSolidBox(int32 x1, int32 y1, int32 x2, int32 y2, uint8 color) { + int32 i; + int32 j; + + for (i = x1; i < x2; i++) { + for (j = y1; j < y2; j++) { + globalScreen[j * 320 + i] = color; + } + } +} + +void drawBlackSolidBoxSmall() { +// gfxModuleData.drawSolidBox(64,100,256,117,0); + drawSolidBox(64, 100, 256, 117, 0); +} + +void resetRaster(uint8 *rasterPtr, int32 rasterSize) { + memset(rasterPtr, 0, rasterSize); +} + +void drawInfoStringSmallBlackBox(uint8 *string) { + //uint8 buffer[256]; + + gfxModuleData_field_90(); + gfxModuleData_gfxWaitVSync(); + drawBlackSolidBoxSmall(); + + drawString(10, 100, string, gfxModuleData.pPage10, video4, 300); + + gfxModuleData_flip(); + + flipScreen(); + + while (1); +} + +void loadPakedFileToMem(int fileIdx, uint8 *buffer) { + //changeCursor(1); + + currentVolumeFile.seek(volumePtrToFileDescriptor[fileIdx].offset, + SEEK_SET); + currentVolumeFile.read(buffer, + volumePtrToFileDescriptor[fileIdx].size); +} + +int loadScriptSub1(int scriptIdx, int param) { + objDataStruct *ptr2; + int counter; + int i; + + if (!overlayTable[scriptIdx].ovlData) + return (0); + + ptr2 = overlayTable[scriptIdx].ovlData->objDataTable; + + if (!ptr2) + return (0); + + if (overlayTable[scriptIdx].ovlData->numObjData == 0) + return (0); + + counter = 0; + + for (i = 0; i < overlayTable[scriptIdx].ovlData->numObjData; i++) { + if (ptr2[i].var0 == param) { + counter++; + } + } + + return (counter); +} + +void saveShort(void *ptr, short int var) { + *(int16 *) ptr = var; + + flipShort((int16 *) ptr); +} + +int16 loadShort(void *ptr) { + short int temp; + + temp = *(int16 *) ptr; + + flipShort(&temp); + + return (temp); +} + +void resetFileEntryRange(int param1, int param2) { + int i; + + for (i = param1; i < param2; i++) { + resetFileEntry(i); + } +} + +int getProcParam(int overlayIdx, int param2, uint8 *name) { + int numExport; + int i; + exportEntryStruct *exportDataPtr; + uint8 *exportNamePtr; + uint8 exportName[80]; + + if (!overlayTable[overlayIdx].alreadyLoaded) + return 0; + + if (!overlayTable[overlayIdx].ovlData) + return 0; + + numExport = overlayTable[overlayIdx].ovlData->numExport; + exportDataPtr = overlayTable[overlayIdx].ovlData->exportDataPtr; + exportNamePtr = overlayTable[overlayIdx].ovlData->exportNamesPtr; + + if (!exportNamePtr) + return 0; + + for (i = 0; i < numExport; i++) { + if (exportDataPtr[i].var4 == param2) { + strcpyuint8(exportName, + exportDataPtr[i].offsetToName + exportNamePtr); + + if (!strcmpuint8(exportName, name)) { + return (exportDataPtr[i].idx); + } + } + } + + return 0; +} + +void changeScriptParamInList(int param1, int param2, scriptInstanceStruct *pScriptInstance, int newValue, int param3) { + pScriptInstance = pScriptInstance->nextScriptPtr; + while (pScriptInstance) { + if ((pScriptInstance->overlayNumber == param1) || (param1 == -1)) + if ((pScriptInstance->scriptNumber == param2) || (param2 == -1)) + if ((pScriptInstance->freeze == param3) || (param3 == -1)) { + pScriptInstance->freeze = newValue; + } + + pScriptInstance = pScriptInstance->nextScriptPtr; + } +} + +void initBigVar3() { + int i; + + for (i = 0; i < 257; i++) { + if (filesDatabase[i].subData.ptr) { + free(filesDatabase[i].subData.ptr); + } + + filesDatabase[i].subData.ptr = NULL; + filesDatabase[i].subData.ptr2 = NULL; + + filesDatabase[i].subData.index = -1; + filesDatabase[i].subData.resourceType = 0; + } +} + +void resetPtr2(scriptInstanceStruct *ptr) { + ptr->nextScriptPtr = NULL; + ptr->scriptNumber = -1; +} + +void resetActorPtr(actorStruct *ptr) { + ptr->next = NULL; + ptr->prev = NULL; +} + +ovlData3Struct *getOvlData3Entry(int32 scriptNumber, int32 param) { + ovlDataStruct *ovlData = overlayTable[scriptNumber].ovlData; + + if (!ovlData) { + return NULL; + } + + if (param < 0) { + return NULL; + } + + if (ovlData->numScripts1 <= param) { + return NULL; + } + + if (!ovlData->data3Table) { + return NULL; + } + + return (&ovlData->data3Table[param]); +} + +ovlData3Struct *scriptFunc1Sub2(int32 scriptNumber, int32 param) { + ovlDataStruct *ovlData = overlayTable[scriptNumber].ovlData; + + if (!ovlData) { + return NULL; + } + + if (param < 0) { + return NULL; + } + + if (ovlData->numScripts2 <= param) { + return NULL; + } + + if (!ovlData->ptr1) { + return NULL; + } + + return ((ovlData3Struct *) (ovlData->ptr1 + param * 0x1C)); +} + +void scriptFunc2(int scriptNumber, scriptInstanceStruct * scriptHandle, + int param, int param2) { + if (scriptHandle->nextScriptPtr) { + if (scriptNumber == scriptHandle->nextScriptPtr->overlayNumber + || scriptNumber != -1) { + if (param2 == scriptHandle->nextScriptPtr->scriptNumber + || param2 != -1) { + scriptHandle->nextScriptPtr->sysKey = param; + } + } + } +} + +uint8 *getDataFromData3(ovlData3Struct *ptr, int param) { + uint8 *dataPtr; + + if (!ptr) + return (NULL); + + dataPtr = ptr->dataPtr; + + if (!dataPtr) + return (NULL); + + switch (param) { + case 0: + { + return (dataPtr); + } + case 1: + { + return (dataPtr + ptr->offsetToSubData3); // strings + } + case 2: + { + return (dataPtr + ptr->offsetToSubData2); + } + case 3: + { + return (dataPtr + ptr->offsetToImportData); // import data + } + case 4: + { + return (dataPtr + ptr->offsetToImportName); // import names + } + case 5: + { + return (dataPtr + ptr->offsetToSubData5); + } + default: + { + return (NULL); + } + } +} + +void printInfoBlackBox(const char *string) { +} + +void waitForPlayerInput() { +} + +void getFileExtention(const char *name, char *buffer) { + while (*name != '.' && *name) { + name++; + } + + strcpy(buffer, name); +} + +void removeExtention(const char *name, char *buffer) { // not like in original + char *ptr; + + strcpy(buffer, name); + + ptr = strchr(buffer, '.'); + + if (ptr) + *ptr = 0; +} + +int lastFileSize; + +int loadFileSub1(uint8 **ptr, uint8 *name, uint8 *ptr2) { + int i; + char buffer[256]; + int fileIdx; + int unpackedSize; + uint8 *unpackedBuffer; + + for (i = 0; i < 64; i++) { + if (mediumVar[i].ptr) { + if (!strcmpuint8(mediumVar[i].name, name)) { + printf("Unsupported code in loadFIleSub1 !\n"); + exit(1); + } + } + } + + getFileExtention((char *)name, buffer); + + if (!strcmp(buffer, ".SPL")) { + removeExtention((char *)name, buffer); + + // if(useH32) + { + strcatuint8(buffer, ".H32"); + } + /* else + * if(useAdlib) + * { + * strcatuint8(buffer,".ADL"); + * } + * else + * { + * strcatuint8(buffer,".HP"); + * } */ + } else { + strcpyuint8(buffer, name); + } + + fileIdx = findFileInDisks((uint8 *) buffer); + + if (fileIdx < 0) + return (-18); + + unpackedSize = loadFileVar1 = + volumePtrToFileDescriptor[fileIdx].extSize + 2; + + // TODO: here, can unpack in gfx module buffer + unpackedBuffer = (uint8 *) mallocAndZero(unpackedSize); + + if (!unpackedBuffer) { + return (-2); + } + + lastFileSize = unpackedSize; + + if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) { + uint8 *pakedBuffer = + (uint8 *) mallocAndZero(volumePtrToFileDescriptor[fileIdx]. + size + 2); + + loadPakedFileToMem(fileIdx, pakedBuffer); + + uint32 realUnpackedSize = READ_BE_UINT32(pakedBuffer + volumePtrToFileDescriptor[fileIdx].size - 4); + + lastFileSize = realUnpackedSize; + + delphineUnpack(unpackedBuffer, pakedBuffer, volumePtrToFileDescriptor[fileIdx].size); + + free(pakedBuffer); + } else { + loadPakedFileToMem(fileIdx, unpackedBuffer); + } + + *ptr = unpackedBuffer; + + return (1); +} + +void resetFileEntry(int32 entryNumber) { + if (entryNumber >= 257) + return; + + if (!filesDatabase[entryNumber].subData.ptr) + return; + + free(filesDatabase[entryNumber].subData.ptr); + + filesDatabase[entryNumber].subData.ptr = NULL; + filesDatabase[entryNumber].subData.ptr2 = NULL; + filesDatabase[entryNumber].widthInColumn = 0; + filesDatabase[entryNumber].width = 0; + filesDatabase[entryNumber].resType = 0; + filesDatabase[entryNumber].height = 0; + filesDatabase[entryNumber].subData.index = -1; + filesDatabase[entryNumber].subData.resourceType = 0; + filesDatabase[entryNumber].subData.field_1C = 0; + filesDatabase[entryNumber].subData.name[0] = 0; + +} + +uint8 *mainProc14(uint16 overlay, uint16 idx) { + ASSERT(0); + + return NULL; +} + +int initAllData(void) { + int i; + + setupFuncArray(); + setupOpcodeTable(); + initOverlayTable(); + + setup1 = 0; + currentActiveBackgroundPlane = 0; + + freeDisk(); + + initVar5[0] = -1; + initVar5[3] = -1; + initVar5[6] = -1; + initVar5[9] = -1; + + menuTable[0] = NULL; + + for (i = 0; i < 2000; i++) { + globalVars[i] = 0; + } + + for (i = 0; i < 8; i++) { + backgroundTable[i].name[0] = 0; + } + + for (i = 0; i < 257; i++) { + filesDatabase[i].subData.ptr = NULL; + filesDatabase[i].subData.ptr2 = NULL; + } + + initBigVar3(); + + resetPtr2(&procHead); + resetPtr2(&relHead); + + resetPtr(&cellHead); + + resetActorPtr(&actorHead); + resetBackgroundIncrustList(&backgroundIncrustHead); + + bootOverlayNumber = loadOverlay((uint8 *) "AUTO00"); + +#ifdef DUMP_SCRIPT + loadOverlay("TITRE"); + loadOverlay("TOM"); + loadOverlay("XX2"); + loadOverlay("SUPER"); + loadOverlay("BEBE1"); + loadOverlay("BIBLIO"); + loadOverlay("BRACAGE"); + loadOverlay("CONVERS"); + loadOverlay("DAF"); + loadOverlay("DAPHNEE"); + loadOverlay("DESIRE"); + loadOverlay("FAB"); + loadOverlay("FABIANI"); + loadOverlay("FIN"); + loadOverlay("FIN01"); + loadOverlay("FINBRAC"); + loadOverlay("GEN"); + loadOverlay("GENDEB"); + loadOverlay("GIFLE"); + loadOverlay("HECTOR"); + loadOverlay("HECTOR2"); + loadOverlay("I00"); + loadOverlay("I01"); + loadOverlay("I04"); + loadOverlay("I06"); + loadOverlay("I07"); + loadOverlay("INVENT"); + loadOverlay("JULIO"); + loadOverlay("LOGO"); + loadOverlay("MANOIR"); + loadOverlay("MISSEL"); + loadOverlay("POKER"); + loadOverlay("PROJ"); + loadOverlay("REB"); + loadOverlay("REBECCA"); + loadOverlay("ROS"); + loadOverlay("ROSE"); + loadOverlay("S01"); + loadOverlay("S02"); + loadOverlay("S03"); + loadOverlay("S04"); + loadOverlay("S06"); + loadOverlay("S07"); + loadOverlay("S08"); + loadOverlay("S09"); + loadOverlay("S10"); + loadOverlay("S103"); + loadOverlay("S11"); + loadOverlay("S113"); + loadOverlay("S12"); + loadOverlay("S129"); + loadOverlay("S131"); + loadOverlay("S132"); + loadOverlay("S133"); + loadOverlay("int16"); + loadOverlay("S17"); + loadOverlay("S18"); + loadOverlay("S19"); + loadOverlay("S20"); + loadOverlay("S21"); + loadOverlay("S22"); + loadOverlay("S23"); + loadOverlay("S24"); + loadOverlay("S25"); + loadOverlay("S26"); + loadOverlay("S27"); + loadOverlay("S29"); + loadOverlay("S30"); + loadOverlay("S31"); + loadOverlay("int32"); + loadOverlay("S33"); + loadOverlay("S33B"); + loadOverlay("S34"); + loadOverlay("S35"); + loadOverlay("S36"); + loadOverlay("S37"); + loadOverlay("SHIP"); + loadOverlay("SUPER"); + loadOverlay("SUZAN"); + loadOverlay("SUZAN2"); + loadOverlay("TESTA1"); + loadOverlay("TESTA2"); + //exit(1); +#endif + + if (bootOverlayNumber) { + positionInStack = 0; + + attacheNewScriptToTail(bootOverlayNumber, &procHead, 0, 20, 0, 0, scriptType_PROC); + scriptFunc2(bootOverlayNumber, &procHead, 1, 0); + } + + strcpyuint8(systemStrings.bootScriptName, "AUTO00"); + + return (bootOverlayNumber); +} + +int removeFinishedScripts(scriptInstanceStruct *ptrHandle) { + scriptInstanceStruct *ptr = ptrHandle->nextScriptPtr; // can't destruct the head + scriptInstanceStruct *oldPtr = ptrHandle; + + if (!ptr) + return (0); + + do { + if (ptr->scriptNumber == -1) { + oldPtr->nextScriptPtr = ptr->nextScriptPtr; + + if (ptr->var6 && ptr->varA) { + // free(ptr->var6); + } + + free(ptr); + + ptr = oldPtr->nextScriptPtr; + } else { + oldPtr = ptr; + ptr = ptr->nextScriptPtr; + } + } while (ptr); + + return (0); +} + +int nePasAffichierMenuDialogue; +int var37 = 0; +int var38 = 0; + +int getCursorFromObject(int mouseX, int mouseY, int *outX, int *outY) { + int16 var_2; + int16 var_4; + int16 var_14; + int16 var_16; + objectParamsQuery params; + int16 var_10; + int16 var_E; + int16 var_C; +// int16 var_42; + int16 var_A; + int16 var_6; + + char objectName[80]; + + cellStruct *currentObject = cellHead.prev; + + while (currentObject) { + if (currentObject->overlay >= 0) { + if (overlayTable[currentObject->overlay].alreadyLoaded) { + if (currentObject->type == 4 + || currentObject->type == 1 + || currentObject->type == 9 + || currentObject->type == 3) { + strcpy(objectName, + getObjectName(currentObject->idx, + overlayTable[currentObject-> + overlay].ovlData-> + specialString2)); + + if (strlen(objectName)) { + if (currentObject->freeze == 0) { + var_2 = + currentObject->idx; + var_4 = + currentObject-> + overlay; + var_14 = + currentObject-> + followObjectIdx; + var_16 = + currentObject-> + followObjectOverlayIdx; + + getMultipleObjectParam + (currentObject-> + overlay, + currentObject->idx, + ¶ms); + + var_10 = 0; + var_E = 0; + var_C = 0; + + if ((var_4 != var_16) + && (var_2 != + var_14)) { + getMultipleObjectParam + (var_16, + var_14, + ¶ms); + + var_C = + params.X; + var_E = + params.Y; + var_10 = + params. + fileIdx; + } + + if (params.var5 >= 0 + && params. + fileIdx >= 0) { + if (currentObject->type == 3) { + assert + (0); + + var_2 = + params. + scale; + var_A = + params. + X + + var_C; + + // TODO: this var3 is stupid, investigate... + if ((var_A <= mouseX) && (var_A + params.fileIdx >= mouseX) && (mouseY >= params.Y + var_E) && (params.Y + var_E + var2 >= mouseY)) { + *outX + = + var_16; + *outY + = + var_14; + + return + (currentObject-> + type); + } + } else + if + (currentObject-> + type == 4 + || + currentObject-> + type == 1 + || + currentObject-> + type == + 9) { + int si; + int var_8; + int di; + + var_A = + params. + X + + var_C; + var_6 = + params. + Y + + var_E; + + di = params.fileIdx; + + if (di + < + 0) + { + di += var_10; + } + +/* if((filesDatabase[di].subData.resourceType == 8) && (filesDatabase[di].subData.ptr)) + { + assert(0); + } + else */ + { + var_4 + = + filesDatabase + [di]. + resType; + + if (var_4 == 1) { + var_C + = + filesDatabase + [di]. + widthInColumn + / + 2; + } else { + var_C + = + filesDatabase + [di]. + width; + } + + var_8 + = + filesDatabase + [di]. + height; + + var_2 + = + mouseX + - + var_A; + si = mouseY - var_6; + + if (var_2 > 0) { + if (var_C > var_2) { + if (si > 0) { + if (var_8 >= si) { + if (filesDatabase[di].subData.ptr) { + if (var_4 == 1) { + } else { + } + + printf + ("should compare to mask in getCursorFromObject...\n"); + + *outX + = + var_16; + *outY + = + var_14; + + printf + ("Selected: %s\n", + objectName); + + return + currentObject-> + type; + } + } + } + } + } + } + } + } + } + } + } + } + } + + currentObject = currentObject->prev; + } + + *outX = 0; + *outY = 0; + + return -1; +} + +char keyboardVar = 0; + +void freeStuff2(void) { + printf("implement freeStuff2\n"); +} + +void *allocAndZero(int size) { + void *ptr; + + ptr = malloc(size); + memset(ptr, 0, size); + + return ptr; +} + +char *getObjectName(int index, uint8 *string) { + int i; + char *ptr = (char *)string; + + if (!string) + return NULL; + + for (i = 0; i < index; i++) { + while (*ptr) { + ptr++; + } + ptr++; + } + return ptr; +} + +int buildInventorySub1(int overlayIdx, int objIdx) { + objDataStruct *pObjectData = + getObjectDataFromOverlay(overlayIdx, objIdx); + + if (pObjectData) { + return pObjectData->type; + } else { + return -11; + } +} + +void buildInventory(int X, int Y) { + int numObjectInInventory = 0; + menuStruct *pMenu; + + pMenu = createMenu(X, Y, "Inventaire"); + + menuTable[1] = pMenu; + + if (pMenu) { + numObjectInInventory = 0; + + if (numOfLoadedOverlay > 1) { + int i; + + for (i = 1; i < numOfLoadedOverlay; i++) { + ovlDataStruct *pOvlData = + overlayTable[i].ovlData; + + if (pOvlData && pOvlData->objDataTable) { + int var_2; + + var_2 = 0; + + if (pOvlData->numObjData) { + int j; + + for (j = 0; + j < pOvlData->numObjData; + j++) { + if (buildInventorySub1 + (i, j) != 3) { + int16 + returnVar; + + getSingleObjectParam + (i, j, 5, + &returnVar); + + if (returnVar < + -1) { + addSelectableMenuEntry + (i, + j, + pMenu, + 1, + -1, + getObjectName + (j, pOvlData->specialString2)); + numObjectInInventory++; + } + } + } + } + } + } + } + } + + if (numObjectInInventory == 0) { + freeMenu(menuTable[1]); + menuTable[1] = NULL; + } +} + +int currentMenuElementX; +int currentMenuElementY; +menuElementStruct *currentMenuElement; + +menuElementSubStruct *getSelectedEntryInMenu(menuStruct *pMenu) { + menuElementStruct *pMenuElement; + + if (pMenu == NULL) { + return NULL; + } + + if (pMenu->numElements == 0) { + return NULL; + } + + pMenuElement = pMenu->ptrNextElement; + + while (pMenuElement) { + if (pMenuElement->varC) { + currentMenuElementX = pMenuElement->x; + currentMenuElementY = pMenuElement->y; + currentMenuElement = pMenuElement; + + return pMenuElement->ptrSub; + } + + pMenuElement = pMenuElement->next; + } + + return NULL; +} + +int callInventoryObject(int param0, int param1, int x, int y) { + int var_2C; + int var_30; + int var_28; + int var_1E; + int16 returnVar; + + var_30 = -1; + + getSingleObjectParam(param0, param1, 5, &returnVar); + + var_2C = 0; + var_28 = 1; + + for (var_1E = 1; var_1E < numOfLoadedOverlay; var_1E++) { + ovlDataStruct *var_2A = overlayTable[var_1E].ovlData; + if (var_2A->ptr1) { + int var_18; + int var_14; + + var_18 = var_2A->numLinkData; + + if (var_18) { + int var_16; + + var_16 = 0; + + for (var_14 = 0; var_14 < var_18; var_14++) { + objDataStruct *pObject; + linkDataStruct *var_34; + int var_2; + + var_34 = &var_2A->linkDataPtr[var_14]; + + var_2 = var_34->stringIdx; + + if (!var_2) { + var_2 = var_1E; + } + + pObject = + getObjectDataFromOverlay(var_2, + var_34->stringNameOffset); + + if (var_2 == param0) { + if (param1 == + var_34->stringNameOffset) { + if (pObject) { + if (pObject-> + type != + 3) { + char var_214[80]; + char var_1C4[80]; + char var_174[80]; + char var_124[80]; + char var_D4[80]; + char var_84[80]; + + ovlDataStruct + *var_12; + ovlDataStruct + *var_22; + + int var_E = var_34->varIdx; + int cx + = + var_34-> + stringIdx; + int var_C = var_34->procIdx; + + int di + = + var_E; + if (var_E == 0) + di = var_1E; + + var_2 = + cx; + if (cx + == + 0) + var_2 + = + var_1E; + + if (var_C == 0) + var_C + = + var_1E; + + var_12 + = + NULL; + var_22 + = + NULL; + + var_214 + [0] + = + 0; + var_1C4 + [0] + = + 0; + var_174 + [0] + = + 0; + var_124 + [0] + = + 0; + var_D4 + [0] + = + 0; + var_84 + [0] + = + 0; + + if (di + > + 0) + { + var_22 + = + overlayTable + [di]. + ovlData; + } + + if (var_2 > 0) { + var_12 + = + overlayTable + [var_2]. + ovlData; + } + + if (var_12) { + if (var_34->stringNameOffset) { + var_30 + = + var_34-> + field_1A; + if (var_28) { + if (var_12->specialString2) { + if (var_30 == -1 || var_30 == returnVar) { + char *ptrName = getObjectName(var_34->stringNameOffset, var_12->specialString2); + + menuTable + [0] + = + createMenu + (x, + y, + ptrName); + var_28 + = + 0; + } + } + } + } + } + + if (var_22) { + if (true /*var_34->varNameOffset>=0 */ ) // FIXME: This check is always true since varNameOffset is unsigned + { + if (var_22->specialString1) { + char *ptr = getObjectName(var_34->varNameOffset, var_22->specialString1); + + strcpy + (var_214, + ptr); + + if (var_28 == 0) { + if (var_30 == -1 || var_30 == returnVar) { + if (strlen(var_214)) { + attacheNewScriptToTail + (var_1E, + &relHead, + var_34-> + field_2, + 30, + currentScriptPtr-> + scriptNumber, + currentScriptPtr-> + overlayNumber, + scriptType_REL); + } else { + if (var_22->specialString1) { + ptr = getObjectName(var_34->varNameOffset, var_22->specialString1); + + var_2C + = + 1; + + addSelectableMenuEntry + (var_1E, + var_14, + menuTable + [0], + 1, + -1, + ptr); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + return var_2C; +} + +int processInventory(void) { + if (menuTable[1]) { + menuElementSubStruct *pMenuElementSub = + getSelectedEntryInMenu(menuTable[1]); + + if (pMenuElementSub) { + //int var2; + //int var4; + + var2 = pMenuElementSub->var2; + var4 = pMenuElementSub->var4; + + freeMenu(menuTable[1]); + menuTable[1] = NULL; + + callInventoryObject(var2, var4, + currentMenuElementX + 80, currentMenuElementY); + + return 1; + } else { + freeMenu(menuTable[1]); + menuTable[1] = NULL; + } + } + + return 0; +} + +int processInput(void) { + menuStruct *var_5C; + + int16 mouseX = 0; + int16 mouseY = 0; + int16 button = 0; + + /*if(inputSub1keyboad()) + * { + * return 1; + * } */ + + button = 0; + + if (sysKey != -1) { + button = sysKey; + mouseX = var11; + mouseY = var12; + sysKey = -1; + } else { + if (automaticMode == 0) { + getMouseStatus(&main10, &mouseX, &button, &mouseY); + } + } + + if (button) { + nePasAffichierMenuDialogue = 0; + } + + if (userDelay) { + userDelay--; + return 0; + } + // test both buttons + + if (((button & 3) == 3) || keyboardVar == 0x44 || keyboardVar == 0x53) { + changeCursor(0); + keyboardVar = 0; + return (playerMenu(mouseX, mouseY)); + } + + if (!userEnabled) { + return 0; + } + + if (currentActiveMenu != -1) { + var_5C = menuTable[currentActiveMenu]; + + if (var_5C) { + updateMenuMouse(mouseX, mouseY, var_5C); + } + } + + if (var6) { + ASSERT(0); + } + + if (button & 1) { + if (nePasAffichierMenuDialogue == 0) { + nePasAffichierMenuDialogue = 1; + + if (mouseVar1) { + ASSERT(0); + } + + if (var38 == 0) // are we in inventory mode ? + { + if (menuTable[0] == 0) { + int X; + int Y; + int objIdx; + + objIdx = + getCursorFromObject(mouseX, mouseY, + &X, &Y); + + if (objIdx != -1) { + //ASSERT(0); + //moveActor(X,Y,mouseVar1); + } else { + var34 = mouseX; + var35 = mouseY; + animationStart = true; + var38 = 0; + } + } + //ASSERT(0); + } else { + if (processInventory()) { + var37 = 1; + currentActiveMenu = 0; + var38 = 0; + } else { + currentActiveMenu = -1; + var38 = 0; + } + + return 0; + } + + //ASSERT(0); + } + } + + if ((button & 2) || (keyboardVar == 0x43) || (keyboardVar == 0x52)) { + if (nePasAffichierMenuDialogue == 0) { + keyboardVar = 0; + + if ((mouseVar1 == 0) && (menuTable[0])) { + ASSERT(0); + freeMenu(menuTable[0]); + menuTable[0] = NULL; + var37 = 0; + var38 = 0; + currentActiveMenu = -1; + } + + if (var37 || var38 || menuTable[1]) { + nePasAffichierMenuDialogue = 1; + return 0; + } + + buildInventory(mouseX, mouseY); + + if (menuTable[1]) { + currentActiveMenu = 1; + var38 = 1; + } else { + var38 = 1; + } + + nePasAffichierMenuDialogue = 1; + return 0; + } + } + return 0; +} + +int oldMouseX; +int oldMouseY; + +void manageEvents(int count) { + Common::Event event; + + Common::EventManager * eventMan = g_system->getEventManager(); + while (eventMan->pollEvent(event)) { + switch (event.type) { + /* case Common::EVENT_LBUTTONDOWN: + * mouseLeft = 1; + * break; + * case Common::EVENT_RBUTTONDOWN: + * mouseRight = 1; + * break; + * case Common::EVENT_MOUSEMOVE: + * break; */ + case Common::EVENT_QUIT: + g_system->quit(); + break; + /* case Common::EVENT_KEYDOWN: + * switch (event.kbd.keycode) { + * case '\n': + * case '\r': + * case 261: // Keypad 5 + * if (allowPlayerInput) { + * mouseLeft = 1; + * } + * break; + * case 27: // ESC + * if (allowPlayerInput) { + * mouseRight = 1; + * } + * break; + * case 282: // F1 + * if (allowPlayerInput) { + * playerCommand = 0; // EXAMINE + * makeCommandLine(); + * } + * break; + * case 283: // F2 + * if (allowPlayerInput) { + * playerCommand = 1; // TAKE + * makeCommandLine(); + * } + * break; + * case 284: // F3 + * if (allowPlayerInput) { + * playerCommand = 2; // INVENTORY + * makeCommandLine(); + * } + * break; + * case 285: // F4 + * if (allowPlayerInput) { + * playerCommand = 3; // USE + * makeCommandLine(); + * } + * break; + * case 286: // F5 + * if (allowPlayerInput) { + * playerCommand = 4; // ACTIVATE + * makeCommandLine(); + * } + * break; + * case 287: // F6 + * if (allowPlayerInput) { + * playerCommand = 5; // SPEAK + * makeCommandLine(); + * } + * break; + * case 290: // F9 + * if (allowPlayerInput && !inMenu) { + * makeActionMenu(); + * makeCommandLine(); + * } + * break; + * case 291: // F10 + * if (!disableSystemMenu && !inMenu) { + * g_cine->makeSystemMenu(); + * } + * break; + * default: + * //lastKeyStroke = event.kbd.keycode; + * break; + * } + * break; */ + default: + break; + } + } + + /*if (count) { + * mouseData.left = mouseLeft; + * mouseData.right = mouseRight; + * mouseLeft = 0; + * mouseRight = 0; + * } + */ + int i; + + for (i = 0; i < count; i++) { + //FIXME(?): Maybe there's a better way to "fix" this? + // + //Since not all backends/ports can update the screen + //100 times per second, only update the screen every + //other frame (1000 / 2 * 10 i.e. 50 times per second max.) + if (i % 2) + g_system->updateScreen(); + g_system->delayMillis(10); + manageEvents(0); + } +} + +void mainLoop(void) { +#define SPEED 40 /* Ticks per Frame */ +#define SLEEP_MIN 20 /* Minimum time a sleep takes, usually 2*GRAN */ +#define SLEEP_GRAN 1 /* Granularity of sleep */ + + int frames = 0; /* Number of frames displayed */ + //int32 t_start,t_left; + //uint32 t_end; + //int32 q=0; /* Dummy */ + + int enableUser = 0; + //int16 mouseX; + //int16 mouseY; + //int16 mouseButton; + + scriptNameBuffer[0] = 0; + systemStrings.bootScriptName[0] = 0; + initVar4[0] = 0; + currentActiveMenu = -1; + main14 = -1; + mouseVar1 = 0; + main21 = 0; + main22 = 0; + main7 = 0; + main8 = 0; + main15 = 0; + + if (initAllData()) { + int playerDontAskQuit = 1; + int quitValue2 = 1; + int quitValue = 0; + + do { + frames++; +// t_start=Osystem_GetTicks(); + +// readKeyboard(); + playerDontAskQuit = processInput(); + + //if(enableUser) + { + userEnabled = 1; + enableUser = 0; + } + + manageScripts(&relHead); + manageScripts(&procHead); + + removeFinishedScripts(&relHead); + removeFinishedScripts(&procHead); + + processAnimation(); + + if (var0) { + // ASSERT(0); + /* main3 = 0; + * var24 = 0; + * var23 = 0; + * + * freeStuff2(); */ + } + + if (initVar4[0]) { + ASSERT(0); +/* redrawStrings(0,&initVar4,8); + + waitForPlayerInput(); + + initVar4 = 0; */ + } + + if (affichePasMenuJoueur) { + if (main5) + fadeVar = 0; + + /*if(fadeVar) + * { + * // TODO! + * } */ + + mainDraw(0); + flipScreen(); + + /* if(userEnabled && !main7 && !main15 && currentActiveMenu == -1) + * { + * getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY); + * + * if(mouseX != oldMouseX && mouseY != oldMouseY) + * { + * int cursorType; + * int newCursor1; + * int newCursor2; + * + * oldMouseX = mouseX; + * oldMouseY = mouseY; + * + * cursorType = getCursorFromObject(mouseX, mouseY, &newCursor1, &newCursor2); + * + * if(cursorType == 9) + * { + * changeCursor(5); + * } + * else + * if(cursorType == -1) + * { + * changeCursor(6); + * } + * else + * { + * changeCursor(4); + * } + * + * } + * } + * else */ + { + changeCursor(0); + } + + if (main7) { + ASSERT(0); + } + + if (main15) { + ASSERT(0); + } + + if (main14 != -1) { + ASSERT(0); + } + } + // t_end = t_start+SPEED; +// t_left=t_start-Osystem_GetTicks()+SPEED; +#ifndef FASTDEBUG + /* if(t_left>0) + * if(t_left>SLEEP_MIN) + * Osystem_Delay(t_left-SLEEP_GRAN); + * while(Osystem_GetTicks()<t_end){q++;}; */ +#endif + manageEvents(4); + + } while (!playerDontAskQuit && quitValue2 && quitValue != 7); + } + +} + +int oldmain(int argc, char *argv[]) { + printf("Cruise for a corpse recode\n"); + +// OSystemInit(); +// osystem = new OSystem; + + printf("Osystem Initialized\n"); + + printf("Initializing engine...\n"); + +// initBuffer(scaledScreen,640,400); + + fadeVar = 0; + + //lowLevelInit(); + + // arg parser stuff + + ptr_something = + (ctpVar19Struct *) mallocAndZero(sizeof(ctpVar19Struct) * 0x200); + + /*volVar1 = 0; + * fileData1 = 0; */ + + /*PAL_fileHandle = -1; */ + + // video init stuff + + loadSystemFont(); + + // another bit of video init + + if (!readVolCnf()) { + printf("Fatal: unable to load vol.cnf !\n"); + return (-1); + } + + printf("Entering main loop...\n"); + mainLoop(); + + //freeStuff(); + + //freePtr(ptr_something); + + return (0); +} + +void changeCursor(uint16 cursorType) { + //printf("changeCursor %d\n", cursorType); +} + +void *mallocAndZero(int32 size) { + void *ptr; + + ptr = malloc(size); + memset(ptr, 0, size); + return ptr; +} + +} // End of namespace Cruise diff --git a/engines/cruise/cruise_main.h b/engines/cruise/cruise_main.h new file mode 100644 index 0000000000..a36d8a066e --- /dev/null +++ b/engines/cruise/cruise_main.h @@ -0,0 +1,102 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_CRUISE_MAIN_H +#define CRUISE_CRUISE_MAIN_H + +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +#include "common/stdafx.h" +#include "common/scummsys.h" + +#include "cruise/overlay.h" +#include "cruise/object.h" +#include "cruise/ctp.h" +#include "cruise/actor.h" +#include "cruise/vars.h" +#include "cruise/font.h" +#include "cruise/volume.h" +#include "cruise/fontCharacterTable.h" +#include "cruise/stack.h" +#include "cruise/script.h" +#include "cruise/various.h" +#include "cruise/stringSupport.h" +#include "cruise/function.h" +#include "cruise/saveload.h" +#include "cruise/linker.h" +#include "cruise/mouse.h" +#include "cruise/gfxModule.h" +#include "cruise/dataLoader.h" +#include "cruise/perso.h" +#include "cruise/menu.h" + +#include "cruise/background.h" +#include "cruise/backgroundIncrust.h" + +#include "cruise/mainDraw.h" + +namespace Cruise { + +/*#define DUMP_SCRIPT +#define DUMP_OBJECT*/ + +#define ASSERT_PTR assert +#define ASSERT assert + +bool delphineUnpack(byte *dst, const byte *src, int len); + +ovlData3Struct *getOvlData3Entry(int32 scriptNumber, int32 param); +ovlData3Struct *scriptFunc1Sub2(int32 scriptNumber, int32 param); +int16 loadShort(void *ptr); +void resetFileEntry(int32 entryNumber); +void saveShort(void *ptr, int16 var); +void *mallocAndZero(int32 size); +uint8 *mainProc14(uint16 overlay, uint16 idx); +void printInfoBlackBox(const char *string); +void waitForPlayerInput(void); +int loadCtp(uint8 * ctpName); +void loadPakedFileToMem(int fileIdx, uint8 * buffer); +int loadScriptSub1(int scriptIdx, int param); +void resetFileEntryRange(int param1, int param2); +int getProcParam(int overlayIdx, int param2, uint8 * name); +void changeScriptParamInList(int param1, int param2, + scriptInstanceStruct * pScriptInstance, int newValue, int param3); +uint8 *getDataFromData3(ovlData3Struct * ptr, int param); +int32 prepareWordRender(int32 param, int32 var1, int16 * out2, uint8 * ptr3, + uint8 * string); +void removeExtention(const char *name, char *buffer); +void resetRaster(uint8 * rasterPtr, int32 rasterSize); +void changeCursor(uint16 cursorType); +void resetPtr2(scriptInstanceStruct * ptr); +void getFileExtention(const char *name, char *buffer); +void *allocAndZero(int size); +void freeStuff2(void); +char *getObjectName(int index, uint8 * string); +void mainLoop(void); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/ctp.cpp b/engines/cruise/ctp.cpp new file mode 100644 index 0000000000..a3acbef944 --- /dev/null +++ b/engines/cruise/ctp.cpp @@ -0,0 +1,412 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" +#include "common/util.h" + +namespace Cruise { + +ctpVar19Struct *ptr_something; +ctpVar19Struct *polyStruct; +ctpVar19Struct *ctpVar11; +ctpVar19Struct *ctpVar13; +ctpVar19Struct *ctpVar15; + +uint8 *ctpVar17; +ctpVar19Struct *ctpVar19; + +int currentWalkBoxCenterX; +int currentWalkBoxCenterY; +int currentWalkBoxCenterXBis; +int currentWalkBoxCenterYBis; + +int ctpVarUnk; +uint8 walkboxTable[0x12]; + +int ctpProc2(int varX, int varY, int paramX, int paramY) { + int diffX = ABS(paramX - varX); + int diffY = ABS(paramY - varY); + + if (diffX > diffY) { + diffY = diffX; + } + + ctpVar14 = diffY; // highest difference + return (diffY); +} + +// this function process path finding coordinates +void loadCtpSub2(short int coordCount, short int *ptr) { +// coordCount = ctp_routeCoordCount, ptr = ctpVar8 + int i; + int offset = 0; + + short int *cur_ctp_routeCoords = (short int *)ctp_routeCoords; // coordinates table + int8 *cur_ctp_routes = (int8 *) ctp_routes; + + for (i = 0; i < coordCount; i++) // for i < ctp_routeCoordCount + { + int varX = cur_ctp_routeCoords[0]; // x + int varY = cur_ctp_routeCoords[1]; // y + + int di = 0; + int var4Offset = 2; + + while (*(int16 *) cur_ctp_routes > di) // while (coordCount > counter++) + { + int idx = *(int16 *) (cur_ctp_routes + var4Offset); + ptr[offset + idx] = + ctpProc2(varX, varY, ctp_routeCoords[idx][0], + ctp_routeCoords[idx * 2][1]); + + var4Offset += 2; + di++; + } + + offset += 10; + cur_ctp_routes += 20; + cur_ctp_routeCoords += 2; + } +} + +void getWalkBoxCenter(int boxIdx, uint16 *_walkboxTable) { + int minX = 1000; + int minY = 1000; + int maxX = -1; + int maxY = -1; + + ASSERT(boxIdx <= 15); // max number of walkboxes is 16 + ASSERT(_walkboxTable[boxIdx * 40]); // we should never have an empty walk box + + if (_walkboxTable[boxIdx * 40] > 0) { + int numPoints = _walkboxTable[boxIdx * 40]; + uint16 *pCurrentPtr = _walkboxTable + (boxIdx * 40) + 1; + + int i; + + for (i = 0; i < numPoints; i++) { + int X = *(pCurrentPtr++); + int Y = *(pCurrentPtr++);; + + if (X < minX) + minX = X; + + if (X > maxX) + maxX = X; + + if (Y < minY) + minY = Y; + + if (Y > maxY) + maxY = Y; + } + } + + currentWalkBoxCenterX = ((maxX - minX) / 2) + minX; + currentWalkBoxCenterY = ((maxY - minY) / 2) + minY; +} + +// ax dx bx +void renderCTPWalkBox(int X1, int Y1, int X2, int scale, int Y2, + uint16 *walkboxData) { + int numPoints; + int wbSelf1; + int wbSelf2; + int i; + int16 *destination; + + wbSelf1 = upscaleValue(X1, scale) - X2; + wbSelf2 = upscaleValue(Y1, scale) - Y2; + + numPoints = *(walkboxData++); + + destination = polyBuffer2; + + for (i = 0; i < numPoints; i++) { + int pointX = *(walkboxData++); + int pointY = *(walkboxData++); + + int scaledX = upscaleValue(pointX, scale) - wbSelf1; + int scaledY = upscaleValue(pointY, scale) - wbSelf2; + + *(destination++) = scaledX >> 16; + *(destination++) = scaledY >> 16; + } + + m_color = 0; + ctpVarUnk = 0; + + for (i = 0; i < numPoints; i++) { + walkboxTable[i] = i; + } + + drawPolyMode2((char *)walkboxTable, numPoints); +} + +// this process the walkboxes +void loadCtpSub1(int boxIdx, int scale, uint16 *_walkboxTable, + ctpVar19Struct *param4) { + int minX = 1000; + int minY = 1000; + int maxX = -1; + int maxY = -1; + + ctpVar19Struct *var_1C; + ctpVar19Struct *var_12; + int16 *var_18; + int16 *si; + // int16* di; + // uint8* cx; + // int bx; + // int ax; + // int var_2; + int var_E; + //int var_C = 1000; + //int var_A = 0; + ctpVar19SubStruct *subStruct; + + ASSERT(boxIdx <= 15); + + if (_walkboxTable[boxIdx * 40] > 0) // is walkbox used ? + { + getWalkBoxCenter(boxIdx, _walkboxTable); + + currentWalkBoxCenterYBis = currentWalkBoxCenterY; + currentWalkBoxCenterXBis = currentWalkBoxCenterX; + // + 512 + renderCTPWalkBox(currentWalkBoxCenterX, currentWalkBoxCenterY, + currentWalkBoxCenterX, scale + 0x200, + currentWalkBoxCenterY, _walkboxTable + boxIdx * 40); + + var_1C = param4; + var_12 = var_1C + 1; // next + + var_18 = polyBuffer3; + var_E = 0; + + si = &polyBuffer3[1]; + /* if(*si>=0) + * { + * di = si; + * cx = var_12; + * + * do + * { + * di++; + * bx = di[-1]; + * ax = di[0]; + * di++; + * + * var_2 = ax; + * if(var_C < bx) + * { + * var_C = bx; + * } + * + * if(var_2 < var_A) + * { + * var_A = var_2; + * } + * + * *cx = bx; + * cx++; + * *cx = var_2; + * cx++; + * var_E ++; + * }while(di); + * + * var_12 = cx; + * } */ + + /*************/ + { + int i; + int numPoints; + uint16 *pCurrentPtr = _walkboxTable + boxIdx * 40; + + numPoints = *(pCurrentPtr++); + + for (i = 0; i < numPoints; i++) { + int X = *(pCurrentPtr++); + int Y = *(pCurrentPtr++); + + if (X < minX) + minX = X; + + if (X > maxX) + maxX = X; + + if (Y < minY) + minY = Y; + + if (Y > maxY) + maxY = Y; + } + } + /************/ + + var_1C->field_0 = var_12; + ctpVar13 = var_12; + var_12->field_0 = (ctpVar19Struct *) (-1); + + subStruct = &var_1C->subStruct; + + subStruct->boxIdx = boxIdx; + subStruct->type = walkboxType[boxIdx]; + subStruct->minX = minX; + subStruct->maxX = maxX; + subStruct->minY = minY; + subStruct->maxY = maxY; + } +} + +int loadCtp(uint8 *ctpName) { + int walkboxCounter; // si + uint8 *ptr; + uint8 *dataPointer; // ptr2 + char fileType[5]; // string2 + short int segementSizeTable[7]; // tempTable + char string[32]; + + if (ctpVar1 == 0) { + int i; + + for (i = 0; i < 10; i++) { + persoTable[i] = NULL; + } + } + + if (!loadFileSub1(&ptr, ctpName, 0)) { + free(ptr); + return (-18); + } + + dataPointer = ptr; + + fileType[4] = 0; + memcpy(fileType, dataPointer, 4); // get the file type, first 4 bytes of the CTP file + dataPointer += 4; + + if (strcmp(fileType, "CTP ")) { + free(ptr); + return (0); + } + + memcpy(&ctp_routeCoordCount, dataPointer, 2); // get the number of path-finding coordinates + dataPointer += 2; + flipShort(&ctp_routeCoordCount); + + memcpy(segementSizeTable, dataPointer, 0xE); + dataPointer += 0xE; // + 14 + flipGen(segementSizeTable, 0xE); + + memcpy(ctp_routeCoords, dataPointer, segementSizeTable[0]); // get the path-finding coordinates + dataPointer += segementSizeTable[0]; + flipGen(ctp_routeCoords, segementSizeTable[0]); + + memcpy(ctp_routes, dataPointer, segementSizeTable[1]); // get the path-finding line informations (indexing the routeCoords array) + dataPointer += segementSizeTable[1]; + flipGen(ctp_routes, segementSizeTable[1]); + + memcpy(ctp_walkboxTable, dataPointer, segementSizeTable[2]); // get the walkbox coordinates and lines + dataPointer += segementSizeTable[2]; + flipGen(ctp_walkboxTable, segementSizeTable[2]); + + if (ctpVar1) { + dataPointer += segementSizeTable[3]; + dataPointer += segementSizeTable[4]; + } else { + memcpy(walkboxType, dataPointer, segementSizeTable[3]); // get the walkbox type + dataPointer += segementSizeTable[3]; + flipGen(walkboxType, segementSizeTable[3]); // Type: 0x00 - non walkable, 0x01 - walkable, 0x02 - exit zone + + memcpy(walkboxChange, dataPointer, segementSizeTable[4]); // change indicator, walkbox type can change, i.e. blocked by object (values are either 0x00 or 0x01) + dataPointer += segementSizeTable[4]; + flipGen(walkboxChange, segementSizeTable[4]); + } + + memcpy(ctpVar6, dataPointer, segementSizeTable[5]); // unknown? always 2*16 bytes (used by S24.CTP, S33.CTP, S33_2.CTP, S34.CTP, S35.CTP, S36.CTP; values can be 0x00, 0x01, 0x03, 0x05) + dataPointer += segementSizeTable[5]; + flipGen(ctpVar6, segementSizeTable[5]); + + memcpy(ctp_scale, dataPointer, segementSizeTable[6]); // scale values for the walkbox coordinates (don't know why there is a need for scaling walkboxes) + dataPointer += segementSizeTable[6]; + flipGen(ctp_scale, segementSizeTable[6]); // ok + + free(ptr); + + strcpyuint8(string, currentCtpName); + + numberOfWalkboxes = segementSizeTable[6] / 2; // get the number of walkboxes + + loadCtpSub2(ctp_routeCoordCount, ctpVar8); // process path-finding stuff + + polyStruct = ctpVar11 = ctpVar13 = ptr_something; + + ptr = (uint8 *) polyStruct; + + walkboxCounter = numberOfWalkboxes; + + while ((--walkboxCounter) >= 0) { + loadCtpSub1(walkboxCounter, 0, ctp_walkboxTable, ctpVar13); + } + + ctpVar15 = ctpVar13 + 1; // was after the -1 thing + + walkboxCounter = numberOfWalkboxes; + + while (--walkboxCounter) { + loadCtpSub1(walkboxCounter, ctp_scale[walkboxCounter] * 20, + ctp_walkboxTable, ctpVar13); + } + + //ctpVar17 = ctpVar13 - ptr + 4; + + { + int numOfUsedEntries = ctpVar13 - (ctpVar19Struct *) ptr; + numOfUsedEntries++; // there is a -1 entry at the end... Original was only mallocing numOfUsedEntries*sizeof(ctpVar19Struct)+4, but this is a bit ugly... + ctpVar13 = ctpVar11 = polyStruct = + (ctpVar19Struct *) malloc(numOfUsedEntries * + sizeof(ctpVar19Struct)); + } + + walkboxCounter = numberOfWalkboxes; + while ((--walkboxCounter) >= 0) { + loadCtpSub1(walkboxCounter, 0, ctp_walkboxTable, ctpVar13); + } + + ctpVar15 = ctpVar13 + 1; + + walkboxCounter = numberOfWalkboxes; + while (--walkboxCounter) { + loadCtpSub1(walkboxCounter, ctp_scale[walkboxCounter] * 20, + ctp_walkboxTable, ctpVar13); + } + + ctpVar19 = ctpVar11; + + return (1); +} + +} // End of namespace Cruise diff --git a/backends/platform/PalmOS/Src/missing/time.h b/engines/cruise/ctp.h index 3de16f4517..f6a31d387d 100644 --- a/backends/platform/PalmOS/Src/missing/time.h +++ b/engines/cruise/ctp.h @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,34 +22,37 @@ * */ -#ifndef __TIME_H__ -#define __TIME_H__ +#ifndef CRUISE_CTP_H +#define CRUISE_CTP_H -#include "palmversion.h" +namespace Cruise { -#ifdef __cplusplus -extern "C" { -#endif +struct ctpVar19SubStruct { + uint16 boxIdx; //0 + uint16 type; //2 + uint16 minX; //4 + uint16 maxX; //6 + uint16 minY; //8 + uint16 maxY; //A +}; -typedef UInt32 time_t; - -struct tm { - Int16 tm_sec; // seconds [0,61] - Int16 tm_min; // minutes [0,59] - Int16 tm_hour; // hour [0,23] - Int16 tm_mday; // day of month [1,31] - Int16 tm_mon; // month of year [0,11] - Int16 tm_year; // years since 1900 - Int16 tm_wday; // day of week [0,6] (Sunday = 0) - Int16 tm_yday; // day of year [0,365] - Int16 tm_isdst; // daylight savings flag +struct ctpVar19Struct { + struct ctpVar19Struct *field_0; //0 + ctpVar19SubStruct subStruct; }; -time_t time(time_t *tloc); -struct tm *localtime(const time_t *timer); +extern ctpVar19Struct *ptr_something; +extern ctpVar19Struct *polyStruct; +extern ctpVar19Struct *ctpVar11; +extern ctpVar19Struct *ctpVar13; +extern ctpVar19Struct *ctpVar15; -#ifdef __cplusplus -} -#endif +extern uint8 *ctpVar17; +extern ctpVar19Struct *ctpVar19; + +int loadCtp(uint8 * ctpName); +int ctpProc2(int varX, int varY, int paramX, int paramY); + +} // End of namespace Cruise #endif diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp new file mode 100644 index 0000000000..92d830418c --- /dev/null +++ b/engines/cruise/dataLoader.cpp @@ -0,0 +1,515 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +void loadSetEntry(uint8 * name, uint8 * ptr, int currentEntryIdx, + int currentDestEntry); +void loadFNTSub(uint8 * ptr, int destIdx); + +enum fileTypeEnum { + type_UNK, + type_SPL, + type_SET, + type_FNT +}; + +int loadSingleFile; + +// TODO: Unify decodeGfxFormat1, decodeGfxFormat4 and decodeGfxFormat5 + +void decodeGfxFormat1(dataFileEntry *pCurrentFileEntry) { + uint8 *buffer; + uint8 *dataPtr = pCurrentFileEntry->subData.ptr; + + int spriteSize = + pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 8; + int x = 0; + + buffer = (uint8 *) malloc(spriteSize); + + while (x < spriteSize) { + uint8 c; + uint16 p0; + + p0 = (dataPtr[0] << 8) | dataPtr[1]; + + /* decode planes */ + for (c = 0; c < 16; c++) { + buffer[x + c] = ((p0 >> 15) & 1); + + p0 <<= 1; + } + + x += 16; + + dataPtr += 2; + } + + pCurrentFileEntry->subData.ptr = buffer; +} + +void decodeGfxFormat4(dataFileEntry *pCurrentFileEntry) { + uint8 *buffer; + uint8 *dataPtr = pCurrentFileEntry->subData.ptr; + + int spriteSize = + pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn * 2; + int x = 0; + + buffer = (uint8 *) malloc(spriteSize); + + while (x < spriteSize) { + uint8 c; + uint16 p0; + uint16 p1; + uint16 p2; + uint16 p3; + + p0 = (dataPtr[0] << 8) | dataPtr[1]; + p1 = (dataPtr[2] << 8) | dataPtr[3]; + p2 = (dataPtr[4] << 8) | dataPtr[5]; + p3 = (dataPtr[6] << 8) | dataPtr[7]; + + /* decode planes */ + for (c = 0; c < 16; c++) { + buffer[x + c] = + ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & + 4) | ((p3 >> 12) & 8); + + p0 <<= 1; + p1 <<= 1; + p2 <<= 1; + p3 <<= 1; + } + + x += 16; + + dataPtr += 8; + } + + pCurrentFileEntry->subData.ptr = buffer; +} + +void decodeGfxFormat5(dataFileEntry *pCurrentFileEntry) { + uint8 *buffer; + uint8 *dataPtr = pCurrentFileEntry->subData.ptr; + + int spriteSize = + pCurrentFileEntry->height * pCurrentFileEntry->widthInColumn; + int x = 0; + int range = pCurrentFileEntry->height * pCurrentFileEntry->width; + + buffer = (uint8 *) malloc(spriteSize); + + while (x < spriteSize) { + uint8 c; + uint16 p0; + uint16 p1; + uint16 p2; + uint16 p3; + uint16 p4; + + p0 = (dataPtr[0 + range * 0] << 8) | dataPtr[1 + range * 0]; + p1 = (dataPtr[0 + range * 1] << 8) | dataPtr[1 + range * 1]; + p2 = (dataPtr[0 + range * 2] << 8) | dataPtr[1 + range * 2]; + p3 = (dataPtr[0 + range * 3] << 8) | dataPtr[1 + range * 3]; + p4 = (dataPtr[0 + range * 4] << 8) | dataPtr[1 + range * 4]; + + /* decode planes */ + for (c = 0; c < 16; c++) { + buffer[x + c] = + ((p0 >> 15) & 1) | ((p1 >> 14) & 2) | ((p2 >> 13) & + 4) | ((p3 >> 12) & 8) | ((p4 >> 11) & 16); + + p0 <<= 1; + p1 <<= 1; + p2 <<= 1; + p3 <<= 1; + p4 <<= 1; + } + + x += 16; + + dataPtr += 2; + } + + pCurrentFileEntry->subData.ptr = buffer; +} + +int updateResFileEntry(int height, int width, int entryNumber, int resType) { + int div = 0; + int size; + + resetFileEntry(entryNumber); + + filesDatabase[entryNumber].subData.field_1C = 0; + + size = height * width; // for sprites: width * height + + if (resType == 4) { + div = size / 4; + } else if (resType == 5) { + width = (width * 8) / 5; + } + + filesDatabase[entryNumber].subData.ptr = + (uint8 *) mallocAndZero(size + div); + + if (!filesDatabase[entryNumber].subData.ptr) + return (-2); + + filesDatabase[entryNumber].widthInColumn = width; + filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr + size; + filesDatabase[entryNumber].width = width / 8; + filesDatabase[entryNumber].resType = resType; + filesDatabase[entryNumber].height = height; + filesDatabase[entryNumber].subData.index = -1; + + return entryNumber; +} + +int createResFileEntry(int width, int height, int resType) { + int i; + int entryNumber; + int div = 0; + int size; + + printf("Executing untested createResFileEntry!\n"); + exit(1); + + for (i = 0; i < 257; i++) { + if (!filesDatabase[i].subData.ptr) + break; + } + + if (i >= 257) { + return (-19); + } + + entryNumber = i; + + filesDatabase[entryNumber].subData.field_1C = 0; + + size = width * height; // for sprites: width * height + + if (resType == 4) { + div = size / 4; + } else if (resType == 5) { + width = (width * 8) / 5; + } + + filesDatabase[entryNumber].subData.ptr = (uint8 *) mallocAndZero(size + div); + + if (filesDatabase[entryNumber].subData.ptr) { + return (-2); + } + + filesDatabase[entryNumber].widthInColumn = width; + filesDatabase[entryNumber].subData.ptr2 = filesDatabase[entryNumber].subData.ptr + size; + filesDatabase[entryNumber].width = width / 8; + filesDatabase[entryNumber].resType = resType; + filesDatabase[entryNumber].height = height; + filesDatabase[entryNumber].subData.index = -1; + + return entryNumber; +} + +fileTypeEnum getFileType(uint8 *name) { + char extentionBuffer[16]; + + fileTypeEnum newFileType = type_UNK; + + getFileExtention((char *)name, extentionBuffer); + + if (!strcmp(extentionBuffer, ".SPL")) { + newFileType = type_SPL; + } else if (!strcmp(extentionBuffer, ".SET")) { + newFileType = type_SET; + } else if (!strcmp(extentionBuffer, ".FNT")) { + newFileType = type_FNT; + } + + ASSERT(newFileType != type_UNK); + + return newFileType; +} + +int getNumMaxEntiresInSet(uint8 *ptr) { + uint16 numEntries = *(uint16 *) (ptr + 4); + flipShort(&numEntries); + + return numEntries; +} + +int loadFileMode2(uint8 *name, int startIdx, int currentEntryIdx, int numIdx) { + uint8 *ptr = NULL; + fileTypeEnum fileType; + + fileType = getFileType(name); + + loadFileSub1(&ptr, name, NULL); + + switch (fileType) { + case type_SET: + { + int i; + int numMaxEntriesInSet = getNumMaxEntiresInSet(ptr); + + for (i = 0; i < numIdx; i++) { + if ((currentEntryIdx + i) > numMaxEntriesInSet) { + return 0; // exit if limit is reached + } + loadSetEntry(name, ptr, currentEntryIdx + i, + startIdx + i); + } + + break; + } + case type_FNT: + { + loadFNTSub(ptr, startIdx); + break; + } + case type_UNK: + { + break; + } + case type_SPL: + { + break; + } + } + return 0; +} + +int loadFullBundle(uint8 *name, int startIdx) { + uint8 *ptr = NULL; + fileTypeEnum fileType; + + fileType = getFileType(name); + + loadFileSub1(&ptr, name, NULL); + + switch (fileType) { + case type_SET: + { + int i; + int numMaxEntriesInSet; + + numMaxEntriesInSet = getNumMaxEntiresInSet(ptr); // get maximum number of sprites/animations in SET file + + for (i = 0; i < numMaxEntriesInSet; i++) { + loadSetEntry(name, ptr, i, startIdx + i); + } + + break; + } + case type_FNT: + { + loadFNTSub(ptr, startIdx); + break; + } + case type_UNK: + { + break; + } + case type_SPL: + { + break; + } + } + + return 0; +} + +void loadFNTSub(uint8 *ptr, int destIdx) { + uint8 *ptr2 = ptr; + uint8 *destPtr; + int fileIndex; + uint32 fontSize; + + ptr2 += 4; + memcpy(&loadFileVar1, ptr2, 4); + + flipLong(&loadFileVar1); + + if (destIdx == -1) { + fileIndex = createResFileEntry(loadFileVar1, 1, 1); + } else { + fileIndex = updateResFileEntry(loadFileVar1, 1, destIdx, 1); + } + + destPtr = filesDatabase[fileIndex].subData.ptr; + + memcpy(destPtr, ptr2, loadFileVar1); + + memcpy(&fontSize, ptr2, 4); + flipLong(&fontSize); + + if (destPtr != NULL) { + int32 i; + uint8 *currentPtr; + + destPtr = filesDatabase[fileIndex].subData.ptr; + + flipLong((int32 *) destPtr); + flipLong((int32 *) (destPtr + 4)); + flipGen(destPtr + 8, 6); + + currentPtr = destPtr + 14; + + for (i = 0; i < *(int16 *) (destPtr + 8); i++) { + flipLong((int32 *) currentPtr); + currentPtr += 4; + + flipGen(currentPtr, 8); + currentPtr += 8; + } + } +} + +void loadSetEntry(uint8 *name, uint8 *ptr, int currentEntryIdx, + int currentDestEntry) { + uint8 *ptr2; + uint8 *ptr3; + int offset; + int sec = 0; + uint16 numIdx; + + if (!strcmpuint8(ptr, "SEC")) { + sec = 1; + } + + ptr2 = ptr + 4; + + memcpy(&numIdx, ptr2, 2); + flipShort(&numIdx); + + ptr3 = ptr + 6; + + offset = currentEntryIdx * 16; + + { + uint8 *ptr4; + int resourceSize; + int fileIndex; + setHeaderEntry localBuffer; + uint8 *ptr5; + + ptr4 = ptr + offset + 6; + + memcpy(&localBuffer, ptr4, sizeof(setHeaderEntry)); + + flipLong((int32 *) & localBuffer.field_0); + flipGen(&localBuffer.width, 12); + + if ((sec == 1) || (localBuffer.type == 5)) { + localBuffer.width = localBuffer.width - (localBuffer.type * 2); // Type 1: Width - (1*2) , Type 5: Width - (5*2) + } + + resourceSize = localBuffer.width * localBuffer.height; + + if (currentDestEntry == -1) { + fileIndex = + createResFileEntry(localBuffer.width, + localBuffer.height, localBuffer.type); + } else { + fileIndex = + updateResFileEntry(localBuffer.height, + localBuffer.width, currentDestEntry, + localBuffer.type); + } + + if (fileIndex < 0) { + return; // TODO: buffer is not freed + } + + ptr5 = ptr3 + localBuffer.field_0 + numIdx * 16; + + memcpy(filesDatabase[fileIndex].subData.ptr, ptr5, + resourceSize); + ptr5 += resourceSize; + + switch (localBuffer.type) { + case 0: + { + filesDatabase[fileIndex].subData.resourceType = + 8; + break; + } + case 1: + { + filesDatabase[fileIndex].subData.resourceType = + 2; + decodeGfxFormat1(&filesDatabase[fileIndex]); + break; + } + case 4: + { + filesDatabase[fileIndex].width *= 2; + filesDatabase[fileIndex].subData.resourceType = + 4; + decodeGfxFormat4(&filesDatabase[fileIndex]); + break; + } + case 5: + { + if (sec == 0) { + // TODO sec type 5 needs special conversion. cut out 2 bytes at every width/5 position. + return; + } + filesDatabase[fileIndex].subData.resourceType = + 4; + decodeGfxFormat5(&filesDatabase[fileIndex]); + break; + } + case 8: + { + filesDatabase[fileIndex].subData.resourceType = 4; // dummy ! + break; + } + default: + { + printf("Unsuported gfx loading type: %d\n", + localBuffer.type); + break; + } + } + + filesDatabase[fileIndex].subData.index = currentDestEntry; + filesDatabase[fileIndex].subData.transparency = + localBuffer.transparency; /*% 0x10 */ ; + + strcpyuint8(filesDatabase[fileIndex].subData.name, name); + } + + // TODO: free + + return; +} + +} // End of namespace Cruise diff --git a/engines/cruise/dataLoader.h b/engines/cruise/dataLoader.h new file mode 100644 index 0000000000..8c8e6bd301 --- /dev/null +++ b/engines/cruise/dataLoader.h @@ -0,0 +1,38 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_DATALOADER_H +#define CRUISE_DATALOADER_H + +namespace Cruise { + +int loadData(uint8 * name, int startIdx); +int loadFileMode2(uint8 * name, int param, int startIdx, int numIdx); +int loadFileSub1(uint8 ** ptr, uint8 * name, uint8 * ptr2); + +int loadFullBundle(uint8 * name, int startIdx); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/decompiler.cpp b/engines/cruise/decompiler.cpp new file mode 100644 index 0000000000..072fa171fd --- /dev/null +++ b/engines/cruise/decompiler.cpp @@ -0,0 +1,1598 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +#ifdef DUMP_SCRIPT + +#define numMaxLignes 100000 +#define lineMaxSize 10000 + +int currentLineType = 0; + +struct decompileLineStruct { + int lineOffset; + char line[lineMaxSize]; + int indent; + int type; + int pendingElse; +}; + +struct decompileLineStruct decompileLineTable[numMaxLignes]; + +int positionInDecompileLineTable; + +int failed; + +char *currentDecompScript; +scriptInstanceStruct dummy; +scriptInstanceStruct *currentDecompScriptPtr = &dummy; + +uint8 *getDataFromData3(ovlData3Struct * ptr, int param); + +opcodeTypeFunction decompOpcodeTypeTable[64]; + +int currentLineIdx = 0; + +unsigned long int currentOffset; + +unsigned long int dumpIdx = 0; + +FILE *fHandle = NULL; + +#define DECOMPILER_STACK_DEPTH 100 +#define DECOMPILER_STACK_ENTRY_SIZE 5000 + +char tempbuffer[5000]; + +char decompileStack[DECOMPILER_STACK_DEPTH][DECOMPILER_STACK_ENTRY_SIZE]; + +unsigned long int decompileStackPosition = 0; + +uint8 stringName[256]; + +ovlData3Struct *currentScript; + +ovlDataStruct *currentDecompOvl; +int currentDecompScriptIdx; + +char decompSaveOpcodeVar[256]; + +uint8 *getStringNameFromIdx(uint16 stringTypeIdx, char *offset) { + switch (stringTypeIdx & 7) { + case 2: + { + sprintf(stringName, "\"%s\"", + currentScript->dataPtr + + currentScript->offsetToSubData3 + atoi(offset)); + break; + } + case 5: + { + sprintf(stringName, "vars[%s]", offset); + break; + } + default: + { + sprintf(stringName, "string[%d][%s]", + stringTypeIdx & 7, offset); + break; + } + } + + return stringName; +} + +char *resolveMessage(char *messageIdxString) { + char buffer[500]; + int variable; + + variable = atoi(messageIdxString); + sprintf(buffer, "%d", variable); + + if (strcmp(buffer, messageIdxString)) { + return messageIdxString; + } else { + return currentDecompOvl->stringTable[atoi(messageIdxString)]. + string; + } +} + +void pushDecomp(char *string, ...) { + va_list va; + + va_start(va, string); + vsprintf(decompileStack[decompileStackPosition], string, va); + va_end(va); + + // fprintf(fHandle, "----> %s\n",decompileStack[decompileStackPosition]); + + decompileStackPosition++; +} + +void resolveDecompShort(char *buffer) { + ovlData3Struct *data3Ptr = currentScript; + + { + int i; + + importScriptStruct *importEntry = + (importScriptStruct *) (data3Ptr->dataPtr + + data3Ptr->offsetToImportData); + + for (i = 0; i < data3Ptr->numImport; i++) { + switch (importEntry->type) { + case 20: // script + case 30: + case 40: + case 50: + { + if (importEntry->offset == currentDecompScriptPtr->var4 - 3) // param1 + { + sprintf(buffer, + data3Ptr->dataPtr + + data3Ptr-> + offsetToImportName + + importEntry->offsetToName); + return; + } + if (importEntry->offset == currentDecompScriptPtr->var4 - 6) // param2 + { + sprintf(buffer, "linkedIdx"); + return; + } + break; + } + default: + { + if (importEntry->offset == + currentDecompScriptPtr->var4 - 4) { + sprintf(buffer, + data3Ptr->dataPtr + + data3Ptr-> + offsetToImportName + + importEntry->offsetToName); + return; + } + } + } + importEntry++; + } + } + + buffer[0] = 0; + +} + +void resolveDecompChar(char *buffer) { + ovlData3Struct *data3Ptr = currentScript; + + { + int i; + + importScriptStruct *importEntry = + (importScriptStruct *) (data3Ptr->dataPtr + + data3Ptr->offsetToImportData); + + for (i = 0; i < data3Ptr->numImport; i++) { + switch (importEntry->type) { + default: + { + if (importEntry->offset == + currentDecompScriptPtr->var4 - 2) { + sprintf(buffer, + data3Ptr->dataPtr + + data3Ptr-> + offsetToImportName + + importEntry->offsetToName); + return; + } + } + } + importEntry++; + } + } + + buffer[0] = 0; + +} + +char *popDecomp() { + // printf("<----\n"); + + if (!decompileStackPosition) { + return (""); + } + + decompileStackPosition--; + + return decompileStack[decompileStackPosition]; +} + +void getByteFromDecompScript(char *buffer) { + short int var = currentDecompScript[currentDecompScriptPtr->var4]; + + currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 1; + + if (var == -1) { + resolveDecompChar(buffer); + + if (buffer[0]) + return; + } + + sprintf(buffer, "%d", var); +} + +char getByteFromDecompScriptReal(void) { + short int var = currentDecompScript[currentDecompScriptPtr->var4]; + + currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 1; + + return var; +} + +void getShortFromDecompScript(char *buffer) { + short int var = + *(int16 *) (currentDecompScript + currentDecompScriptPtr->var4); + + currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 2; + + flipShort(&var); + + if (var == -1) { + resolveDecompShort(buffer); + + if (buffer[0]) + return; + } + + sprintf(buffer, "%d", var); +} + +short int getShortFromDecompScriptReal(void) { + short int var = + *(int16 *) (currentDecompScript + currentDecompScriptPtr->var4); + + currentDecompScriptPtr->var4 = currentDecompScriptPtr->var4 + 2; + + flipShort(&var); + + return var; +} + +void addDecomp(char *string, ...) { + va_list va; + + /* fprintf(fHandle,"%d: ",currentLineIdx); + * + * va_start(va,string); + * vfprintf(fHandle,string,va); + * va_end(va); + * + * fprintf(fHandle,"\n"); */ + + struct decompileLineStruct *pLineStruct = + &decompileLineTable[positionInDecompileLineTable++]; + + pLineStruct->lineOffset = currentLineIdx; + pLineStruct->indent = 0; + pLineStruct->type = currentLineType; + pLineStruct->line[0] = 0; + pLineStruct->pendingElse = 0; + + va_start(va, string); + vsprintf(pLineStruct->line, string, va); + va_end(va); + + currentLineIdx = currentDecompScriptPtr->var4; + currentLineType = 0; + + /*printf("%d: ",currentOffset); + * + * va_start(va,string); + * vprintf(string,va); + * va_end(va); + * + * printf("\n"); */ +} + +void resolveVarName(char *ovlIdxString, int varType, char *varIdxString, + char *outputName) { + int varIdx = atoi(varIdxString); + + strcpy(outputName, ""); + + if (varType == 2) { + strcpy(outputName, getStringNameFromIdx(varType, + varIdxString)); + return; + } + if (varType == 1) { + sprintf(outputName, "localVar_%s", varIdxString); + return; + } + + if (!strcmp(ovlIdxString, "0")) { + int i; + + for (i = 0; i < currentDecompOvl->numExport; i++) { + if (varIdx == currentDecompOvl->exportDataPtr[i].idx) { + if (((currentDecompOvl->exportDataPtr[i].var4 & 0xF0) == 0) && varType != 0x20) // var + { + strcpy(outputName, + currentDecompOvl->exportNamesPtr + + currentDecompOvl->exportDataPtr[i]. + offsetToName); + return; + } + if ((currentDecompOvl->exportDataPtr[i].var4) == 20 && varType == 0x20) // script + { + strcpy(outputName, + currentDecompOvl->exportNamesPtr + + currentDecompOvl->exportDataPtr[i]. + offsetToName); + return; + } + } + } + sprintf(outputName, "ovl(%s).[%d][%s]", ovlIdxString, varType, + varIdxString); + } else { + strcpy(outputName, ovlIdxString); + } +} + +int decompLoadVar(void) { + switch (currentScriptOpcodeType) { + case 0: + { + char buffer[256]; + + getShortFromDecompScript(buffer); + + pushDecomp(buffer); + + return (0); + } + // string + case 1: + { + char buffer1[256]; + char buffer2[256]; + char buffer3[256]; + char varName[256]; + + getByteFromDecompScript(buffer1); + getByteFromDecompScript(buffer2); + + getShortFromDecompScript(buffer3); + + resolveVarName(buffer2, atoi(buffer1) & 7, buffer3, + varName); + + pushDecomp("%s", varName); + return (0); + } + case 2: + { + char buffer1[256]; + char buffer2[256]; + char buffer3[256]; + char varName[256]; + + getByteFromDecompScript(buffer1); + getByteFromDecompScript(buffer2); + + getShortFromDecompScript(buffer3); + + resolveVarName(buffer2, atoi(buffer1) & 7, buffer3, + varName); + + pushDecomp("%s", varName); + return (0); + } + case 5: + { + char buffer1[256]; + char buffer2[256]; + char buffer3[256]; + char varName[256]; + + getByteFromDecompScript(buffer1); + getByteFromDecompScript(buffer2); + + getShortFromDecompScript(buffer3); + + resolveVarName(buffer2, atoi(buffer1) & 7, buffer3, + varName); + + pushDecomp("%s[%s]", varName, decompSaveOpcodeVar); + return (0); + } + default: + { + printf("Unsupported type %d in opcodeType0\n", + currentScriptOpcodeType); + failed = 1; + } + } +} + +int decompSaveVar(void) { +// int var = popVar(); + + switch (currentScriptOpcodeType) { + case 0: + { + addDecomp(popDecomp()); + return (0); + } + // modify string + case 1: + { + char buffer1[256]; + char buffer2[256]; + char buffer3[256]; + char varName[256]; + uint8 type; + + getByteFromDecompScript(buffer1); + getByteFromDecompScript(buffer2); + + getShortFromDecompScript(buffer3); + + type = atoi(buffer1) & 7; + + resolveVarName(buffer2, type, buffer3, varName); + + addDecomp("%s = %s", varName, popDecomp()); + break; + } + case 2: + { + char buffer1[256]; + char buffer2[256]; + char buffer3[256]; + + getByteFromDecompScript(buffer1); + getByteFromDecompScript(buffer2); + + getShortFromDecompScript(buffer3); + + addDecomp("ovl(%s).setVar(%s,%s) = %s", buffer2, + buffer1, buffer3, popDecomp()); + break; + } + case 4: + { + strcpy(decompSaveOpcodeVar, popDecomp()); + break; + } + case 5: + { + char buffer1[256]; + char buffer2[256]; + char buffer3[256]; + char varName[256]; + uint8 type; + + getByteFromDecompScript(buffer1); + getByteFromDecompScript(buffer2); + + getShortFromDecompScript(buffer3); + + type = atoi(buffer1) & 7; + + resolveVarName(buffer2, type, buffer3, varName); + + addDecomp("%s[%s] = %s", varName, decompSaveOpcodeVar, + popDecomp()); + break; + } + default: + { + printf("Unsupported type %d in opcodeType1\n", + currentScriptOpcodeType); + failed = 1; + } + } + + return (0); +} + +int decompOpcodeType2(void) { + switch (currentScriptOpcodeType) { + case 1: + { + char buffer3[256]; + char varName[256]; + int byte1 = getByteFromDecompScriptReal(); + int byte2 = getByteFromDecompScriptReal(); + getShortFromDecompScript(buffer3); + + resolveVarName("0", byte1 & 7, buffer3, varName); + + pushDecomp(varName); + + break; + } + case 5: + { + int byte1 = getByteFromDecompScriptReal(); + int byte2 = getByteFromDecompScriptReal(); + short int short1 = getShortFromDecompScriptReal(); + + int8 *ptr = scriptDataPtrTable[byte1 & 7] + short1; + + if ((byte1 & 7) == 2) { + pushDecomp("\"%s\"[%s]", ptr, + decompSaveOpcodeVar); + } else if ((byte1 & 7) == 5) { + pushDecomp("freeString[%d][%s]", short1, + decompSaveOpcodeVar); + } else { + printf("Unsupported type %d in opcodeType2\n", + byte1 & 7); + failed = 1; + } + break; + } + default: + { + printf("Unsupported type %d in opcodeType2\n", + currentScriptOpcodeType); + failed = 1; + } + } + return (0); +} + +int decompMath(void) { + char *param1 = popDecomp(); + char *param2 = popDecomp(); + + switch (currentScriptOpcodeType) { + case 0: + { + sprintf(tempbuffer, "%s+%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + case 1: + { + sprintf(tempbuffer, "%s/%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + case 2: + { + sprintf(tempbuffer, "%s-%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + case 3: + { + sprintf(tempbuffer, "%s*%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + case 4: + { + sprintf(tempbuffer, "%s\%%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + case 5: + case 7: + { + sprintf(tempbuffer, "%s|%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + case 6: + { + sprintf(tempbuffer, "%s&%s", param1, param2); + pushDecomp(tempbuffer); + break; + } + + default: + { + sprintf(tempbuffer, "decompMath(%d,%s,%s)", + currentScriptOpcodeType, param1, param2); + pushDecomp(tempbuffer); + break; + } + } + return (0); +} + +int decompBoolCompare(void) { + char *param1; + char *param2; + + param1 = popDecomp(); + param2 = popDecomp(); + + sprintf(tempbuffer, "compare(%s,%s)", param1, param2); + pushDecomp(tempbuffer); + + return 0; +} + +int decompTest(void) { + unsigned long int oldOffset = currentDecompScriptPtr->var4; + short int offset = getShortFromDecompScriptReal(); + + switch (currentScriptOpcodeType) { + case 0: + { + currentLineType = 1; + addDecomp("test '!(bitMask & 1)' and goto %d", + offset + oldOffset); + break; + } + case 1: + { + currentLineType = 1; + addDecomp("test '(bitMask & 1)' and goto %d", + offset + oldOffset); + break; + } + case 2: + { + currentLineType = 1; + addDecomp("test '(bitMask & 2)' and goto %d", + offset + oldOffset); + break; + } + case 3: + { + currentLineType = 1; + addDecomp("test '(bitMask & 3)' and goto %d", + offset + oldOffset); + break; + } + case 4: + { + currentLineType = 1; + addDecomp("test '(bitMask & 4)' and goto %d", + offset + oldOffset); + break; + } + case 5: + { + currentLineType = 1; + addDecomp("test '(bitMask & 5)' and goto %d", + offset + oldOffset); + break; + } + case 6: + { + currentLineType = 2; + addDecomp("test 'never' and goto %d", + offset + oldOffset); + break; + } + case 7: + { + currentLineType = 3; + addDecomp("goto %d", offset + oldOffset); + break; + } + + } + + return 0; +} + +int decompCompare(void) { + char *param; + + param = popDecomp(); + + addDecomp("sign(%s)", param); + +/* + if(!pop) + si = 1; + + if(pop<0) + { + si |= 4; + } + + if(pop>0) + { + si |= 2; + } + + currentScriptPtr->bitMask = si; +*/ + + return 0; +} + +int decompSwapStack(void) { + char *stack1; + char *stack2; + char buffer1[4000]; + char buffer2[4000]; + + stack1 = popDecomp(); + stack2 = popDecomp(); + + strcpyuint8(buffer1, stack1); + strcpyuint8(buffer2, stack2); + + pushDecomp(buffer1); + pushDecomp(buffer2); + + return 0; +} + +int decompFunction(void) { + currentScriptOpcodeType = getByteFromDecompScriptReal(); +// addDecomp("OP_%X", currentScriptOpcodeType); + switch (currentScriptOpcodeType) { + case 0x1: + { + pushDecomp("_setMain5()"); + break; + } + case 0x2: + { + pushDecomp("_prepareFade()"); + break; + } + case 0x3: + { + sprintf(tempbuffer, "_loadBackground(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x4: + { + sprintf(tempbuffer, "_loadFullBundle(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x5: + { + sprintf(tempbuffer, "_addCell(%s,%s,%s)", popDecomp(), + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x6: + { + unsigned long int numArg = atoi(popDecomp()); + char *ovlStr; + char *idxStr; + int i; + char functionName[100]; + + idxStr = popDecomp(); + ovlStr = popDecomp(); + + resolveVarName(ovlStr, 0x20, idxStr, functionName); + + sprintf(tempbuffer, "_startASync(%s", functionName); + + for (i = 0; i < numArg; i++) { + strcatuint8(tempbuffer, ","); + strcatuint8(tempbuffer, popDecomp()); + } + + strcatuint8(tempbuffer, ")"); + + pushDecomp(tempbuffer); + break; + } + case 0x7: + { + char *var1; + char *objIdxStr; + char *ovlStr; + char varName[256]; + int i; + + var1 = popDecomp(); + objIdxStr = popDecomp(); + ovlStr = popDecomp(); + + sprintf(tempbuffer, + "_createObjectFromOvlData(ovl:%s,dataIdx:%s,%s)", + ovlStr, objIdxStr, var1); + pushDecomp(tempbuffer); + break; + } + case 0x8: + { + sprintf(tempbuffer, "_removeCell(%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x9: + { + pushDecomp("_freeobjectList()"); + break; + } + case 0xA: + { + sprintf(tempbuffer, "_removeScript(ovl(%s),%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0xB: + { + sprintf(tempbuffer, "_resetFilesEntries(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0xC: + { + sprintf(tempbuffer, "_loadOverlay(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0xD: + { + sprintf(tempbuffer, "_palManipulation(%s,%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0xE: + { + sprintf(tempbuffer, "_playSample(%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x10: + { + sprintf(tempbuffer, "_releaseScript2(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x11: + { + sprintf(tempbuffer, "_getOverlayIdx(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x13: + { + sprintf(tempbuffer, + "_displayMessage(%s,\"%s\",%s,%s,%s,%s)", + popDecomp(), resolveMessage(popDecomp()), + popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x14: + { + sprintf(tempbuffer, "_removeObject(ovl(%s),%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x15: + { + pushDecomp("_pauseScript()"); + break; + } + case 0x16: + { + sprintf(tempbuffer, + "_Op_FreezeCell(%s,%s,%s,%s,%s,%s)", popDecomp(), + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x17: + { + sprintf(tempbuffer, "_loadCtp(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x18: + { + sprintf(tempbuffer, + "_Op_AddAnimation(%s,%s,%s,%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x19: + { + sprintf(tempbuffer, "_Op_RemoveAnimation(%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x1A: + { + sprintf(tempbuffer, "_setupScaleFormula(%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x1E: + { + sprintf(tempbuffer, "_op_1E(%s,%s,%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x21: + { + sprintf(tempbuffer, "_isActorLoaded(%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x22: + { + sprintf(tempbuffer, "_computeScale(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x23: + { + sprintf(tempbuffer, "_convertToScale(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x24: + { + sprintf(tempbuffer, "_op_24(%s,%s,%s,%s)", popDecomp(), + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x27: + { + sprintf(tempbuffer, "_getWalkBoxCollision(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x28: + { + sprintf(tempbuffer, "_changeSaveAllowedState(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x29: + { + pushDecomp("_freeAllPerso()"); + break; + } + case 0x2B: + { + sprintf(tempbuffer, "_getProcIdx(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x2C: + { + sprintf(tempbuffer, "_setObjectPosition(%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x2E: + { + sprintf(tempbuffer, "_releaseScript(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x2F: + { + sprintf(tempbuffer, "_addBackgroundIncrust(%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x30: + { + sprintf(tempbuffer, "_removeBackgroundIncrust(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x31: + { + sprintf(tempbuffer, "_op_31(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x32: + { + pushDecomp("_freeBackgroundInscrustList()"); + break; + } + case 0x35: + { + sprintf(tempbuffer, "_op35(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x37: + { + sprintf(tempbuffer, "_op37(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x38: + { + sprintf(tempbuffer, "_removeBackground(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x39: + { + sprintf(tempbuffer, "_SetActiveBackgroundPlane(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x3A: + { + sprintf(tempbuffer, "_setVar49(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x3B: + { + pushDecomp("_op3B()"); + break; + } + case 0x3C: + { + sprintf(tempbuffer, "_rand(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x3D: + { + sprintf(tempbuffer, "_loadMusic(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x3E: + { + pushDecomp("_op_3E()"); + break; + } + case 0x3F: + { + pushDecomp("_op_3F()"); + break; + } + case 0x40: + { + pushDecomp("_op_40()"); + break; + } + case 0x41: + { + sprintf(tempbuffer, "_isFileLoaded2(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x45: + { + pushDecomp("_stopSound()"); + break; + } + case 0x49: + { + sprintf(tempbuffer, "_op49(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x54: + { + sprintf(tempbuffer, "_setFontVar(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x56: + { + sprintf(tempbuffer, "_changeCutSceneState(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x57: + { + pushDecomp("_getMouseX()"); + break; + } + case 0x58: + { + pushDecomp("_getMouseY()"); + break; + } + case 0x59: + { + pushDecomp("_getMouse3()"); + break; + } + case 0x5A: + { + sprintf(tempbuffer, "_isFileLoaded(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x5B: + { + pushDecomp("_regenerateBackgroundIncrust()"); + break; + } + case 0x5C: + { + sprintf(tempbuffer, "_Op_AddCellC(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x5E: + { + sprintf(tempbuffer, "_Op_AddCellE(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x60: + { + sprintf(tempbuffer, "_op_60(%s,%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x61: + { + sprintf(tempbuffer, "_op61(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x62: + { + pushDecomp("_pauseCallingScript()"); + break; + } + case 0x63: + { + pushDecomp("_resumeScript()"); + break; + } + case 0x64: + { + unsigned long int numArg = atoi(popDecomp()); + char *ovlStr; + char *idxStr; + int i; + char functionName[256]; + + idxStr = popDecomp(); + ovlStr = popDecomp(); + + resolveVarName(ovlStr, 0x20, idxStr, functionName); + + sprintf(tempbuffer, "%s(", functionName); + + for (i = 0; i < numArg; i++) { + if (i) + strcatuint8(tempbuffer, ","); + strcatuint8(tempbuffer, popDecomp()); + } + + strcatuint8(tempbuffer, ")"); + + pushDecomp(tempbuffer); + break; + } + case 0x65: + { + sprintf(tempbuffer, + "_addWaitObject(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x66: + { + sprintf(tempbuffer, "_op_66(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x67: + { + sprintf(tempbuffer, "_loadAudioResource(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x68: + { + pushDecomp("_freeMediumVar()"); + break; + } + case 0x6A: + { + sprintf(tempbuffer, "_op_6A(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x6B: + { + sprintf(tempbuffer, "_loadData(%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x6C: + { + sprintf(tempbuffer, "_op_6C(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x6D: + { + sprintf(tempbuffer, "_strcpy(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x6E: + { + sprintf(tempbuffer, "_op_6E(%s,%s)", popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x6F: + { + unsigned long int numArg = atoi(popDecomp()); + char *ovlStr; + char *idxStr; + int i; + + idxStr = popDecomp(); + ovlStr = popDecomp(); + + sprintf(tempbuffer, "_op_6F(%s,%s", idxStr, ovlStr); + + for (i = 0; i < numArg; i++) { + strcatuint8(tempbuffer, ","); + strcatuint8(tempbuffer, popDecomp()); + } + + strcatuint8(tempbuffer, ")"); + + pushDecomp(tempbuffer); + break; + } + case 0x70: + { + sprintf(tempbuffer, "_comment(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x71: + { + sprintf(tempbuffer, "_op71(%s,%s,%s,%s,%s)", + popDecomp(), popDecomp(), popDecomp(), popDecomp(), + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x72: + { + sprintf(tempbuffer, "_op72(%s,%s)", popDecomp(), + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x73: + { + sprintf(tempbuffer, "_op73(%s)", popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x74: + { + sprintf(tempbuffer, "_getInitVar1()"); + pushDecomp(tempbuffer); + break; + } + case 0x76: + { + sprintf(tempbuffer, "_Op_InitializeState6(%s,%s)", + popDecomp(), popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x77: + { + sprintf(tempbuffer, "_Op_InitializeState7(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x78: + { + sprintf(tempbuffer, "_Op_InitializeState8(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x79: + { + sprintf(tempbuffer, "_EnterPlayerMenu(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x7B: + { + sprintf(tempbuffer, "_Op_InitializeStateB(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x7C: + { + sprintf(tempbuffer, "_Op_InitializeStateC(%s)", + popDecomp()); + pushDecomp(tempbuffer); + break; + } + case 0x7D: + { + pushDecomp("_freeAllMenu()"); + break; + } + default: + { + addDecomp("OP_%X", currentScriptOpcodeType); + printf("OPCODE: %X\n", currentScriptOpcodeType); + failed = 1; + break; + } + } + +// pushDecomp("functionDummyPush"); + + return (0); +} + +uint8 stop = 0; + +int decompStop(void) { + stop = 1; + addDecomp("stop\n"); + return 0; +} + +int decompBreak(void) { + addDecomp("break"); + return 0; +} + +void generateIndentation(void) { + int i; + + for (i = 0; i < positionInDecompileLineTable; i++) { + if (decompileLineTable[i].type != 0) { + char *gotoStatement; + int destLine; + int destLineIdx; + + gotoStatement = + strstr(decompileLineTable[i].line, "goto"); + assert(gotoStatement); + gotoStatement = strchr(gotoStatement, ' ') + 1; + + destLine = atoi(gotoStatement); + + { + int j; + + destLineIdx = -1; + + for (j = 0; j < positionInDecompileLineTable; + j++) { + if (decompileLineTable[j].lineOffset == + destLine) { + destLineIdx = j; + break; + } + } + + assert(destLineIdx != -1); + + if (destLineIdx > i) { + int j; + + for (j = i + 1; j < destLineIdx; j++) { + decompileLineTable[j].indent++; + } + + if (strstr(decompileLineTable + [destLineIdx - 1].line, + "goto") == + decompileLineTable[destLineIdx - + 1].line) { + //decompileLineTable[destLineIdx-1].pendingElse = 1; + } + } + } + } + } +} + +void dumpScript(uint8 *ovlName, ovlDataStruct *ovlData, int idx) { + uint8 opcodeType; + char buffer[256]; + int i; + + char temp[256]; + char scriptName[256]; + + sprintf(temp, "%d", idx); + + failed = 0; + + currentScript = &ovlData->data3Table[idx]; + + currentDecompScript = currentScript->dataPtr; + currentDecompScriptPtr->var4 = 0; + + currentDecompOvl = ovlData; + currentDecompScriptIdx = idx; + + currentLineIdx = 0; + positionInDecompileLineTable = 0; + currentLineType = 0; + + resolveVarName("0", 0x20, temp, scriptName); + + printf("decompiling script %d - %s\n", idx, scriptName); + + // return; + +// scriptDataPtrTable[1] = *(char**)(ptr+0x6); + scriptDataPtrTable[2] = getDataFromData3(currentScript, 1); // strings + scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings + scriptDataPtrTable[6] = ovlData->ptr8; + + stop = 0; + + sprintf(buffer, "%s-%02d-%s.txt", ovlName, idx, scriptName); + fHandle = fopen(buffer, "w+"); + + decompileStackPosition = 0; + + for (i = 0; i < 64; i++) { + decompOpcodeTypeTable[i] = NULL; + } + + decompOpcodeTypeTable[1] = decompLoadVar; + decompOpcodeTypeTable[2] = decompSaveVar; + decompOpcodeTypeTable[3] = decompOpcodeType2; + decompOpcodeTypeTable[4] = decompMath; + decompOpcodeTypeTable[5] = decompBoolCompare; + decompOpcodeTypeTable[6] = decompTest; + decompOpcodeTypeTable[7] = decompCompare; + decompOpcodeTypeTable[8] = decompSwapStack; + decompOpcodeTypeTable[9] = decompFunction; + decompOpcodeTypeTable[10] = decompStop; + decompOpcodeTypeTable[12] = decompBreak; + + do { + currentOffset = currentDecompScriptPtr->var4; + + opcodeType = getByteFromDecompScriptReal(); + + currentScriptOpcodeType = opcodeType & 7; + + if (!decompOpcodeTypeTable[(opcodeType & 0xFB) >> 3]) { + printf("Unsupported opcode type %d in decomp\n", + (opcodeType & 0xFB) >> 3); + return; + } + + //printf("Optype: %d\n",(opcodeType&0xFB)>>3); + + decompOpcodeTypeTable[(opcodeType & 0xFB) >> 3] (); + + if (failed) { + printf("Aborting decompilation..\n"); + fclose(fHandle); + return; + } + + } while (!stop); + + dumpIdx++; + + generateIndentation(); + + for (i = 0; i < positionInDecompileLineTable; i++) { + int j; + + if (decompileLineTable[i].pendingElse) { + fprintf(fHandle, "%05d:\t", + decompileLineTable[i].lineOffset); + fprintf(fHandle, "else", decompileLineTable[i].line); + fprintf(fHandle, "\n"); + } + + fprintf(fHandle, "%05d:\t", decompileLineTable[i].lineOffset); + for (j = 0; j < decompileLineTable[i].indent; j++) { + fprintf(fHandle, "\t"); + } + fprintf(fHandle, "%s", decompileLineTable[i].line); + fprintf(fHandle, "\n"); + } + + fclose(fHandle); +} + +#endif + +} // End of namespace Cruise diff --git a/engines/cruise/delphine-unpack.cpp b/engines/cruise/delphine-unpack.cpp new file mode 100644 index 0000000000..611d1573fd --- /dev/null +++ b/engines/cruise/delphine-unpack.cpp @@ -0,0 +1,120 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +namespace Cruise { + +struct UnpackCtx { + int size, datasize; + uint32 crc; + uint32 chk; + byte *dst; + const byte *src; +}; + +static int rcr(UnpackCtx *uc, int CF) { + int rCF = (uc->chk & 1); + uc->chk >>= 1; + if (CF) { + uc->chk |= 0x80000000; + } + return rCF; +} + +static int nextChunk(UnpackCtx *uc) { + int CF = rcr(uc, 0); + if (uc->chk == 0) { + uc->chk = READ_BE_UINT32(uc->src); uc->src -= 4; + uc->crc ^= uc->chk; + CF = rcr(uc, 1); + } + return CF; +} + +static uint16 getCode(UnpackCtx *uc, byte numChunks) { + uint16 c = 0; + while (numChunks--) { + c <<= 1; + if (nextChunk(uc)) { + c |= 1; + } + } + return c; +} + +static void unpackHelper1(UnpackCtx *uc, byte numChunks, byte addCount) { + uint16 count = getCode(uc, numChunks) + addCount + 1; + uc->datasize -= count; + while (count--) { + *uc->dst = (byte)getCode(uc, 8); + --uc->dst; + } +} + +static void unpackHelper2(UnpackCtx *uc, byte numChunks) { + uint16 i = getCode(uc, numChunks); + uint16 count = uc->size + 1; + uc->datasize -= count; + while (count--) { + *uc->dst = *(uc->dst + i); + --uc->dst; + } +} + +bool delphineUnpack(byte *dst, const byte *src, int len) { + UnpackCtx uc; + uc.src = src + len - 4; + uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4; + uc.dst = dst + uc.datasize - 1; + uc.size = 0; + uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4; + uc.chk = READ_BE_UINT32(uc.src); uc.src -= 4; + uc.crc ^= uc.chk; + do { + if (!nextChunk(&uc)) { + uc.size = 1; + if (!nextChunk(&uc)) { + unpackHelper1(&uc, 3, 0); + } else { + unpackHelper2(&uc, 8); + } + } else { + uint16 c = getCode(&uc, 2); + if (c == 3) { + unpackHelper1(&uc, 8, 8); + } else if (c < 2) { + uc.size = c + 2; + unpackHelper2(&uc, c + 9); + } else { + uc.size = getCode(&uc, 8); + unpackHelper2(&uc, 12); + } + } + } while (uc.datasize > 0); + return uc.crc == 0; +} + +} // End of namespace Cruise diff --git a/engines/cruise/detection.cpp b/engines/cruise/detection.cpp new file mode 100644 index 0000000000..d875cc4943 --- /dev/null +++ b/engines/cruise/detection.cpp @@ -0,0 +1,125 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" + +#include "base/plugins.h" + +#include "common/advancedDetector.h" + +#include "cruise/cruise.h" + +namespace Cruise { + +struct CRUISEGameDescription { + Common::ADGameDescription desc; + + int gameType; + uint32 features; +}; + +int CruiseEngine::getGameType() const { return _gameDescription->gameType; } +uint32 CruiseEngine::getFeatures() const { return _gameDescription->features; } +Common::Language CruiseEngine::getLanguage() const { return _gameDescription->desc.language; } +Common::Platform CruiseEngine::getPlatform() const { return _gameDescription->desc.platform; } + +} + +static const PlainGameDescriptor cruiseGames[] = { + {"cruise", "Cinematique evo.2 engine game"}, + {"cruise", "Cruise for a corpse"}, + {0, 0} +}; + +static const Common::ADObsoleteGameID obsoleteGameIDsTable[] = { + {"cruise", "cruise", Common::kPlatformUnknown}, + {0, 0, Common::kPlatformUnknown} +}; + +namespace Cruise { + +static const CRUISEGameDescription gameDescriptions[] = { + { + { + "cruise", + "", + AD_ENTRY1("D1", "41a7a4d426dbd048eb369cfee4bb2717"), + Common::FR_FRA, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GType_CRUISE, + 0, + }, + { + { + "cruise", + "256 colors", + AD_ENTRY1("D1", "a90d2b9ead6b4d812cd14268672cf178"), + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GType_CRUISE, + 0, + }, + {AD_TABLE_END_MARKER, 0, 0} +}; + +} + +static const Common::ADParams detectionParams = { + // Pointer to ADGameDescription or its superset structure + (const byte *)Cruise::gameDescriptions, + // Size of that superset structure + sizeof(Cruise::CRUISEGameDescription), + // Number of bytes to compute MD5 sum for + 5000, + // List of all engine targets + cruiseGames, + // Structure for autoupgrading obsolete targets + obsoleteGameIDsTable, + // Name of single gameid (optional) + "cruise", + // List of files for file-based fallback detection (optional) + 0, + // Fallback callback + 0, + // Flags + Common::kADFlagAugmentPreferredTarget +}; + +ADVANCED_DETECTOR_DEFINE_PLUGIN(CRUISE, Cruise::CruiseEngine, detectionParams); + +REGISTER_PLUGIN(CRUISE, "Cinematique evo 2 engine", "Cruise for a Corpse (C) Delphine Software"); + +namespace Cruise { + +bool CruiseEngine::initGame() { + _gameDescription = (const CRUISEGameDescription *)Common::AdvancedDetector::detectBestMatchingGame(detectionParams); + + return (_gameDescription != 0); +} + +} // End of namespace Cruise diff --git a/engines/cruise/font.cpp b/engines/cruise/font.cpp new file mode 100644 index 0000000000..22f358033e --- /dev/null +++ b/engines/cruise/font.cpp @@ -0,0 +1,673 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/file.h" + +#include "cruise/cruise_main.h" + +namespace Cruise { + +// (old: fontProc1(int16 param, uint8* ptr1, uint8* ptr2)) +int32 getLineHeight(int16 charCount, uint8 * fontPtr, uint8 * fontPrt_Desc) { + uint8 *dest; + int32 highestChar = 0; + int32 i; + + if (!charCount) { + return (0); + } + dest = fontPrt_Desc + 6; // fontPtr + 20 // char height + + for (i = 0; i < charCount; i++) { + if ((*(int16 *) dest) > highestChar) { + highestChar = *(int16 *) dest; + } + dest += 12; + } + return highestChar; +} + +// this function determins how many lines the text will have (old: fontProc2(int32 param1, int32 param2, uint8* ptr, uint8* string)) +int32 getTextLineCount(int32 rightBorder_X, int32 wordSpacingWidth, + uint8 *ptr, uint8 *textString) { + uint8 *localString = textString; + uint8 *currentStringPtr; + uint8 character; + + int32 var_6 = 0; + int32 lineLength = 0; + + uint8 *tempPtr = 0; + + if (!*localString) { + return (0); + } + currentStringPtr = localString; + character = *localString; + + do { + int32 charData = fontCharacterTable[character]; + + if (character == '|') { + lineLength = rightBorder_X; + localString = tempPtr; + } else { + if (charData >= 0) { // + 0xA jump to last 2 bytes of the 12 bytes slice = letter width + lineLength += + wordSpacingWidth + *(int16 *) (ptr + 0xA + + charData * 12); + } else { + if (character == ' ') { + lineLength += wordSpacingWidth + 5; + localString = currentStringPtr; + } + } + } + + tempPtr = currentStringPtr; + + if (rightBorder_X <= lineLength) { + var_6 += rightBorder_X; + currentStringPtr = localString; + tempPtr = localString; + lineLength = 0; + } + + character = *(tempPtr++); + currentStringPtr = tempPtr; + + } while (character); + + if (lineLength == 0) { + return (var_6 / rightBorder_X); + } else { + return ((var_6 + rightBorder_X) / rightBorder_X); + } +} + +void loadFNT(const void *fileNameChar) { + uint8 header[6]; + int32 fontSize; + int32 data2; + uint8 data3[6]; + uint8 *fileName = (uint8 *) fileNameChar; + _systemFNT = NULL; + + Common::File fontFileHandle; + + if (!fontFileHandle.exists((char *)fileName)) { + return; + } + + fontFileHandle.open((char *)fileName); + + fontFileHandle.read(header, 4); + + if (strcmpuint8(header, "FNT") == 0) { + fontFileHandle.read(&fontSize, 4); + flipLong(&fontSize); + + fontFileHandle.read(&data2, 4); + flipLong(&data2); + + fontFileHandle.read(data3, 6); // may need an endian flip ? + flipGen(&data3, 6); + + _systemFNT = (uint8 *) mallocAndZero(fontSize); + + if (_systemFNT != NULL) { + int32 i; + uint8 *currentPtr; + + fontFileHandle.seek(0); + fontFileHandle.read(header, 4); // not really require, we could fseek to 4 + + fontFileHandle.read(_systemFNT, fontSize); + + flipLong((int32 *) _systemFNT); + flipLong((int32 *) (_systemFNT + 4)); + flipGen(_systemFNT + 8, 6); + + currentPtr = _systemFNT + 14; + + for (i = 0; i < *(int16 *) (_systemFNT + 8); i++) { + flipLong((int32 *) currentPtr); + currentPtr += 4; + + flipGen(currentPtr, 8); + currentPtr += 8; + } + } + } + + fontFileHandle.close(); +} + +void loadSystemFont(void) { + int32 i; + + video2 = 15; + video4 = 9; + video3 = 13; + colorOfSelectedSaveDrive = 10; + + for (i = 0; i < 64; i++) { + mediumVar[i].ptr = 0; + mediumVar[i].field_1C = 0; + } + + initVar1 = 0; + main5 = 0; + var22 = 0; + initVar2 = 0; + initVar3 = 0; + currentActiveBackgroundPlane = 0; + + //changeCursor(); + + initVar4[0] = 0; + + loadFNT("system.fnt"); +} + +void flipShort(int16 *var) { + uint8 *varPtr = (uint8 *) var; + uint8 temp = varPtr[0]; + varPtr[0] = varPtr[1]; + varPtr[1] = temp; +} + +void flipShort(uint16 *var) { + uint8 *varPtr = (uint8 *) var; + uint8 temp = varPtr[0]; + varPtr[0] = varPtr[1]; + varPtr[1] = temp; +} + +void flipLong(int32 *var) { + char swap1; + char swap2; + char *varPtr = (char *)var; + + swap1 = varPtr[0]; + varPtr[0] = varPtr[3]; + varPtr[3] = swap1; + + swap2 = varPtr[1]; + varPtr[1] = varPtr[2]; + varPtr[2] = swap2; +} + +void flipLong(uint32 *var) { + char swap1; + char swap2; + char *varPtr = (char *)var; + + swap1 = varPtr[0]; + varPtr[0] = varPtr[3]; + varPtr[3] = swap1; + + swap2 = varPtr[1]; + varPtr[1] = varPtr[2]; + varPtr[2] = swap2; +} + +void flipGen(void *var, int32 length) { + int i; + short int *varPtr = (int16 *) var; + + for (i = 0; i < (length / 2); i++) { + flipShort(&varPtr[i]); + } +} + +void renderWord(uint8 * fontPtr_Data, uint8 * outBufferPtr, + int32 drawPosPixel_X, int32 heightOff, int32 height, int32 param4, + int32 stringRenderBufferSize, int32 width, int32 charWidth) { + int i; + int j; + uint8 *fontPtr_Data2 = fontPtr_Data + height * 2; + + outBufferPtr += heightOff * width * 2; // param2 = height , param6 = width + outBufferPtr += drawPosPixel_X; // param1 = drawPosPixel_X + + for (i = 0; i < height; i++) // y++ + { + uint16 currentColor1 = + (*(fontPtr_Data) << 8) | *(fontPtr_Data + 1); + uint16 currentColor2 = + (*(fontPtr_Data2) << 8) | *(fontPtr_Data2 + 1); + + fontPtr_Data += 2; + fontPtr_Data2 += 2; + + for (j = 0; j < charWidth; j++) { + *outBufferPtr = + ((currentColor1 >> 15) & 1) | ((currentColor2 >> + 14) & 2); + outBufferPtr++; + + currentColor1 <<= 1; + currentColor2 <<= 1; + } + outBufferPtr += (width * 2) - charWidth; + } +} + +// returns character count and pixel size (via pointer) per line of the string (old: prepareWordRender(int32 param, int32 var1, int16* out2, uint8* ptr3, uint8* string)) +int32 prepareWordRender(int32 inRightBorder_X, int32 wordSpacingWidth, + int16 * strPixelLength, uint8 * ptr3, uint8 * textString) { + uint8 *localString = textString; + + int32 counter = 0; + int32 finish = 0; + int32 temp_pc = 0; // var_A // temporary pixel count save + int32 temp_cc = 0; // var_C // temporary char count save + int32 pixelCount = 0; // si + + do { + uint8 character = *(localString++); + int16 charData = fontCharacterTable[character]; + + if (character == ' ') { + temp_cc = counter; + temp_pc = pixelCount; + + if (pixelCount + wordSpacingWidth + 5 >= + inRightBorder_X) { + finish = 1; + } else { + pixelCount += wordSpacingWidth + 5; + } + } else { + if (character == '|' || !character) { + finish = 1; + } else { + if (charData) { + if (pixelCount + wordSpacingWidth + + *(int16 *) ((ptr3 + + charData * 12) + 0xA) >= + inRightBorder_X) { + finish = 1; + if (temp_pc) { + pixelCount = temp_pc; + counter = temp_cc; + } + } else { + pixelCount += + wordSpacingWidth + + *(int16 *) ((ptr3 + + charData * 12) + 0xA); + } + } + } + } + counter++; + } while (!finish); + + *strPixelLength = (int16) pixelCount; + return counter; +} + +void drawString(int32 x, int32 y, uint8 *string, uint8 *buffer, uint8 color, + int32 inRightBorder_X) { + uint8 *fontPtr; + uint8 *fontPtr_Data; // ptr2 + uint8 *fontPtr_Desc; // ptr3 + int32 wordSpacingWidth; // var1 + int32 wordSpacingHeight; // var2 + int32 rightBorder_X; // param2 + int32 lineHeight; // fontProc1result + int32 numLines; + int32 stringHeight; + int32 stringFinished; + int32 stringWidth; // var_1C + int32 stringRenderBufferSize; + int32 useDynamicBuffer; + uint8 *currentStrRenderBuffer; + // int32 var_8; // don't need that on + int32 heightOffset; // var_12 + int32 renderBufferSize; // var_1E + int needFlip; + + if (!buffer || !string) { + return; + } + + if (fontFileIndex != -1) { + fontPtr = filesDatabase[fontFileIndex].subData.ptr; + + if (!fontPtr) { + fontPtr = _systemFNT; + } + } else { + fontPtr = _systemFNT; + } + + if (!fontPtr) { + return; + } + + fontPtr_Data = fontPtr + *(int16 *) (fontPtr + 4); + fontPtr_Desc = fontPtr + 14; + + lineHeight = getLineHeight(*(int16 *) (fontPtr + 8), fontPtr, fontPtr_Desc); // ok + + wordSpacingWidth = *(int16 *) (fontPtr + 10); + wordSpacingHeight = *(int16 *) (fontPtr + 12); + + if (inRightBorder_X > 310) { + rightBorder_X = 310; + } else { + rightBorder_X = inRightBorder_X; + } + if (x + rightBorder_X > 319) { + x = 319 - rightBorder_X; + } + if (y < 0) { + y = 0; + } + if (x < 0) { + x = 0; + } + numLines = getTextLineCount(rightBorder_X, wordSpacingWidth, fontPtr_Desc, string); // ok + + if (!numLines) { + return; + } + stringHeight = ((wordSpacingHeight + lineHeight + 2) * numLines) + 1; + + if (y + stringHeight > 199) { + y = 200 - stringHeight; + } + stringFinished = 0; + stringWidth = (rightBorder_X / 16) + 2; + stringRenderBufferSize = stringWidth * stringHeight * 4; + inRightBorder_X = rightBorder_X; + + if (stringRenderBufferSize > 0x2000) { + currentStrRenderBuffer = + (uint8 *) mallocAndZero(stringRenderBufferSize); + + if (!currentStrRenderBuffer) { + return; + } + useDynamicBuffer = 1; + } else { + currentStrRenderBuffer = (uint8 *) ptr_something; + useDynamicBuffer = 0; + } + + resetRaster(currentStrRenderBuffer, stringRenderBufferSize); + + // var_8 = 0; + heightOffset = 0; + renderBufferSize = stringRenderBufferSize; + + do { + int spacesCount = 0; // si + char character = *(string); + short int strPixelLength; // var_16; + uint8 *ptrStringEnd; // var_4 //ok + int drawPosPixel_X; // di + + while (character == ' ') { + spacesCount++; + character = *(string + spacesCount); + } + + string += spacesCount; + ptrStringEnd = string + prepareWordRender(inRightBorder_X, wordSpacingWidth, &strPixelLength, fontPtr_Desc, string); //ok + + if (inRightBorder_X > strPixelLength) { + drawPosPixel_X = + (inRightBorder_X - strPixelLength) / 2; + } else { + drawPosPixel_X = 0; + } + // drawPosPixel_X = var_8; + + do { + character = *(string++); + + short int data = fontCharacterTable[(int)character]; + + if (character) { + if (character == ' ' || character == 0x7D) { + drawPosPixel_X += var1 + 5; + } else { + if (data) { + short int *si = + (int16 *) (fontPtr_Desc + + data * 12); + //int var_2 = si[5]; + + renderWord(fontPtr_Data + + si[0], + currentStrRenderBuffer, + drawPosPixel_X, + si[4] - si[3] + + lineHeight + heightOffset, + si[3], si[2], + renderBufferSize / 2, + stringWidth * 2, si[5]); + + drawPosPixel_X += + wordSpacingWidth + si[5]; + } + } + } else { + stringFinished = 1; + } + + if (ptrStringEnd <= string) { + break; + } + + } while (!stringFinished); + + // var_8 = 0; + heightOffset = wordSpacingHeight + lineHeight; + + } while (!stringFinished); + + needFlip = 0; + + if (buffer == gfxModuleData.pPage00) { + if (gfxModuleData.field_1 != 0) { + needFlip = 1; + gfxModuleData_field_90(); + } + + gfxModuleData_gfxWaitVSync(); + } + + gfxModuleData_field_64((char *)currentStrRenderBuffer, stringWidth, + stringHeight, (char *)buffer, x, y, 0); + gfxModuleData_field_64((char *)currentStrRenderBuffer, stringWidth, + stringHeight, (char *)buffer, x, y, color); + + if (needFlip) { + gfxModuleData_flip(); + } + + if (useDynamicBuffer) { + free(currentStrRenderBuffer); + } +} + +// calculates all necessary datas and renders text +gfxEntryStruct *renderText(int inRightBorder_X, uint8 *string) { + uint8 *fontPtr; + uint8 *fontPtr_Data; // pt2 + uint8 *fontPtr_Desc; // ptr3 + int32 wordSpacingWidth; // var1 //0 or -1 + int32 wordSpacingHeight; // var2 //0 or -1 + int32 rightBorder_X; + int32 lineHeight; // fontProc1result + int32 numLines; + int32 stringHeight; + int32 stringFinished; + int32 stringWidth; // var_1C + int32 stringRenderBufferSize; + // int32 useDynamicBuffer; + uint8 *currentStrRenderBuffer; + // int32 var_8; // don't need that one + int32 heightOffset; // var_12 // how much pixel-lines have already been drawn + // int32 var_1E; + gfxEntryStruct *generatedGfxEntry; + + // check if string is empty + if (!string) { + return NULL; + } + // check if font has been loaded, else get system font + if (fontFileIndex != -1) { + fontPtr = filesDatabase[fontFileIndex].subData.ptr; + + if (!fontPtr) { + fontPtr = _systemFNT; + } + } else { + fontPtr = _systemFNT; + } + + if (!fontPtr) { + return NULL; + } + fontPtr_Data = fontPtr + *(int16 *) (fontPtr + 4); // offset to char data + fontPtr_Desc = fontPtr + 14; // offset to char description + + lineHeight = getLineHeight(*(int16 *) (fontPtr + 8), fontPtr, fontPtr_Desc); // ok + + wordSpacingWidth = *(int16 *) (fontPtr + 10); + wordSpacingHeight = *(int16 *) (fontPtr + 12); + + // if right border is higher then screenwidth (+ spacing), adjust border + if (inRightBorder_X > 310) { + rightBorder_X = 310; + } else { + rightBorder_X = inRightBorder_X; + } + numLines = getTextLineCount(rightBorder_X, wordSpacingWidth, fontPtr_Desc, string); // ok + + if (!numLines) { + return NULL; + } + + stringHeight = ((wordSpacingHeight + lineHeight + 2) * numLines) + 1; + stringFinished = 0; + stringWidth = rightBorder_X + 2; // max render width to the right + stringRenderBufferSize = stringWidth * stringHeight * 4; + inRightBorder_X = rightBorder_X; + + currentStrRenderBuffer = + (uint8 *) mallocAndZero(stringRenderBufferSize); + resetRaster(currentStrRenderBuffer, stringRenderBufferSize); + + generatedGfxEntry = (gfxEntryStruct *) malloc(sizeof(gfxEntryStruct)); + generatedGfxEntry->imagePtr = currentStrRenderBuffer; + generatedGfxEntry->imageSize = stringRenderBufferSize / 2; + generatedGfxEntry->fontIndex = fontFileIndex; + generatedGfxEntry->height = stringHeight; + generatedGfxEntry->width = stringWidth; // maximum render width to the right + + // var_8 = 0; + heightOffset = 0; + + do { + int spacesCount = 0; // si + unsigned char character = *string; + short int strPixelLength; // var_16 + uint8 *ptrStringEnd; // var_4 //ok + int drawPosPixel_X; // di + + // find first letter in string, skip all spaces + while (character == ' ') { + spacesCount++; + character = *(string + spacesCount); + } + + string += spacesCount; + + // returns character count and pixel length (via pointer) per line of the text string + ptrStringEnd = string + prepareWordRender(inRightBorder_X, wordSpacingWidth, &strPixelLength, fontPtr_Desc, string); //ok + + // determine how much space is left to the right and left (center text) + if (inRightBorder_X > strPixelLength) { + //var_8 = (inRightBorder_X - strPixelLength) / 2; + drawPosPixel_X = + (inRightBorder_X - strPixelLength) / 2; + } else { + drawPosPixel_X = 0; + } + //drawPosPixel_X = var_8; + + // draw textline, character wise + do { + character = *(string++); + + short int charData = fontCharacterTable[character]; // get character position + + if (character) { + if (character == ' ' || character == 0x7C) { + drawPosPixel_X += wordSpacingWidth + 5; // if char = "space" adjust word starting postion (don't render space though); + } else { + if (charData >= 0) { + short int *si = (int16 *) (fontPtr_Desc + charData * 12); // offset font data + // int var_2 = si[5]; // don't need this + + // should ist be stringRenderBufferSize/2 for the second last param? + renderWord(fontPtr_Data + + si[0], + currentStrRenderBuffer, + drawPosPixel_X, + si[4] - si[3] + + lineHeight + heightOffset, + si[3], si[2], + stringRenderBufferSize, + stringWidth / 2, si[5]); + + drawPosPixel_X += + wordSpacingWidth + si[5]; + } + } + } else { + stringFinished = 1; // character = 0x00 + } + + // check if string already reached the end + if (ptrStringEnd <= string) { + break; + } + } while (!stringFinished); + + // var_8 = 0; + heightOffset += wordSpacingHeight + lineHeight; + } while (!stringFinished); + + return generatedGfxEntry; +} + +} // End of namespace Cruise diff --git a/engines/cruise/font.h b/engines/cruise/font.h new file mode 100644 index 0000000000..b4533f2e43 --- /dev/null +++ b/engines/cruise/font.h @@ -0,0 +1,52 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_FONT_H +#define CRUISE_FONT_H + +namespace Cruise { + +void loadFNT(const void *fileName); +void loadSystemFont(void); + +////////////////////////////////////////////////// +void flipShort(int16 * var); +void flipShort(uint16 * var); +void flipLong(int32 * var); // TODO: move away +void flipLong(uint32 * var); // TODO: move away +void flipGen(void *var, int32 length); + +int32 getLineHeight(int16 charCount, uint8 * fontPtr, uint8 * fontPrt_Desc); // fontProc1 +int32 getTextLineCount(int32 rightBorder_X, int32 wordSpacingWidth, uint8 * ptr, uint8 * textString); // fontProc2 + +void renderWord(uint8 * fontPtr_Data, uint8 * outBufferPtr, + int32 drawPosPixel_X, int32 heightOff, int32 height, int32 param4, + int32 stringRenderBufferSize, int32 width, int32 charWidth); +gfxEntryStruct *renderText(int inRightBorder_X, uint8 * string); +void drawString(int32 x, int32 y, uint8 * string, uint8 * buffer, uint8 color, + int32 inRightBorder_X); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/fontCharacterTable.cpp b/engines/cruise/fontCharacterTable.cpp new file mode 100644 index 0000000000..20badd7953 --- /dev/null +++ b/engines/cruise/fontCharacterTable.cpp @@ -0,0 +1,194 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +int16 fontCharacterTable[256] = { + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + 106, 105, + -1, + -1, + -1, + -1, + 107, 108, + -1, -1, + 109, 110, + -1, + -1, + -1, + -1, + -1, -1, + 111, -1, + 112, + -1, -1, + 113, + 114, + -1, + -1, + 116, 93, + -1, + 118, + -1, + 94, + -1, + 117, + 115, + 96, + 95, + 97, + 98, + -1, + -1, + 99, + 100, + -1, + -1, + -1, + -1, + 101, + -1, + 102, + -1, + -1, + 103, + -1, + 104, + -1, + -1, + -1, + -1, +}; + +} // End of namespace Cruise diff --git a/backends/platform/PalmOS/Src/missing/assert.h b/engines/cruise/fontCharacterTable.h index 7bc571ec15..b45a47e89d 100644 --- a/backends/platform/PalmOS/Src/missing/assert.h +++ b/engines/cruise/fontCharacterTable.h @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,13 +22,12 @@ * */ -#ifndef __ASSERT_H__ -#define __ASSERT_H__ +#ifndef CRUISE_FONTCHARACTERTABLE_H +#define CRUISE_FONTCHARACTERTABLE_H -#ifdef _DEBUG -#define assert(a) ErrFatalDisplayIf(!(a), "Assertion failed: " #a) -#else -#define assert(a) (void)0 -#endif +namespace Cruise { + +extern short int fontCharacterTable[256]; +} // End of namespace Cruise #endif diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp new file mode 100644 index 0000000000..73e1bd9084 --- /dev/null +++ b/engines/cruise/function.cpp @@ -0,0 +1,1523 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" +#include "cruise/cell.h" +#include "common/util.h" + +namespace Cruise { + +opcodeFunction opcodeTablePtr[256]; + +int16 Op_LoadOverlay(void) { + uint8 *originalScriptName; + uint8 scriptName[38]; + int returnValue; + + scriptName[0] = 0; + + originalScriptName = (uint8 *) popPtr(); + + if (originalScriptName) { + strcpyuint8(scriptName, originalScriptName); + } + + if (!scriptName[0] || !originalScriptName) { + return (0); + } + + strToUpper(scriptName); + + //gfxModuleData.field_84(); + //gfxModuleData.field_84(); + + returnValue = loadOverlay(scriptName); + + updateAllScriptsImports(); + + strcpyuint8(scriptNameBuffer, scriptName); + + return (returnValue); +} + +int16 Op_strcpy(void) { + char *ptr1 = (char *)popPtr(); + char *ptr2 = (char *)popPtr(); + + //printf("strcpy %s\n",ptr1); + + while (*ptr1) { + *ptr2 = *ptr1; + + ptr2++; + ptr1++; + } + + *ptr2 = 0; + + return (0); +} + +int16 Op_startScript(void) { + int scriptIdx; + int ovlIdx; + uint8 *ptr; + uint8 *ptr2; + + short int popTable[256]; // TODO: check original size; + + int numOfArgToPop = popVar(); + + int i = 0; + + for (i = 0; i < numOfArgToPop; i++) { + popTable[numOfArgToPop - i - 1] = popVar(); + } + + scriptIdx = popVar(); + ovlIdx = popVar(); + + if (!ovlIdx) { + ovlIdx = currentScriptPtr->overlayNumber; + } + + ptr = attacheNewScriptToTail(ovlIdx, &procHead, scriptIdx, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_MinusPROC); + + if (!ptr) + return (0); + + if (numOfArgToPop <= 0) { + return (0); + } + + ptr2 = ptr; + + for (i = 0; i < numOfArgToPop; i++) { + saveShort(ptr2, popTable[i]); + ptr2 += 2; + } + + return (0); +} + +int16 Op_AddProc(void) { + int pop1 = popVar(); + int pop2; + int overlay; + + if (pop1 - 1 > 0) { + printf("Unsuported arg pop in Op_6!\n"); + exit(1); + } + + pop2 = popVar(); + overlay = popVar(); + + if (!overlay) + overlay = currentScriptPtr->overlayNumber; + + if (!overlay) + return (0); + + attacheNewScriptToTail(overlay, &procHead, pop2, currentScriptPtr->type, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, scriptType_PROC); + + if (pop1 > 0) { + printf("Unsupported art send in op6!\n"); + exit(1); + } + + return (0); +} + +int16 Op_37(void) { + int pop1 = popVar(); + int pop2 = popVar(); + + if (!pop2) + pop2 = currentScriptPtr->overlayNumber; + + var30 = pop2; + var31 = pop1; + + return (0); +} + +int16 Op_GetMouseX(void) { // TODO: implement properly + int16 dummy; + int16 mouseX; + int16 mouseY; + int16 mouseButton; + + getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY); + + return (mouseX); +} + +int16 Op_GetMouseY(void) { // TODO: implement properly + int16 dummy; + int16 mouseX; + int16 mouseY; + int16 mouseButton; + + getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY); + + return (mouseY); +} + +int16 Op_rand(void) { // TODO: implement + int var = popVar(); + + if (var < 2) { + return (0); + } + + return (rand() % var); +} + +int16 Op_PlayFX(void) { // TODO: implement + popVar(); + popVar(); + popVar(); + popVar(); + + // printf("Op_PlayFX, implement (sound related)\n"); + + return (0); +} + +int16 Op_freeAllPerso(void) { + freeAllPerso(); + return (0); +} + +void freeObjectList(cellStruct *pListHead) { + int var_2 = 0; + cellStruct *pCurrent = pListHead->next; + + while (pCurrent) { + cellStruct *pNext = pCurrent->next; + + if (pCurrent->freeze == 0) { + free(pCurrent->gfxPtr); + free(pCurrent); + } + + var_2 = 1; + + pCurrent = pNext; + } + + if (var_2) { + resetPtr(pListHead); + } +} + +int16 Op_FreeCell(void) { + freeObjectList(&cellHead); + return (0); +} + +int16 Op_freeBackgroundInscrustList(void) { + freeBackgroundIncrustList(&backgroundIncrustHead); + return (0); +} + +int16 Op_removeBackground(void) { + int backgroundIdx; + + backgroundIdx = popVar(); + + printf("Op_removeBackground: remove background %d\n", backgroundIdx); + return (0); +} + +int16 Op_freeMediumVar(void) { + // TODO: implement + printf("Op_freeMediumVar, implement\n"); + return (0); +} + +int16 Op_RemoveMessage(void) { + int idx; + int overlay; + + idx = popVar(); + overlay = popVar(); + + if (!overlay) { + overlay = currentScriptPtr->overlayNumber; + } + + removeCell(&cellHead, overlay, idx, 5, currentActiveBackgroundPlane); + + return (0); +} + +int16 Op_isFileLoaded(void) { + int16 i; + uint8 name[36] = ""; + uint8 *ptr; + + ptr = (uint8 *) popPtr(); + + if (!ptr) { + return -1; + } + + strcpyuint8(name, ptr); + strToUpper(name); + + for (i = 0; i < 257; i++) { + if (!strcmpuint8(name, filesDatabase[i].subData.name)) { + return (i); + } + } + + return -1; +} + +int16 Op_RemoveFrame(void) { + //int var1; + //int var2; + + var1 = popVar(); + var2 = popVar(); + + resetFileEntryRange(var2, var1); + + return (0); +} + +int16 Op_comment(void) { + char *var; + + var = (char *)popPtr(); + + printf("COMMENT: \"%s\"\n", var); + + return (0); +} + +int16 Op_RemoveProc(void) { + int idx; + int overlay; + + idx = popVar(); + overlay = popVar(); + + if (!overlay) { + overlay = currentScriptPtr->overlayNumber; + } + + removeScript(overlay, idx, &procHead); + + return (0); +} + +int16 Op_FreeOverlay(void) { + uint8 localName[36] = ""; + uint8 *namePtr; + + namePtr = (uint8 *) popPtr(); + + strcpyuint8(localName, namePtr); + + if (localName[0]) { + strToUpper(localName); + releaseOverlay((char *)localName); + } + + return 0; +} + +int16 Op_2B(void) { + uint8 name[36] = ""; + uint8 *ptr; + int param; + + ptr = (uint8 *) popPtr(); + + strcpyuint8(name, ptr); + + param = getProcParam(popVar(), 20, name); + + return param; +} + +int16 Op_freeAllMenu(void) { + // TODO: implement + printf("Op_freeAllMenu, implement\n"); + + return 0; +} + +int16 Op_PlayFXnterPlayerMenu(void) { + int oldValue = entrerMenuJoueur; + entrerMenuJoueur = popVar(); + + return oldValue; +} + +int16 Op_ChangeSaveAllowedState(void) { + int oldValue = userEnabled; + int newValue = popVar(); + + if (newValue != -1) { + userEnabled = newValue; + } + + return oldValue; +} + +int16 Op_changeCutSceneState(void) { + int oldValue = affichePasMenuJoueur; + int newValue = popVar(); + + if (newValue != -1) { + affichePasMenuJoueur = newValue; + } + + return oldValue; +} + +int16 Op_62(void) { + if (currentScriptPtr->var1A == 20) { + changeScriptParamInList(currentScriptPtr->var18, + currentScriptPtr->var16, &procHead, 9997, -1); + } else if (currentScriptPtr->var1A == 30) { + changeScriptParamInList(currentScriptPtr->var18, + currentScriptPtr->var16, &relHead, 9997, -1); + } + + return 0; +} + +int16 Op_LoadBackground(void) { + int result = 0; + uint8 bgName[36] = ""; + uint8 *ptr; + int bgIdx; + + ptr = (uint8 *) popPtr(); + + strcpyuint8(bgName, ptr); + + bgIdx = popVar(); + + if (bgIdx >= 0 || bgIdx < 8) { + strToUpper(bgName); + + gfxModuleData_gfxWaitVSync(); + gfxModuleData_gfxWaitVSync(); + + result = loadBackground((char *)bgName, bgIdx); + } + + changeCursor(0); + + return result; +} + +int16 Op_isFileLoaded2(void) { + int param; + + param = popVar(); + + if (param < 0 || param > 255) { + return 0; + } + + if (filesDatabase[param].subData.ptr) { + return 1; + } + + return 0; +} + +int16 Op_loadFile(void) { + int param1; + int param2; + int param3; + uint8 name[36] = ""; + uint8 *ptr; + + ptr = (uint8 *) popPtr(); + + strcpyuint8(name, ptr); + + param1 = popVar(); + param2 = popVar(); + param3 = popVar(); + + if (param3 >= 0 || param3 < 257) { + strToUpper(name); + + gfxModuleData_gfxWaitVSync(); + gfxModuleData_gfxWaitVSync(); + + saveVar6[0] = 0; + + loadFileMode2(name, param3, param2, param1); + + saveVar6[0] = 0; + } + + changeCursor(0); + return 0; +} + +int16 Op_LoadAbs(void) { + int param1; +// int param2; +// int param3; + uint8 name[36] = ""; + uint8 *ptr; + int result = 0; + + ptr = (uint8 *) popPtr(); + + strcpyuint8(name, ptr); + + param1 = popVar(); + + if (param1 >= 0 || param1 < 257) { + strToUpper(name); + + gfxModuleData_gfxWaitVSync(); + gfxModuleData_gfxWaitVSync(); + + result = loadFullBundle(name, param1); + } + + changeCursor(0); + return result; +} + +int16 Op_InitializeState(void) { + int param1 = popVar(); + int objIdx = popVar(); + int ovlIdx = popVar(); + + if (!ovlIdx) + ovlIdx = currentScriptPtr->overlayNumber; + + objInit(ovlIdx, objIdx, param1); + + return (0); +} + +int16 Op_GetInitVar1(void) { + return initVar1; +} + +int16 Op_FadeOut(void) { + printf("Op_FadeOut dummy\n"); + return 0; +} + +int16 isOverlayLoaded(uint8 * name) { + int16 i; + + for (i = 1; i < numOfLoadedOverlay; i++) { + if (!strcmpuint8(overlayTable[i].overlayName, name) + && overlayTable[i].alreadyLoaded) { + return i; + } + } + + return 0; +} + +int16 Op_FindOverlay(void) { + uint8 name[36] = ""; + uint8 *ptr; + + ptr = (uint8 *) popPtr(); + + strcpyuint8(name, ptr); + strToUpper(name); + + return (isOverlayLoaded(name)); +} + +int16 Op_2C(void) { + int16 returnParam; + + int16 param1 = popVar(); + int16 param2 = popVar(); + int16 param3 = popVar(); + int16 param4 = popVar(); + + getSingleObjectParam(param4, param3, param2, &returnParam); + setObjectPosition(param4, param3, param2, param1); + + return returnParam; +} + +int16 Op_FadeIn(void) { + main5 = 1; + return 0; +} + +int16 Op_GetMouseClick3(void) { + int16 dummy; + int16 mouseX; + int16 mouseY; + int16 mouseButton; + + getMouseStatus(&dummy, &mouseX, &mouseButton, &mouseY); + + if (mouseButton & 4) + return 1; + return 0; +} + +int16 Op_AddCell(void) { + int16 objType = popVar(); + int16 objIdx = popVar(); + int16 overlayIdx = popVar(); + + if (!overlayIdx) + overlayIdx = currentScriptPtr->overlayNumber; + + addCell(&cellHead, overlayIdx, objIdx, objType, currentActiveBackgroundPlane, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type); + + return 0; +} + +int16 Op_AddBackgroundIncrust(void) { + + int16 objType = popVar(); + int16 objIdx = popVar(); + int16 overlayIdx = popVar(); + + if (!overlayIdx) + overlayIdx = currentScriptPtr->overlayNumber; + + addBackgroundIncrust(overlayIdx, objIdx, &backgroundIncrustHead, currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, currentActiveBackgroundPlane, objType); + + return 0; +} + +int16 Op_RemoveCell(void) { + int objType = popVar(); + int objectIdx = popVar(); + int ovlNumber = popVar(); + + if (!ovlNumber) { + ovlNumber = currentScriptPtr->overlayNumber; + } + + removeCell(&cellHead, ovlNumber, objectIdx, objType, currentActiveBackgroundPlane); + + return 0; +} + +int16 fontFileIndex; + +int16 Op_SetFontFileIndex(void) { + fontFileIndex = popVar(); + + return 0; +} + +int16 Op_63(void) { + if (currentScriptPtr->var1A == 0x14) { + changeScriptParamInList(currentScriptPtr->var18, + currentScriptPtr->var16, &procHead, 0, -1); + } else if (currentScriptPtr->var1A == 0x1E) { + changeScriptParamInList(currentScriptPtr->var18, + currentScriptPtr->var16, &relHead, 0, -1); + } + + return 0; +} + +int16 op7CVar = 0; + +int16 Op_InitializeStateC(void) { + int16 temp = op7CVar; + int16 newVar; + + newVar = popVar(); + if (newVar != -1) { + op7CVar = newVar; + } + return temp; +} + +int16 Op_AddMessage(void) { + int16 color = popVar(); + int16 var_2 = popVar(); + int16 var_4 = popVar(); + int16 var_6 = popVar(); + int16 var_8 = popVar(); + int16 overlayIdx = popVar(); + + if (!overlayIdx) + overlayIdx = currentScriptPtr->overlayNumber; + + if (color == -1) { + color = 0; + ASSERT(0); + //color = calcTabSomething(); + } else { + if (CVTLoaded) { + color = cvtPalette[color]; + } + } + + createTextObject(overlayIdx, var_8, &cellHead, + currentScriptPtr->scriptNumber, currentScriptPtr->overlayNumber, + currentActiveBackgroundPlane, color, var_2, var_4, var_6); + + return 0; +} + +int16 Op_loadAudioResource(void) { + popPtr(); + popVar(); + + return 0; +} + +int16 Op_LoadCt(void) { + return loadCtp((uint8 *) popPtr()); +} + +int16 Op_loadMusic(void) { + popPtr(); + return 0; +} + +int16 Op_21(void) { + int param1 = popVar(); + int param2 = popVar(); + int overlay = popVar(); + + if (!overlay) + overlay = currentScriptPtr->overlayNumber; + + return mainProc13(overlay, param2, &actorHead, param1); +} + +int16 Op_InitializeState6(void) { + popPtr(); + popVar(); + + return 0; +} + +int16 Op_AutoCell(void) { + cellStruct *pObject; + + int signal = popVar(); + int loop = popVar(); + int wait = popVar(); + int animStep = popVar(); + int end = popVar(); + int start = popVar(); + int type = popVar(); + int change = popVar(); + int obj = popVar(); + int overlay = popVar(); + + if (!overlay) + overlay = currentScriptPtr->overlayNumber; + + pObject = addCell(&cellHead, overlay, obj, 4, currentActiveBackgroundPlane, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, currentScriptPtr->type); + + if (!pObject) + return 0; + + pObject->animSignal = signal; + pObject->animLoop = loop; + pObject->animWait = wait; + pObject->animStep = animStep; + pObject->animEnd = end; + pObject->animStart = start; + pObject->animType = type; + pObject->animChange = change; + + if (type) { + if (currentScriptPtr->type == scriptType_PROC) { + changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &procHead, 9996, -1); + } else if (currentScriptPtr->type == scriptType_REL) { + changeScriptParamInList(currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber, &relHead, 9996, -1); + } + } + + if (change == 5) { + objInit(pObject->overlay, pObject->idx, start); + } else { + setObjectPosition(pObject->overlay, pObject->idx, pObject->animChange, start); + } + + if (wait < 0) { + objectParamsQuery params; + + getMultipleObjectParam(overlay, obj, ¶ms); + pObject->animCounter = params.var6 - 1; + } + + return 0; +} + +int16 Op_66(void) { + objectParamsQuery params; + int index = popVar(); + int overlay = popVar(); + + if (!overlay) + overlay = currentScriptPtr->overlayNumber; + + getMultipleObjectParam(overlay, index, ¶ms); + + return params.var7 - 1; +} + +int16 Op_SetActiveBackgroundPlane(void) { + int currentPlane = currentActiveBackgroundPlane; + int newPlane = popVar(); + + if (newPlane >= 0 && newPlane < 8) { + if (backgroundPtrtable[newPlane]) { + currentActiveBackgroundPlane = newPlane; + initVar3 = 1; + } + } + + return currentPlane; +} + +int op6AVar; + +int16 Op_6A(void) { + op6AVar = popVar(); + return 0; +} + +int op7BVar = 0; + +int16 Op_InitializeStateB(void) { + int di = popVar(); + int si = 1 - op7BVar; + int sign; + + if (di) { + sign = di / (ABS(di)); + } else { + sign = 0; + } + + op7BVar = -sign; + + return si; +} + +int16 Op_RemoveBackgroundIncrust(void) { + int idx = popVar(); + int overlay = popVar(); + + if (!overlay) { + overlay = currentScriptPtr->overlayNumber; + } + + removeBackgroundIncrust(overlay, idx, &backgroundIncrustHead); + + return 0; +} + +int16 Op_SetColor(void) { + int colorB = popVar(); + int colorG = popVar(); + int colorR = popVar(); + int endIdx = popVar(); + int startIdx = popVar(); + + int i; + + int R,G,B; + +#define convertRatio 36.571428571428571428571428571429 + + for(i=startIdx; i<=endIdx; i++) { + R = (int)(colorR*convertRatio); + G = (int)(colorG*convertRatio); + B = (int)(colorB*convertRatio); + + if (R > 0xFF) + R = 0xFF; + if (G > 0xFF) + G = 0xFF; + if (B > 0xFF) + B = 0xFF; + + if (CVTLoaded) { + int colorIdx = cvtPalette[i]; + gfxModuleData_setPalColor(colorIdx, R, G, B); + } else { + gfxModuleData_setPalColor(i, R, G, B); + } + } + + return 0; +} + +int16 Op_InitializeState8(void) { + int si = var41; + + var41 = popVar(); + + return si; +} + +int16 Op_releaseOverlay(void) { + int overlayIdx; + + overlayIdx = popVar(); + + if (strlen(overlayTable[overlayIdx].overlayName)) { + releaseOverlay(overlayTable[overlayIdx].overlayName); + } + + return 0; +} + +int16 Op_SetColorrawLine(void) { + /* + * int di = popVar(); + * int var_2 = popVar(); + * int var_4 = popVar(); + * int var_6 = popVar(); + * uint8* ptr = (uint8*)popPtr(); + */ + + popVar(); + popVar(); + popVar(); + popVar(); + popPtr(); + + //drawLinePtr(var_6, var_4, var_2, ptr); + + // flipGen(ptr); + + return 0; +} + +int16 Op_61(void) { + int si = popVar(); + popVar(); + + return si; +} + +int16 Op_SetZoom(void) { + var46 = popVar(); + var45 = popVar(); + var42 = popVar(); + var39 = popVar(); + return 0; +} + +int16 computeZoom(int param) { + return (((param - var46) * (var39 - var42)) / (var45 - var46)) + var42; +} + +int16 subOp23(int param1, int param2) { + return (param1 * param2) >> 8; +} + +int16 Op_23(void) { + int si = popVar(); + int dx = popVar(); + + return subOp23(dx, si); +} + +int16 Op_22(void) { + return (computeZoom(popVar())); +} + +actorStruct *addAnimation(actorStruct * pHead, int overlay, int objIdx, int param, int param2) { + actorStruct *pPrevious = pHead; + actorStruct *pCurrent = pHead->next; + + // go to the end of the list + while (pCurrent) { + pPrevious = pCurrent; + pCurrent = pPrevious->next; + } + + if (pCurrent && (pCurrent->overlayNumber == overlay) + && (pCurrent->idx == objIdx) && (pCurrent->type == param2)) { + return NULL; + } + + actorStruct *pNewElement = (actorStruct *) malloc(sizeof(actorStruct)); + if (!pNewElement) + return NULL; + + pNewElement->next = pPrevious->next; + pPrevious->next = pNewElement; + + if (!pCurrent) { + pCurrent = pHead; + } + + pNewElement->prev = pCurrent->prev; + pCurrent->prev = pNewElement; + + pNewElement->idx = objIdx; + pNewElement->type = param2; + pNewElement->pathId = -1; + pNewElement->overlayNumber = overlay; + pNewElement->startDirection = param; + pNewElement->nextDirection = -1; + pNewElement->stepX = 5; + pNewElement->stepY = 2; + pNewElement->phase = ANIM_PHASE_WAIT; + pNewElement->flag = 0; + pNewElement->freeze = 0; + + return pNewElement; +} + +int removeAnimation(actorStruct * pHead, int overlay, int objIdx, int objType) +{ + actorStruct* pl; + actorStruct* pl2; + actorStruct* pl3; + actorStruct* pl4; + + int dir = 0; + + pl = pHead; + pl2 = pl; + pl = pl2->next; + + while(pl) + { + pl2 = pl; + + if(((pl->overlayNumber == overlay) || (overlay == -1)) && + ((pl->idx == objIdx) || (objIdx == -1)) && + ((pl->type == objType) || (objType == -1))) + { + pl->type = -1; + } + + pl = pl2->next; + } + + pl = pHead; + pl2 = pl; + pl = pl2->next; + + while(pl) + { + if(pl->type == -1) + { + pl4 = pl->next; + pl2->next = pl4; + pl3 = pl4; + + if(pl3 == NULL) + pl3 = pHead; + + pl3->prev = pl->prev; + + dir = pl->startDirection; + + if(pl->idx >= 0) + freePerso(pl->idx); + + free(pl); + pl = pl4; + } + else + { + pl2 = pl; + pl = pl2->next; + } + } + + return dir; +} + +int flag_obstacle; // computedVar14Bis + +void checkCollisionWithWalkBoxesBoundingBoxes(int x, int y) { + ctpVar19Struct *di = ctpVar19; + + do { + int minX; + int maxX; + int minY; + int maxY; + + ctpVar19SubStruct *subStruct; + + if ((ctpVar19Struct *)-1 == di->field_0) { // ok, ugly, but it's in the original + flag_obstacle = 0; + return; + } + + subStruct = &di->subStruct; + + minX = subStruct->minX; + maxX = subStruct->maxX; + minY = subStruct->minY; + maxY = subStruct->maxY; + + computedVar14 = subStruct->boxIdx; // Box index + + if (!(walkboxChange[subStruct->boxIdx]) && (minY >= x) + && (maxY <= x) && (minX >= y) && (maxX <= y)) { + /**************/ + + flag_obstacle = walkboxType[computedVar14]; + + /**************/ + } + + di = di->field_0; + } while (1); + + flag_obstacle = 0; +} + +// add animation +int16 Op_AddAnimation(void) { + int stepY = popVar(); + int stepX = popVar(); + int direction = popVar(); + int start = popVar(); + int type = popVar(); + int obj = popVar(); + int overlay = popVar(); + + if (!overlay) { + overlay = currentScriptPtr->overlayNumber; + } + + if (direction >= 0 && direction <= 3) { + actorStruct *si; + + si = addAnimation(&actorHead, overlay, obj, direction, type); + + if (si) { + objectParamsQuery params; + + getMultipleObjectParam(overlay, obj, ¶ms); + + si->x = params.X; + si->y = params.Y; + si->x_dest = -1; + si->y_dest = -1; + si->endDirection = -1; + si->start = start; + si->stepX = stepX; + si->stepY = stepY; + + int newFrame = ABS(raoul_end[direction][0]) - 1; + + int zoom = computeZoom(params.Y); + + if (raoul_end[direction][0] < 0) { + zoom = -zoom; + } + + checkCollisionWithWalkBoxesBoundingBoxes(params.X, params.Y); + + setObjectPosition(overlay, obj, 3, newFrame + start); + setObjectPosition(overlay, obj, 4, zoom); + setObjectPosition(overlay, obj, 5, computedVar14); + + animationStart = false; + } + } + + return 0; +} + +int16 Op_RemoveAnimation(void) { + int objType = popVar(); + int objIdx = popVar(); + int ovlIdx = popVar(); + + if (!ovlIdx) { + ovlIdx = currentScriptPtr->overlayNumber; + } + + return removeAnimation(&actorHead, ovlIdx, objIdx, objType); +} + +int16 Op_regenerateBackgroundIncrust(void) { + regenerateBackgroundIncrust(&backgroundIncrustHead); + return 0; +} + +int16 Op_SetStringColors(void) { + // TODO: here ignore if low color mode + + colorOfSelectedSaveDrive = (uint8) popVar(); + video2 = (uint8) popVar(); + video3 = (uint8) popVar(); + video4 = (uint8) popVar(); + + return 0; +} + +int16 Op_1E(void) { // setup actor position + actorStruct *pActor; + + var0 = popVar(); + int actorY = popVar(); + int actorX = popVar(); + var1 = popVar(); + var2 = popVar(); + int overlay = popVar(); + + if (!overlay) { + overlay = currentScriptPtr->overlayNumber; + } + + pActor = findActor(overlay, var2, &actorHead, var1); + + if (!pActor) { + return 1; + } + + animationStart = false; + + pActor->x_dest = actorX; + pActor->y_dest = actorY; + pActor->flag = 1; + pActor->endDirection = var0; + + return 0; +} + +int16 Op_45(void) { + printf("Partial op 45 stop sound\n"); + + return 0; +} + +int16 Op_AddCellC(void) { + popPtr(); + popVar(); + + printf("Partial op 5C\n"); + + return 0; +} + +int16 Op_AddCellE(void) { + popVar(); + + printf("Partial op 5E (sound related)\n"); + + return 0; +} + +int16 Op_3E(void) { + printf("Partial op 3E (sound related)\n"); + + return 0; +} + +void setVar49Value(int value) { + flagCt = value; +} + +int16 Op_3A(void) { + setVar49Value(1); + return 0; +} + +int16 Op_3B(void) { + setVar49Value(0); + return 0; +} + +int16 Op_3F(void) { + printf("Partial op 3F (sound related)\n"); + return 0; +} + +int16 Op_40(void) { + printf("Partial op 40 (sound related)\n"); + //freeStuff1(); + freeStuff2(); + + var24 = 0; + var23 = 0; + return 0; +} + +int16 Op_6C(void) { + //int var0; + //int var1; + int temp; + + var0 = popVar(); + var1 = popVar(); + + if (!var1) { + var1 = currentScriptPtr->overlayNumber; + } + + temp = overlayTable[var1].executeScripts; + overlayTable[var1].executeScripts = var0; + + return temp; +} + +int16 Op_FreezeCell(void) { + int newFreezz = popVar(); + int oldFreeze = popVar(); + int backgroundPlante = popVar(); + int objType = popVar(); + int objIdx = popVar(); + int overlayIdx = popVar(); + + if (!overlayIdx) { + overlayIdx = currentScriptPtr->overlayNumber; + } + + freezeCell(&cellHead, overlayIdx, objIdx, objType, backgroundPlante, oldFreeze, newFreezz); + + return 0; +} + +void Op_60Sub(int overlayIdx, actorStruct * pActorHead, int _var0, int _var1, + int _var2, int _var3) { + actorStruct *pActor = findActor(overlayIdx, _var0, pActorHead, _var3); + + if (pActor) { + if ((pActor->freeze == _var2) || (_var2 == -1)) { + pActor->freeze = _var1; + } + } +} + +int16 Op_60(void) { + /* + * int var0; + * int var1; + * int var2; + * int var3; + * int var4; + */ + + var0 = popVar(); + var1 = popVar(); + var2 = popVar(); + var3 = popVar(); + var4 = popVar(); + + if (!var4) { + var4 = currentScriptPtr->overlayNumber; + } + + Op_60Sub(var4, &actorHead, var3, var0, var1, var2); + + return 0; +} + +int16 Op_6F(void) { + int numArgs = popVar(); + + assert(numArgs == 0); + + { + popVar(); + char *string = (char *)popPtr(); + + printf("partial opcode 6F sprintf (%s)\n", string); + } + + return 0; +} + +int16 Op_6E(void) { + char *ptr0 = (char *)popPtr(); + char *ptr1 = (char *)popPtr(); + + printf("partial opcode 6E (%s)(%s)\n", ptr0, ptr1); + + return 0; +} + +int16 Op_InitializeState2(void) { + var0 = popVar(); + char *ptr = (char *)popPtr(); + var1 = popVar(); + + if (!var1) + var1 = currentScriptPtr->overlayNumber; + + return getProcParam(var1, var0, (uint8 *) ptr); +} + +int16 Op_2A(void) { + char var_26[36]; + char *ptr = (char *)popPtr(); + int overlayIdx; + + var_26[0] = 0; + + if (ptr) { + strcpy(var_26, ptr); + } + + overlayIdx = popVar(); + + if (!overlayIdx) + overlayIdx = currentScriptPtr->overlayNumber; + + return getProcParam(overlayIdx, 40, (uint8 *) var_26); +} + +void setupOpcodeTable(void) { + int i; + + for (i = 0; i < 256; i++) { + opcodeTablePtr[i] = NULL; + } + + opcodeTablePtr[0x1] = Op_FadeIn; + opcodeTablePtr[0x2] = Op_FadeOut; + opcodeTablePtr[0x3] = Op_LoadBackground; + opcodeTablePtr[0x4] = Op_LoadAbs; + opcodeTablePtr[0x5] = Op_AddCell; + opcodeTablePtr[0x6] = Op_AddProc; + opcodeTablePtr[0x7] = Op_InitializeState; + opcodeTablePtr[0x8] = Op_RemoveCell; + opcodeTablePtr[0x9] = Op_FreeCell; + opcodeTablePtr[0xA] = Op_RemoveProc; + opcodeTablePtr[0xB] = Op_RemoveFrame; + opcodeTablePtr[0xC] = Op_LoadOverlay; + opcodeTablePtr[0xD] = Op_SetColor; + opcodeTablePtr[0xE] = Op_PlayFX; + opcodeTablePtr[0xF] = NULL; // used to be debug + opcodeTablePtr[0x10] = Op_FreeOverlay; + opcodeTablePtr[0x11] = Op_FindOverlay; + opcodeTablePtr[0x12] = NULL; // used to be exec debug + opcodeTablePtr[0x13] = Op_AddMessage; + opcodeTablePtr[0x14] = Op_RemoveMessage; + opcodeTablePtr[0x15] = NULL; // user wait + opcodeTablePtr[0x16] = Op_FreezeCell; + opcodeTablePtr[0x17] = Op_LoadCt; + opcodeTablePtr[0x18] = Op_AddAnimation; + opcodeTablePtr[0x19] = Op_RemoveAnimation; + opcodeTablePtr[0x1A] = Op_SetZoom; + opcodeTablePtr[0x1E] = Op_1E; + opcodeTablePtr[0x21] = Op_21; + opcodeTablePtr[0x22] = Op_22; + opcodeTablePtr[0x24] = Op_SetStringColors; + opcodeTablePtr[0x28] = Op_ChangeSaveAllowedState; + opcodeTablePtr[0x29] = Op_freeAllPerso; + opcodeTablePtr[0x2A] = Op_2A; + opcodeTablePtr[0x2B] = Op_2B; + opcodeTablePtr[0x2C] = Op_2C; + opcodeTablePtr[0x2E] = Op_releaseOverlay; + opcodeTablePtr[0x2F] = Op_AddBackgroundIncrust; + opcodeTablePtr[0x30] = Op_RemoveBackgroundIncrust; + opcodeTablePtr[0x32] = Op_freeBackgroundInscrustList; + opcodeTablePtr[0x37] = Op_37; + opcodeTablePtr[0x38] = Op_removeBackground; + opcodeTablePtr[0x39] = Op_SetActiveBackgroundPlane; + opcodeTablePtr[0x3A] = Op_3A; + opcodeTablePtr[0x3B] = Op_3B; + opcodeTablePtr[0x3C] = Op_rand; + opcodeTablePtr[0x3D] = Op_loadMusic; + opcodeTablePtr[0x3E] = Op_3E; + opcodeTablePtr[0x3F] = Op_3F; + opcodeTablePtr[0x40] = Op_40; + opcodeTablePtr[0x41] = Op_isFileLoaded2; + opcodeTablePtr[0x45] = Op_45; + opcodeTablePtr[0x54] = Op_SetFontFileIndex; + opcodeTablePtr[0x56] = Op_changeCutSceneState; + opcodeTablePtr[0x57] = Op_GetMouseX; + opcodeTablePtr[0x58] = Op_GetMouseY; + opcodeTablePtr[0x59] = Op_GetMouseClick3; + opcodeTablePtr[0x5A] = Op_isFileLoaded; + opcodeTablePtr[0x5B] = Op_regenerateBackgroundIncrust; + opcodeTablePtr[0x5C] = Op_AddCellC; + opcodeTablePtr[0x5E] = Op_AddCellE; + opcodeTablePtr[0x60] = Op_60; + opcodeTablePtr[0x61] = Op_61; + opcodeTablePtr[0x62] = Op_62; + opcodeTablePtr[0x63] = Op_63; + opcodeTablePtr[0x64] = Op_startScript; + opcodeTablePtr[0x65] = Op_AutoCell; + opcodeTablePtr[0x66] = Op_66; + opcodeTablePtr[0x67] = Op_loadAudioResource; + opcodeTablePtr[0x68] = Op_freeMediumVar; + opcodeTablePtr[0x6A] = Op_6A; + opcodeTablePtr[0x6B] = Op_loadFile; + opcodeTablePtr[0x6C] = Op_6C; + opcodeTablePtr[0x6D] = Op_strcpy; + opcodeTablePtr[0x6E] = Op_6E; + opcodeTablePtr[0x6F] = Op_6F; + opcodeTablePtr[0x70] = Op_comment; + opcodeTablePtr[0x71] = Op_SetColorrawLine; + opcodeTablePtr[0x72] = Op_InitializeState2; + opcodeTablePtr[0x74] = Op_GetInitVar1; + opcodeTablePtr[0x76] = Op_InitializeState6; + opcodeTablePtr[0x79] = Op_PlayFXnterPlayerMenu; + opcodeTablePtr[0x78] = Op_InitializeState8; + opcodeTablePtr[0x7B] = Op_InitializeStateB; + opcodeTablePtr[0x7C] = Op_InitializeStateC; + opcodeTablePtr[0x7D] = Op_freeAllMenu; + // TODO: copy the opcodes here +} + +int32 opcodeType8(void) { + int opcode = getByteFromScript(); + + if (!opcode) + return (-21); + + if (opcode > 0x100) + return (-21); + + if (opcodeTablePtr[opcode]) { + //printf("Function: %X\n",opcode); + pushVar(opcodeTablePtr[opcode] ()); + return (0); + } else { + printf("Unsupported opcode %X in opcode type 8\n", opcode); + // exit(1); + } + + return 0; + +} + +} // End of namespace Cruise diff --git a/backends/platform/PalmOS/Src/missing/unistd.h b/engines/cruise/function.h index 400b0e2c39..68fdfed6d0 100644 --- a/backends/platform/PalmOS/Src/missing/unistd.h +++ b/engines/cruise/function.h @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,21 +22,17 @@ * */ -#ifndef __UNISTD_H__ -#define __UNISTD_H__ - -#include "palmversion.h" +#ifndef CRUISE_FUNCTION_H +#define CRUISE_FUNCTION_H -#ifdef __cplusplus -extern "C" { -#endif +namespace Cruise { -extern const Char *gUnistdCWD; +extern int flag_obstacle; +void setupOpcodeTable(void); +int32 opcodeType8(void); +int16 computeZoom(int param); +int16 subOp23(int param1, int param2); -Char *getcwd(Char *buf, UInt32 size); - -#ifdef __cplusplus -} -#endif +} // End of namespace Cruise #endif diff --git a/engines/cruise/gfxModule.cpp b/engines/cruise/gfxModule.cpp new file mode 100644 index 0000000000..23d80a47b0 --- /dev/null +++ b/engines/cruise/gfxModule.cpp @@ -0,0 +1,659 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/system.h" + +#include "cruise/cruise_main.h" + +namespace Cruise { + +uint8 page00[320 * 200]; +uint8 page10[320 * 200]; + +char screen[320 * 200]; +palEntry lpalette[256]; +short globalAtariScreen[320 * 200 / 4]; + +int palDirtyMin = 256; +int palDirtyMax = -1; + +gfxModuleDataStruct gfxModuleData = { + 0, // field_1 + 0, // use Tandy + 0, // use EGA + 1, // use VGA + + page00, // pPage00 + page10, // pPage10 +}; + +void gfxModuleData_gfxClearFrameBuffer(uint8 *ptr) { + memset(ptr, 0, 64000); +} + +void gfxModuleData_gfxCopyScreen(char *sourcePtr, char *destPtr) { + memcpy(destPtr, sourcePtr, 64000); +} + +void outputBit(char *buffer, int bitPlaneNumber, uint8 data) { + *(buffer + (8000 * bitPlaneNumber)) = data; +} + +void gfxModuleData_field_60(char *sourcePtr, int width, int height, + char *destPtr, int x, int y) { + /* + * int loc_1064; + * int loc_10AA; + * int loc_10AD; + * int loc_10C5; + * int loc_10DF; + * int loc_10EC; + * int loc_1147; + * int loc_114B; + * int loc_117C = 0xF8; + * int loc_11DC; + * int loc_1277; + * int loc_12D9; + * int loc_12DD; + * + * int loc_11E7; + * int loc_127A; + * int loc_1203; + * int loc_122B; + * int loc_117F; + * int loc_11EF; + * int loc_1217; + * int loc_12E1; + * + * int tempSwap; + * + * int cx; + * int bp; + * int bpSave; + * + * char* diPtr; + * char* siPtr; + * + * int direction = 1; + * int dx = height; + * int ax = width; + * int es = ax << 1; + * int bx = 0; + * int di = 199; + * int si; + * + * ax = y; + * si = 0; + * + * if(y>199) // out of screen vertically + * return; + * + * if(y<0) // cropped on the top + * { + * cx = bx; + * bx -= ax; + * dx -= bx; + * if(dx <= 0) + * { + * return; + * } + * ax = es; // es = size of a line ? + * ax*=(bx&0xFF); // bx number of lines to skip vertically + * si+=ax; + * ax = cx; + * } + * + * bx = ax; + * ax += dx; + * ax--; + * + * if(ax > di) + * { + * ax -= di; + * dx -= ax; + * + * if(dx <= 0) + * { + * return; + * } + * } + * + * ax = dx; + * loc_10DF = ax; + * ax = bx; + * loc_10AD = ax; + * + * bx = 0; + * di = 319; + * + * ax = x; + * dx = ax; + * cx = ax&0xFF; + * cx &= 7; + * { + * int cl = cx; + * int ch = cl; + * + * cl-=8; + * cl=-cl; + * cl&=7; + * ax = (ch<<8) | (cl); + * } + * loc_1064 = ax; + * ax = es; + * ax <<= 3; + * + * tempSwap = dx; + * dx = ax; + * ax = tempSwap; + * + * if(ax > di) + * { + * return; + * } + * + * cx = ax; + * cx += dx; + * cx --; + * + * dx >>= 3; + * + * dx = dx&0xFF; + * + * if(cx<bx) + * { + * return; + * } + * + * if(cx>di) + * { + * cx -= di; + * cx >>= 3; + * dx = (dx&0xFF00) | (((dx&0xFF) - (cx&0xFF))&0xFF); + * dx = ((cx&0xFF)<<8) | (dx&0xFF); + * di = 0xF8F9; + * } + * else + * { + * di = 0xF8F8; + * } + * + * if(ax<bx) + * { + * ax -= bx; + * ax = -ax; + * ax >>= 3; + * + * si += ax; + * dx = (dx&0xFF00) | (((dx&0xFF)-(ax&0xFF))&0xFF); + * dx = (((dx&0xFF00) + ((ax&0xFF)<<8))&0xFF00) | (dx&0xFF); + * ax = bx; + * cx = di; + * cx = (248<<8)|(cx&0xFF); + * di = cx; + * } + * + * loc_10AA = ax; + * ax = (ax&0xFF00) | (((dx&0xFF00)>>8)&0xFF); + * ax = ax&0xFF; + * loc_10C5 = ax; + * ax = (ax&0xFF00) | (dx&0xFF); + * + * dx = loc_1064; + * + * if(dx) + * { + * if(di&1) + * { + * loc_10C5++; + * } + * + * bx = ax; + * ax--; + * loc_11DC = ax; + * + * if(di&0x100) + * { + * bx--; + * } + * + * ax = bx; + * ax -= 40; + * ax = -ax; + * loc_12D9 = ax; + * ax = di; + * loc_1277 = ax&0xFF; + * ax = (ax&0xFF00) | (((ax&0xFF00)>>8)&0xFF); + * loc_117C = ax&0xFF; + * } + * else + * { + * loc_10EC = ax; + * ax -= 40; + * ax = -ax; + * loc_1147 = ax; + * } + * + * bx = loc_10AA; + * ax = loc_10AD; + * bx = ((((((bx&0xFF00)>>8)&0xFF) + (ax&0xFF))<<8)&0xFF00) | (bx&0xFF); + * + * bx>>=3; + * ax<<=3; + * + * bx+=ax; + * + * diPtr = destPtr; + * diPtr += bx; + * + * ax = loc_10C5; + * ax<<=2; + * loc_114B = ax; + * loc_12DD = ax; + * ax = si; + * ax <<=2; + * siPtr = sourcePtr; + * + * siPtr+=ax; + * + * bp = loc_10DF; + * bx = dx; + * dx = 974; + * + * if(!bx) // no crop ? + * { + * do // for each line + * { + * bpSave = bp; + * cx = loc_10EC; + * + * do // for the line + * { + * outputBit(diPtr,0,*(siPtr)); + * outputBit(diPtr,1,*(siPtr+1)); + * outputBit(diPtr,2,*(siPtr+2)); + * outputBit(diPtr,3,*(siPtr+3)); + * + * siPtr+=4; + * diPtr++; + * }while(--cx); + * + * diPtr += loc_1147; // interline + * siPtr += loc_114B; + * bp = bpSave; + * }while(--bp); + * } + * else // croped + * { + * ASSERT(0); + * loc_1156: + * ax = (ax&0xFF00) | bx&0xFF; + * loc_11E7 = ax&0xFF; + * loc_127A = ax&0xFF; + * loc_1203 = ax&0xFF; + * loc_122B = ax&0xFF; + * + * ax = (ax&0xFF00) | (((bx&0xFF00)>>8)&0xFF); + * loc_117F = ax&0xFF; + * loc_11EF = ax&0xFF; + * loc_1217 = ax&0xFF; + * + * do // main copy loop + * { + * ax = bp; + * loc_12E1 = ax; + * + * if(loc_117C == 0xF8) + * { + * direction = 1; + * } + * else + * { + * direction = -1; + * } + * + * if(direction == -1) + * { + * goto label_11DC; + * } + * + * cx = loc_117F; + * + * ax = (ax&0xFF00) | (((*siPtr)&0xFF)>>cx)&0xFF; + * dx = (((ax&0xFF)<<8)&0xFF00) | (dx&0xFF); + * ax = (((ax&0xFF)<<8)&0xFF00) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+1))&0xFF)>>cx)&0xFF; + * dx = (dx&0xFF00) | (ax&0xFF); + * ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+2))&0xFF)>>cx)&0xFF; + * bx = (((ax&0xFF)<<8)&0xFF00) | (bx&0xFF); + * ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+3))&0xFF)>>cx)&0xFF; + * bx = (bx&0xFF00) | (ax&0xFF); + * ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF); + * + * if(ax) + * { + * bp = dx; + * ax = (ax&0xFF00) | (*diPtr)&0xFF; + * ax = (ax&0xFF00) | 8; + * + * outputBit(diPtr,0,(bp>>8)&0xFF); + * outputBit(diPtr,1,(bp&0xFF)); + * outputBit(diPtr,2,(bx>>8)&0xFF); + * outputBit(diPtr,3,(bx&0xFF)); + * } + * + * diPtr++; + * + * label_11DC: + * + * bp = loc_11DC; + * if(bp >0) + * { + * do + * { + * cx = loc_11E7; + * + * ax = (ax&0xFF00) | (((*siPtr)&0xFF)>>cx)&0xFF; + * dx = (((ax&0xFF)<<8)&0xFF00) | (dx&0xFF); + * cx = loc_11EF; + * ax = (ax&0xFF00) | (((*(siPtr+4))&0xFF)>>cx)&0xFF; + * dx = (((dx&0xFF00) | (((ax&0xFF)<<8)&0xFF00))&0xFF00) | (dx&0xFF); + * ax = (ax&0xFF00) | (((ax&0xFF) | (((dx&0xFF00)>>8)&0xFF))&0xFF); + * ax = ((ax&0xFF)<<8) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+5))&0xFF)>>cx)&0xFF; + * dx = (dx&0xFF00) | (ax&0xFF); + * cx = loc_1203; + * ax = (ax&0xFF00) | (((*(siPtr+1))&0xFF)>>cx)&0xFF; + * dx = (dx&0xFF00) | ((dx&0xFF) | (ax&0xFF)); + * ax = (ax&0xFF00) | ((ax&0xFF) | dx&0xFF); + * ax = (ax&0xFF00) | ((ax&0xFF)<<8) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+2))&0xFF)>>cx)&0xFF; + * bx = (((ax&0xFF)<<8)&0xFF00) | (bx&0xFF); + * cx = loc_1217; + * ax = (ax&0xFF00) | (((*(siPtr+7))&0xFF)>>cx)&0xFF; + * bx = (((bx&0xFF00) | (((ax&0xFF)<<8)&0xFF00))&0xFF00) | (bx&0xFF); + * ax = (ax&0xFF00) | ((ax&0xFF) | ((bx&0xFF00)>>8)); + * ax = (ax&0xFF00) | ((ax&0xFF)<<8) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+7))&0xFF)>>cx)&0xFF; + * bx = (bx&0xFF00) | (ax&0xFF); + * cx = loc_122B; + * ax = (ax&0xFF00) | (((*(siPtr+3))&0xFF)>>cx)&0xFF; + * bx = (bx&0xFF00) | ((bx&0xFF) | (ax&0xFF)); + * ax = (ax&0xFF00) | ((ax&0xFF) | bx&0xFF); + * ax = (ax&0xFF00) | ((ax&0xFF)<<8) | (ax&0xFF); + * + * if(ax) + * { + * cx = dx; + * ax = (ax&0xFF00) | (*diPtr)&0xFF; + * ax = (ax&0xFF00) | 8; + * + * outputBit(diPtr,0,(cx>>8)&0xFF); + * outputBit(diPtr,1,(cx&0xFF)); + * outputBit(diPtr,2,(cx>>8)&0xFF); + * outputBit(diPtr,3,(cx&0xFF)); + * } + * + * siPtr += 4; + * diPtr++; + * }while(--bp); + * } + * + * if(loc_122B == 0xF8) + * { + * direction = 1; + * } + * else + * { + * direction = -1; + * } + * + * if(direction == -1) + * { + * goto label_12D9; + * } + * + * cx = loc_127A; + * + * ax = (ax&0xFF00) | (((*siPtr)&0xFF)>>cx)&0xFF; + * dx = (((ax&0xFF)<<8)&0xFF00) | (dx&0xFF); + * ax = (((ax&0xFF)<<8)&0xFF00) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+1))&0xFF)>>cx)&0xFF; + * dx = (dx&0xFF00) | (ax&0xFF); + * ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+2))&0xFF)>>cx)&0xFF; + * bx = (((ax&0xFF)<<8)&0xFF00) | (bx&0xFF); + * ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF); + * + * ax = (ax&0xFF00) | (((*(siPtr+3))&0xFF)>>cx)&0xFF; + * bx = (bx&0xFF00) | (ax&0xFF); + * ax = ((((((ax&0xFF00)>>8)&0xFF) | (ax&0xFF))<<8)&0xFF00) | (ax&0xFF); + * + * if(ax) + * { + * bp = dx; + * ax = (ax&0xFF00) | (*diPtr)&0xFF; + * ax = (ax&0xFF00) | 8; + * + * outputBit(diPtr,0,(bp>>8)&0xFF); + * outputBit(diPtr,1,(bp&0xFF)); + * outputBit(diPtr,2,(bx>>8)&0xFF); + * outputBit(diPtr,3,(bx&0xFF)); + * } + * + * siPtr+=4; + * + * label_12D9: + * diPtr+=loc_12D9; + * siPtr+=loc_12DD; + * bp = loc_12E1; + * + * }while(--bp); + * } */ + + { + int cols = 320; + int rows = 200; + int row; + int col; + int i; + uint8 *pP; + short atariScreen[320 * 200 / 4]; + + for (i = 0; i < rows * cols / 4; i++) { + atariScreen[i] = *(int16 *) sourcePtr; + flipShort(&atariScreen[i]); + sourcePtr += 2; + } + + memcpy(globalAtariScreen, atariScreen, sizeof(atariScreen)); + + pP = (uint8 *) destPtr; + + for (row = 0; row < rows; ++row) { + for (col = 0; col < cols; ++col, ++pP) { + long int c, ind, b, plane; + + ind = 80 * row + ((col >> 4) << 2); + b = 0x8000 >> (col & 0xf); + c = 0; + + for (plane = 0; plane < 4; ++plane) { + if (b & atariScreen[ind + plane]) { + c |= (1 << plane); + } + } + + *pP = (uint8) c; + } + } + } +/* + { + int i; + int j; + + for(i=x;i<height+x;i++) + { + for(j=y;j<width*16+y;j++) + { + if(i>=0&&i<200&&j>=0&&j<320) + destPtr[i*320+j] = *(sourcePtr++); + } + } + }*/ +} + +void gfxModuleData_setDirtyColors(int min, int max) { + if (min < palDirtyMin) + palDirtyMin = min; + if (max > palDirtyMax) + palDirtyMax = max; +} + +void gfxModuleData_setPalColor(int idx, int r, int g, int b) { + lpalette[idx].R = r; + lpalette[idx].G = g; + lpalette[idx].B = b; + gfxModuleData_setDirtyColors(idx, idx); +} + +void gfxModuleData_setPal256(int16 *ptr) { + int R; + int G; + int B; + int i; + + for (i = 0; i < 256; i++) { + R = *(ptr++); + G = *(ptr++); + B = *(ptr++); + + lpalette[i].R = R; + lpalette[i].G = G; + lpalette[i].B = B; + lpalette[i].A = 255; + } + + gfxModuleData_setDirtyColors(0, 255); +} + +void gfxModuleData_setPal(uint8 *ptr) { + int i; + int R; + int G; + int B; + + for (i = 0; i < 16; i++) { +#define convertRatio 36.571428571428571428571428571429 + short int atariColor = *(int16 *) ptr; + //flipShort(&atariColor); + ptr += 2; + + R = (int)(convertRatio * ((atariColor & 0x700) >> 8)); + G = (int)(convertRatio * ((atariColor & 0x070) >> 4)); + B = (int)(convertRatio * ((atariColor & 0x007))); + + if (R > 0xFF) + R = 0xFF; + if (G > 0xFF) + G = 0xFF; + if (B > 0xFF) + B = 0xFF; + + lpalette[i].R = R; + lpalette[i].G = G; + lpalette[i].B = B; + lpalette[i].A = 255; + } + + gfxModuleData_setDirtyColors(0, 16); +} + +void gfxModuleData_field_90(void) { +} + +void gfxModuleData_gfxWaitVSync(void) { +} + +void gfxModuleData_flip(void) { +} + +void gfxModuleData_field_64(char *sourceBuffer, int width, int height, + char *dest, int x, int y, int color) { + int i; + int j; + + x = 0; + y = 0; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dest[(y + i) * 320 / 4 + x + j] = + sourceBuffer[i * width + j]; + } + } +} + +void gfxModuleData_flipScreen(void) { + memcpy(globalScreen, gfxModuleData.pPage00, 320 * 200); + + flip(); +} + +void flip() { + int i; + byte paletteRGBA[256 * 4]; + //uint8* outPtr = scaledScreen; + //uint8* inPtr = globalScreen; + + if (palDirtyMax != -1) { + for (i = palDirtyMin; i < palDirtyMax; i++) { + paletteRGBA[i * 4 + 0] = lpalette[i].R; + paletteRGBA[i * 4 + 1] = lpalette[i].G; + paletteRGBA[i * 4 + 2] = lpalette[i].B; + paletteRGBA[i * 4 + 3] = 0xFF; + } + g_system->setPalette(paletteRGBA, palDirtyMin, palDirtyMax - palDirtyMin + 1); + palDirtyMin = 256; + palDirtyMax = -1; + } + + g_system->copyRectToScreen(globalScreen, 320, 0, 0, 320, 200); + g_system->updateScreen(); + +} + +} // End of namespace Cruise diff --git a/engines/cruise/gfxModule.h b/engines/cruise/gfxModule.h new file mode 100644 index 0000000000..46b8ee4c37 --- /dev/null +++ b/engines/cruise/gfxModule.h @@ -0,0 +1,68 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_GFXMODULE_H +#define CRUISE_GFXMODULE_H + +namespace Cruise { + +struct gfxModuleDataStruct { + int field_1; + int useTandy; + int useEGA; + int useVGA; + + uint8 *pPage00; + uint8 *pPage10; +}; + +struct palEntry { + uint8 R; + uint8 G; + uint8 B; + uint8 A; +}; + +extern gfxModuleDataStruct gfxModuleData; +extern short globalAtariScreen[320 * 200 / 4]; + +void gfxModuleData_gfxClearFrameBuffer(uint8 * ptr); +void gfxModuleData_setDirtyColors(int min, int max); +void gfxModuleData_setPalColor(int idx, int r, int g, int b); +void gfxModuleData_setPal(uint8 * ptr); +void gfxModuleData_field_90(void); +void gfxModuleData_gfxWaitVSync(void); +void gfxModuleData_flip(void); +void gfxModuleData_field_64(char *sourceBuffer, int width, int height, + char *dest, int x, int y, int color); +void gfxModuleData_gfxCopyScreen(char *sourcePtr, char *destPtr); +void gfxModuleData_field_60(char *sourcePtr, int width, int height, + char *destPtr, int x, int y); +void gfxModuleData_flipScreen(void); +void gfxModuleData_setPal256(int16 * ptr); +void flip(void); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/linker.cpp b/engines/cruise/linker.cpp new file mode 100644 index 0000000000..914a571394 --- /dev/null +++ b/engines/cruise/linker.cpp @@ -0,0 +1,358 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +exportEntryStruct *parseExport(int *out1, int *pExportedFuncionIdx, + char *buffer) { + char localBuffer[256]; + uint8 functionName[256]; + uint8 overlayName[256]; + char *dotPtr; + char *ptr2; + int idx; + int numExport; + exportEntryStruct *currentExportEntry; + uint8 *entity1Name; + int i; + + *out1 = 0; + *pExportedFuncionIdx = 0; + + strcpyuint8(localBuffer, buffer); + dotPtr = strchr(localBuffer, '.'); + + if (dotPtr) { + strcpyuint8(functionName, dotPtr + 1); + *dotPtr = 0; + + strcpyuint8(overlayName, localBuffer); + } else { + overlayName[0] = 0; + + strcpyuint8(functionName, buffer); + } + + ptr2 = strchr((char *)functionName, ':'); + + if (ptr2) { + *ptr2 = 0; + + *out1 = 1; + } + + strToUpper(overlayName); + strToUpper(functionName); + if (strlen((char *)overlayName) == 0) + return NULL; + + idx = findOverlayByName2(overlayName); + + if (idx == -4) + return (NULL); + + if (overlayTable[idx].alreadyLoaded == 0) + return (NULL); + + if (!overlayTable[idx].ovlData) + return (NULL); + + numExport = overlayTable[idx].ovlData->numExport; + currentExportEntry = overlayTable[idx].ovlData->exportDataPtr; + entity1Name = overlayTable[idx].ovlData->exportNamesPtr; + + if (!entity1Name) + return (0); + + for (i = 0; i < numExport; i++) { + uint8 exportedName[256]; + uint8 *name = entity1Name + currentExportEntry->offsetToName; + + strcpyuint8(exportedName, name); + strToUpper(exportedName); + + if (!strcmpuint8(functionName, exportedName)) { + *pExportedFuncionIdx = idx; + + return (currentExportEntry); + } + + currentExportEntry++; + } + + return (NULL); +} + +int updateScriptImport(int ovlIdx) { + char buffer[256]; + ovlDataStruct *ovlData; + int numData3; + int size5; + int numImport; + int param; + int var_32; + ovlData3Struct *pScript; +// char* importDataPtr; +// char* namePtr; +// char* linkDataPtr; + + if (!overlayTable[ovlIdx].ovlData) + return (-4); + + ovlData = overlayTable[ovlIdx].ovlData; + + numData3 = ovlData->numScripts1; + size5 = ovlData->numScripts2; + numImport = ovlData->numImport; + param = 0; + + // do it for the 2 first string types + do { + + int i = 0; + + if (param == 0) { + var_32 = numData3; + } else { + var_32 = size5; + } + + if (var_32) { + do { + importScriptStruct *ptrImportData; + uint8 *ptrImportName; + uint8 *ptrData; + + int var_22 = 0; + + if (param == 0) { + pScript = getOvlData3Entry(ovlIdx, i); + } else { + pScript = scriptFunc1Sub2(ovlIdx, i); + } + + ptrImportData = (importScriptStruct *) (pScript->dataPtr + pScript->offsetToImportData); // import data + ptrImportName = pScript->dataPtr + pScript->offsetToImportName; // import name + ptrData = pScript->dataPtr; + + var_22 = 0; + + if (pScript->numImport > 0) { + int counter = pScript->numImport; + + do { + int param2 = + ptrImportData->type; + + if (param2 != 70) { + exportEntryStruct + * ptrDest2; + int out1; + int out2; + + strcpyuint8(buffer, + ptrImportName + + ptrImportData-> + offsetToName); + ptrDest2 = + parseExport(&out1, + &out2, buffer); + + if (ptrDest2 && out2) { + int temp = + ptrImportData-> + offset; + if (out1) //is sub function... (ie 'invent.livre:s') + { + uint8 *ptr = ptrData + temp; + + *(ptr + + 1) + = + out2; + *(int16 + *) + (ptr + + + 2) + = + ptrDest2-> + idx; + + flipShort + ( + (int16 + *) + (ptr + 2)); + } else { + if (param2 == 20 || param2 == 30 || param2 == 40 || param2 == 50) // this patch a double push + { + uint8 + * + ptr + = + ptrData + + + temp; + + *(ptr + 1) = 0; + *(ptr + 2) = out2; // update the overlay number + + *(int16 *) (ptr + 4) = ptrDest2->idx; + + flipShort + ( + (int16 + *) + (ptr + 4)); + } else { + int var_4 = ptrDest2->var4; + + if (var_4 & 1) { + param2 + = + 8; + } else { + param2 + = + 16; + } + + if (var_4 >= 0 && var_4 <= 3) { + param2 + |= + 5; + } else { + param2 + |= + 6; + } + + *(ptrData + temp) = param2; + *(ptrData + temp + 1) = out2; + + *(int16 *) (ptrData + temp + 2) = ptrDest2->idx; + + flipShort + ( + (int16 + *) + (ptrData + + + temp + + + 2)); + } + } + } + } + + ptrImportData++; + } while (--counter); + } + + } while (++i < var_32); + + } + + } while (++param < 2); + + if (ovlData->importDataPtr && ovlData->importNamePtr && numImport) { + int numImport2 = numImport; + int i; + + for (i = 0; i < numImport2; i++) { + int out1; + int foundExportIdx; + exportEntryStruct *pFoundExport; + int linkType; + int linkEntryIdx; + + strcpyuint8(buffer, + ovlData->importNamePtr + + ovlData->importDataPtr[i].nameOffset); + + pFoundExport = + parseExport(&out1, &foundExportIdx, buffer); + + linkType = ovlData->importDataPtr[i].linkType; + linkEntryIdx = ovlData->importDataPtr[i].linkIdx; + + if (pFoundExport && foundExportIdx) { + switch (linkType) { + case 0: // var + { + ovlData-> + linkDataPtr[linkEntryIdx]. + varIdx = foundExportIdx; + ovlData-> + linkDataPtr[linkEntryIdx]. + varNameOffset = + pFoundExport->offsetToName; + break; + } + case 1: // string + { + ovlData-> + linkDataPtr[linkEntryIdx]. + stringIdx = foundExportIdx; + ovlData-> + linkDataPtr[linkEntryIdx]. + stringNameOffset = + pFoundExport->offsetToName; + break; + } + case 2: // proc + { + ovlData-> + linkDataPtr[linkEntryIdx]. + procIdx = foundExportIdx; + ovlData-> + linkDataPtr[linkEntryIdx]. + procNameOffset = + pFoundExport->offsetToName; + break; + } + } + } + } + } + + return (0); +} + +// check that the newly loaded isn't used by the already loaded overlays +void updateAllScriptsImports(void) { + int i; + + for (i = 0; i < 90; i++) { + if (overlayTable[i].ovlData && overlayTable[i].alreadyLoaded) { + updateScriptImport(i); + } + } +} + +} // End of namespace Cruise diff --git a/backends/platform/PalmOS/Src/missing/memory.h b/engines/cruise/linker.h index f57990b19d..1f3cd045f2 100644 --- a/backends/platform/PalmOS/Src/missing/memory.h +++ b/engines/cruise/linker.h @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,4 +22,12 @@ * */ - #include "string.h"
\ No newline at end of file +#ifndef CRUISE_LINKER_H +#define CRUISE_LINKER_H + +namespace Cruise { + +void updateAllScriptsImports(void); + +} // End of namespace Cruise +#endif diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp new file mode 100644 index 0000000000..3d9064cf59 --- /dev/null +++ b/engines/cruise/mainDraw.cpp @@ -0,0 +1,1031 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" +#include "polys.h" + +namespace Cruise { + +int currentTransparent; + +struct autoCellStruct { + struct autoCellStruct *next; + short int ovlIdx; + short int objIdx; + short int type; + short int newValue; + cellStruct *pCell; +}; + +autoCellStruct autoCellHead; + +void addAutoCell(int overlayIdx, int idx, int type, int newVal, cellStruct *pObject) { + autoCellStruct *pNewEntry; + + pNewEntry = new autoCellStruct; + + pNewEntry->next = autoCellHead.next; + autoCellHead.next = pNewEntry; + + pNewEntry->ovlIdx = overlayIdx; + pNewEntry->objIdx = idx; + pNewEntry->type = type; + pNewEntry->newValue = newVal; + pNewEntry->pCell = pObject; +} + +void freeAutoCell(void) { + autoCellStruct *pCurrent = autoCellHead.next; + + while (pCurrent) { + autoCellStruct *next = pCurrent->next; + + if (pCurrent->type == 5) { + objInit(pCurrent->ovlIdx, pCurrent->objIdx, pCurrent->newValue); + } else { + setObjectPosition(pCurrent->ovlIdx, pCurrent->objIdx, pCurrent->type, pCurrent->newValue); + } + + if (pCurrent->pCell->animWait < 0) { + objectParamsQuery params; + + getMultipleObjectParam(pCurrent->ovlIdx, pCurrent->objIdx, ¶ms); + + pCurrent->pCell->animCounter = params.var6 - 1; + } + + delete pCurrent; + + pCurrent = next; + } +} + +void flipScreen(void) { + uint8 *swapPtr; + + swapPtr = gfxModuleData.pPage00; + gfxModuleData.pPage00 = gfxModuleData.pPage10; + gfxModuleData.pPage10 = swapPtr; + + gfxModuleData_flipScreen(); + + /*memcpy(globalAtariScreen, gfxModuleData.pPage00, 16000); + * convertAtariToRaw(gfxModuleData.pPage00,globalScreen,200,320); */ +} + +int spriteX1; +int spriteX2; +int spriteY1; +int spriteY2; + +char *polyOutputBuffer; + +void pixel(int x, int y, char color) { + if (x >= 0 && x < 320 && y >= 0 && y < 200) + polyOutputBuffer[320 * y + x] = color; +} + +// this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1) +void getPolyData(int fileIndex, int X, int Y, int *outScale, int *outY, + int *outX, char **outDataPtr, int scale, char *dataPtr) { + if (*(uint16 *) dataPtr == 0) { + uint16 newFileIndex; + uint16 newX; + char *newDataPtr; // this one is quite useless + uint16 newY; + + dataPtr += 2; + newFileIndex = *(uint16 *) dataPtr; + flipShort(&newFileIndex); + + dataPtr += 2; + newX = *(uint16 *) dataPtr; + flipShort(&newX); + + newDataPtr = dataPtr; // useless + + newY = *(uint16 *) (newDataPtr + 2); + flipShort(&newY); + + newFileIndex += fileIndex; + + if (true /*newFileIndex >= 0 */ ) // FIXME: comparison is always true due to limited range of data type + { + if (filesDatabase[newFileIndex].resType == 0 + && filesDatabase[newFileIndex].subData.ptr) { + dataPtr = + (char *)filesDatabase[newFileIndex]. + subData.ptr; + } + } + + scale = -scale; + X -= newX; + Y -= newY; + } + + *outDataPtr = dataPtr; + *outX = X; + *outY = Y; + *outScale = scale; +} + +int upscaleValue(int value, int scale) { + return (((value * scale) << 8) / 2); +} + +int m_flipLeftRight; +int m_useSmallScale; +int m_lowerX; +int m_lowerY; +int m_coordCount; +int m_first_X; +int m_first_Y; +int m_scaleValue; +int m_current_X; +int m_current_Y; +int m_color; + +int16 polyBuffer[512]; +int16 polyBuffer2[512]; +int16 polyBuffer3[404]; +int16 polyBuffer4[512]; + +// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2) +void getPolySize(int positionX, int positionY, int scale, int sizeTable[4], + unsigned char *dataPtr) { + int upperBorder; + int lowerBorder; + m_flipLeftRight = 0; + + if (scale < 0) // flip left right + { + m_flipLeftRight = 1; + scale = -scale; + } + // X1 + + upperBorder = *(dataPtr + 3); + + if (m_flipLeftRight) { + upperBorder = -upperBorder; + } + + upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16; + upperBorder = -upperBorder; + lowerBorder = upperBorder; + + // X2 + + upperBorder = *(dataPtr + 1); + upperBorder -= *(dataPtr + 3); + + if (m_flipLeftRight) { + upperBorder = -upperBorder; + } + + upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16; + + if (upperBorder < lowerBorder) // exchange borders if lower > upper + { + int temp = upperBorder; + upperBorder = lowerBorder; + lowerBorder = temp; + } + + sizeTable[0] = lowerBorder; // left + sizeTable[1] = upperBorder; // right + + // Y1 + + upperBorder = *(dataPtr + 4); + upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16; + upperBorder = -upperBorder; + lowerBorder = upperBorder; + + // Y2 + + upperBorder = *(dataPtr + 2); + upperBorder -= *(dataPtr + 4); + upperBorder = (upscaleValue(upperBorder, scale) + 0x8000) >> 16; + + if (upperBorder < lowerBorder) // exchange borders if lower > upper + { + int temp = upperBorder; + upperBorder = lowerBorder; + lowerBorder = temp; + } + + sizeTable[2] = lowerBorder; // bottom + sizeTable[3] = upperBorder; // top +} + +void blitPolyMode1(char *dest, char *ptr, int16 * buffer, char color) { +} + +void blitPolyMode2(char *dest, int16 * buffer, char color) { +} + +int polySize1; +int polySize2; +int polySize3; +int polySize4; + +int polyVar1; +int16 *polyVar2; + +void drawPolySub(void) { + int i; + + for (i = 0; i < polyVar1; i++) { + line(polyBuffer4[i * 2], polyBuffer4[i * 2 + 1], + polyBuffer4[(i + 1) * 2], polyBuffer4[(i + 1) * 2 + 1], + m_color & 0xF); + } + + fillpoly(polyBuffer4, polyVar1, m_color & 0xF); +} + +char *drawPolyMode1(char *dataPointer, int linesToDraw) { + int index; + int16 *pBufferDest; + + polyVar1 = linesToDraw; + pBufferDest = &polyBuffer4[polyVar1 * 2]; + index = *(dataPointer++); + + polySize1 = polySize2 = pBufferDest[-2] = + pBufferDest[-2 + linesToDraw * 2] = polyBuffer2[index * 2]; + polySize1 = polySize2 = pBufferDest[-1] = + pBufferDest[-1 + linesToDraw * 2] = polyBuffer2[(index * 2) + 1]; + + linesToDraw--; + + pBufferDest -= 2; + + polyVar2 = pBufferDest; + + do { + int value; + + index = *(dataPointer++); + value = pBufferDest[-2] = pBufferDest[-2 + polyVar1 * 2] = + polyBuffer2[index * 2]; + + if (value < polySize1) { + polySize1 = value; + } + if (value > polySize2) { + polySize2 = value; + } + + value = pBufferDest[-1] = pBufferDest[-1 + polyVar1 * 2] = + polyBuffer2[(index * 2) + 1]; + + if (value > polySize4) { + polySize4 = value; + } + if (value < polySize3) { + polySize3 = value; + polyVar2 = pBufferDest - 4; + } + pBufferDest -= 2; + + } while (--linesToDraw); + + drawPolySub(); + + return dataPointer; +} + +char *drawPolyMode2(char *dataPointer, int linesToDraw) { + int index; + int16 *pBufferDest; + + pBufferDest = polyBuffer4; + polyVar1 = linesToDraw; + polyVar2 = polyBuffer4; + index = *(dataPointer++); + + polySize1 = polySize2 = pBufferDest[0] = pBufferDest[linesToDraw * 2] = + polyBuffer2[index * 2]; + polySize1 = polySize2 = pBufferDest[1] = + pBufferDest[linesToDraw * 2 + 1] = polyBuffer2[(index * 2) + 1]; + + linesToDraw--; + + pBufferDest += 2; + + do { + int value; + + index = *(dataPointer++); + value = pBufferDest[0] = pBufferDest[polyVar1 * 2] = + polyBuffer2[index * 2]; + + if (value < polySize1) { + polySize1 = value; + } + if (value > polySize2) { + polySize2 = value; + } + + value = pBufferDest[1] = pBufferDest[polyVar1 * 2 + 1] = + polyBuffer2[(index * 2) + 1]; + + if (value > polySize4) { + polySize4 = value; + } + if (value < polySize3) { + polySize3 = value; + polyVar2 = pBufferDest; + } + + pBufferDest += 2; + + } while (--linesToDraw); + + drawPolySub(); + + return dataPointer; +} + +// this function builds the poly model and then calls the draw functions (OLD: mainDrawSub1Sub5) +void buildPolyModel(int positionX, int positionY, int scale, char *ptr2, + char *destBuffer, char *dataPtr) { + int counter = 0; // numbers of coordinates to process + int startX = 0; // first X in model + int startY = 0; // first Y in model + int x = 0; // current X + int y = 0; // current Y + int offsetXinModel = 0; // offset of the X value in the model + int offsetYinModel = 0; // offset of the Y value in the model + unsigned char *dataPointer = (unsigned char *)dataPtr; + int16 *ptrPoly_1_Buf = polyBuffer; + int16 *ptrPoly_2_Buf; + polyOutputBuffer = destBuffer; // global + + m_flipLeftRight = 0; + m_useSmallScale = 0; + m_lowerX = *(dataPointer + 3); + m_lowerY = *(dataPointer + 4); + + if (scale < 0) { + scale = -scale; // flip left right + m_flipLeftRight = 1; + } + + if (scale < 0x180) // If scale is smaller than 384 + { + m_useSmallScale = 1; + m_scaleValue = scale << 1; // double scale + } else { + m_scaleValue = scale; + } + + dataPointer += 5; + + m_coordCount = (*(dataPointer++)) + 1; // original uses +1 here but its later substracted again, we could skip it + m_first_X = *(dataPointer++); + m_first_Y = *(dataPointer++); + startX = m_lowerX - m_first_X; + startY = m_lowerY - m_first_Y; + + if (m_useSmallScale) { + startX >>= 1; + startY >>= 1; + } + + if (m_flipLeftRight) { + startX = -startX; + } + + /* + * NOTE: + * + * The original code continues here with using X, Y instead of startX and StartY. + * + * Original code: + * positionX -= (upscaleValue(startX, m_scaleValue) + 0x8000) >> 16; + * positionY -= (upscaleValue(startX, m_scaleValue) + 0x8000) >> 16; + */ + + // get coordinates from data + + startX = + positionX - ((upscaleValue(startX, m_scaleValue) + 0x8000) >> 16); + startY = + positionY - ((upscaleValue(startY, m_scaleValue) + 0x8000) >> 16); + + ptrPoly_1_Buf[0] = 0; + ptrPoly_1_Buf[1] = 0; + ptrPoly_1_Buf += 2; + counter = m_coordCount - 1 - 1; // skip the first pair, we already have the values + + do { + x = *(dataPointer++) - m_first_X; + y = *(dataPointer++) - m_first_Y; + + if (m_useSmallScale) // shrink all coordinates by factor 2 if a scale smaller than 384 is used + { + x >>= 1; + y >>= 1; + } + + ptrPoly_1_Buf[0] = offsetXinModel - x; + ptrPoly_1_Buf++; + offsetXinModel = x; + + ptrPoly_1_Buf[0] = -(offsetYinModel - y); + ptrPoly_1_Buf++; + offsetYinModel = y; + + } while (--counter); + + // scale and adjust coordinates with offset (using two polybuffers by doing that) + + /* + * NOTE: Is there a need for having two, a scaled and unscaled polybuffer? + */ + + ptrPoly_2_Buf = polyBuffer; + ptrPoly_1_Buf = polyBuffer2; + counter = m_coordCount - 1; // reset counter // process first pair two + m_current_X = 0; + m_current_Y = 0; + + do { + x = ptrPoly_2_Buf[0]; + + if (m_flipLeftRight == 0) { + x = -x; + } + ////////////////// + + m_current_X += upscaleValue(x, m_scaleValue); + ptrPoly_1_Buf[0] = ((m_current_X + 0x8000) >> 16) + startX; // adjust X value with start offset + + m_current_Y += upscaleValue(ptrPoly_2_Buf[1], m_scaleValue); + ptrPoly_1_Buf[1] = ((m_current_Y + 0x8000) >> 16) + startY; // adjust Y value with start offset + + ///////////////// + + ptrPoly_1_Buf += 2; + ptrPoly_2_Buf += 2; + + } while (--counter); + + // position of the dataPointer is m_coordCount * 2 + + do { + int linesToDraw = *dataPointer++; + + if (linesToDraw > 1) // if value not zero + { + uint16 minimumScale; + + m_color = *dataPointer; // color + dataPointer += 2; + + minimumScale = *(uint16 *) (dataPointer); + dataPointer += 2; + + flipShort(&minimumScale); + + if (minimumScale > scale) // if the scale is too small, for the model to be drawn ... + { + dataPointer += linesToDraw; // ... skip ahead + } else { + if (m_flipLeftRight) { + dataPointer = + (unsigned char *) + drawPolyMode1((char *)dataPointer, + linesToDraw); + } else { + dataPointer = + (unsigned char *) + drawPolyMode2((char *)dataPointer, + linesToDraw); + } + + if (destBuffer) { + if (ptr2) { + blitPolyMode1(destBuffer, ptr2, + polyBuffer3, + m_color & 0xF); + } else { + blitPolyMode2(destBuffer, + polyBuffer3, + m_color & 0xF); + } + } + } + } else { + dataPointer += 4; + } + } while (*dataPointer != 0xFF); +} + +// draw poly sprite (OLD: mainDrawSub1) +void mainDrawPolygons(int fileIndex, cellStruct *pObject, int X, int scale, + int Y, char *destBuffer, char *dataPtr) { + int newX; + int newY; + int newScale; + char *newDataPtr; + char *ptr2; // unused + int var_8; // unused + + int sizeTable[4]; // 0 = left, 1 = right, 2 = bottom, 3 = top + + // this function checks if the dataPtr is not 0, else it retrives the data for X, Y, scale and DataPtr again (OLD: mainDrawSub1Sub1) + getPolyData(fileIndex, X, Y, &newScale, &newY, &newX, &newDataPtr, + scale, dataPtr); + + // this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2) + getPolySize(newX, newY, newScale, sizeTable, + (unsigned char *)newDataPtr); + + spriteX2 = sizeTable[0] - 2; // left border + spriteX1 = sizeTable[1] + 18; // right border + spriteY2 = sizeTable[2] - 2; // bottom border + spriteY1 = sizeTable[3] + 2; // top border + +/* if (X == 28 && Y == 80 && scale == 1024) { + printf("0--> x1: %i, y1: %i, x2: %i, y2: %i\n", sizeTable[1], sizeTable[3], sizeTable[0], sizeTable[2]); + printf("1--> x1: %i, y1: %i, x2: %i, y2: %i\n", spriteX1, spriteY1, spriteX2, spriteY2); + } */ + if (spriteX2 >= 320) + return; + if (spriteX1 < 0) + return; + if (spriteY2 >= 200) + return; + if (spriteY1 < 0) + return; + + if (spriteX2 < 0) { + spriteX2 = 0; + } + if (spriteX1 > 320) { + spriteX1 = 320; + } + if (spriteY2 < 0) { + spriteY2 = 0; + } + if (spriteY1 > 200) { + spriteY1 = 200; + } + + if (spriteX1 == spriteX2) + return; + if (spriteY1 == spriteY2) + return; + + ptr2 = NULL; + var_8 = 0; + + if (pObject) { + cellStruct *pCurrentObject = pObject; + + do { + if (pCurrentObject->type == 2) { + // ASSERT(0); + } + + pCurrentObject = pCurrentObject->next; + } while (pCurrentObject); + } + // this function builds the poly model and then calls the draw functions (OLD: mainDrawSub1Sub5) + buildPolyModel(newX, newY, newScale, ptr2, destBuffer, newDataPtr); +} + +void mainSprite(int globalX, int globalY, gfxEntryStruct *pGfxPtr, + uint8 *ouputPtr, int newColor, int idx) { + // this is used for font only + + if (pGfxPtr) { + uint8 *initialOuput; + uint8 *output; + int i; + int j; + int x; + int y; + uint8 *ptr = pGfxPtr->imagePtr; + int height = pGfxPtr->height; + int width = pGfxPtr->width; + + if (globalY < 0) { + globalY = 0; + } + + if (globalY + pGfxPtr->height >= 198) { + globalY = 198 - pGfxPtr->height; + } + + initialOuput = ouputPtr + (globalY * 320) + globalX; + + y = globalY; + x = globalX; + + for (i = 0; i < height; i++) { + output = initialOuput + 320 * i; + + for (j = 0; j < width; j++) { + uint8 color = *(ptr++); + + if (color) { + if ((x >= 0) && (x < 320) && (y >= 0) + && (y < 200)) { + if (color == 1) { + *output = (uint8) 0; + } else { + *output = + (uint8) newColor; + } + } + } + output++; + } + } + } +} + +void mainDrawSub4(int objX1, int var_6, cellStruct *currentObjPtr, + char *data1, int objY2, int objX2, char *output, char *data2) { + int x = 0; + int y = 0; + + for (y = 0; y < var_6; y++) { + for (x = 0; x < (objX1 * 8); x++) { + uint8 color = (data1[0]); + data1++; + + if ((x + objX2) >= 0 && (x + objX2) < 320 + && (y + objY2) >= 0 && (y + objY2) < 200) { + if (color != currentTransparent) { + output[320 * (y + objY2) + x + objX2] = + color; + } + } + } + } +} + +#ifdef _DEBUG +void drawCtp(void) { + int i; + + if (ctp_walkboxTable) { + for (i = 0; i < 15; i++) { + uint16 *dataPtr = &ctp_walkboxTable[i * 40]; + int type = walkboxType[i]; // show different types in different colors + + if (*dataPtr) { + int j; + fillpoly((short *)dataPtr + 1, *dataPtr, type); + + for (j = 0; j < (*dataPtr - 1); j++) { + line(dataPtr[1 + j * 2], + dataPtr[1 + j * 2 + 1], + dataPtr[1 + (j + 1) * 2], + dataPtr[1 + (j + 1) * 2 + 1], 0); + } + + line(dataPtr[1 + j * 2], + dataPtr[1 + j * 2 + 1], dataPtr[1], + dataPtr[2], 0); + } + } + } +} +#endif + +void drawMenu(menuStruct *pMenu) { + if (pMenu && pMenu->numElements) { + int height; + int x; + int y; + int var_10; + int bx; + int newX; + int var_6; + int currentY; + int var_8; + int di; + menuElementStruct *si; + + height = pMenu->gfx->height; + x = pMenu->x; + y = pMenu->y; + + var_10 = pMenu->gfx->width / (199 - (pMenu->gfx->width * 2)); + + bx = var_10 / (pMenu->numElements + 1); // rustine... + + if (!bx) { + bx++; + + if ((pMenu->numElements * height) + y > 199 - height) { + y = ((-1 - pMenu->numElements) * height) + 200; + } + } else { + if (var_10 % pMenu->numElements) { + bx++; + } + + y = height; + } + + newX = 320 * (2 - bx); + + if (newX < x) { + x = newX; + } + + if (x < 0) { + x = 0; + } + + var_6 = (80 * (bx - 1)) + x; + + if (var_6 <= 320) { + mainSprite(var_6, y - height, pMenu->gfx, + gfxModuleData.pPage10, video4, 320); + } + + currentY = y; + var_8 = 0; + di = x; + + si = pMenu->ptrNextElement; + + if (si) { + do { + int color; + + gfxEntryStruct *var_2 = si->gfx; + + si->x = di; + si->y = currentY; + si->varA = 320; + + if (si->varC) { + color = video3; + } else { + if (si->color != 255) { + color = si->color; + } else { + color = video2; + } + } + + if (di < 320) { + mainSprite(di, currentY, var_2, + gfxModuleData.pPage10, color, 320); + } + + currentY += height; + var_8++; + + if (var_8 == var_10) { + var_8 = 0; + di += 320; + currentY = y; + } + + si = si->next; + } while (si); + } + } +} + +int getValueFromObjectQuerry(objectParamsQuery *params, int idx) { + switch (idx) { + case 0: + return params->X; + case 1: + return params->Y; + case 2: + return params->baseFileIdx; + case 3: + return params->fileIdx; + case 4: + return params->scale; + case 5: + return params->var5; + case 6: + return params->var6; + case 7: + return params->var7; + } + + assert(0); + + return 0; +} + +void mainDraw(int16 param) { + uint8 *bgPtr; + cellStruct *currentObjPtr; + int16 currentObjIdx; + int16 objX1 = 0; + int16 objY1 = 0; + int16 objZ1 = 0; + int16 objX2; + int16 objY2; + int16 objZ2; + int16 spriteHeight; + + if (fadeVar) { + return; + } + + bgPtr = backgroundPtrtable[currentActiveBackgroundPlane]; + + if (bgPtr) { + gfxModuleData_gfxCopyScreen((char *)bgPtr, (char *)gfxModuleData.pPage10); + } + + autoCellHead.next = NULL; + + currentObjPtr = cellHead.next; + +#ifdef _DEBUG +/* polyOutputBuffer = (char*)bgPtr; + drawCtp(); */ +#endif + + //-------------------------------------------------- PROCESS SPRITES -----------------------------------------// + + while (currentObjPtr) { + if ((currentActiveBackgroundPlane == currentObjPtr->backgroundPlane) && (currentObjPtr->freeze == 0) && (currentObjPtr->type == OBJ_SPRITE)) { + objectParamsQuery params; + + currentObjIdx = currentObjPtr->idx; + + if ((currentObjPtr->followObjectOverlayIdx != currentObjPtr->overlay) || (currentObjPtr->followObjectIdx != currentObjPtr->idx)) { + // Declaring this twice ? + // objectParamsQuery params; + + getMultipleObjectParam(currentObjPtr->followObjectOverlayIdx, currentObjPtr->followObjectIdx, ¶ms); + + objX1 = params.X; + objY1 = params.Y; + objZ1 = params.fileIdx; + } else { + objX1 = 0; + objY1 = 0; + objZ1 = 0; + } + + getMultipleObjectParam(currentObjPtr->overlay, + currentObjIdx, ¶ms); + + objX2 = objX1 + params.X; + objY2 = objY1 + params.Y; + objZ2 = params.fileIdx; + + if (objZ2 >= 0) { + objZ2 += objZ1; + } + + if ((params.var5 >= 0) && (objZ2 >= 0) && filesDatabase[objZ2].subData.ptr) { + if (filesDatabase[objZ2].subData.resourceType == 8) // Poly + { + mainDrawPolygons(objZ2, currentObjPtr, objX2, params.scale, objY2, (char *)gfxModuleData.pPage10, (char *)filesDatabase[objZ2].subData.ptr); // poly + } else if (filesDatabase[objZ2].subData.resourceType == 6) // sound + { + } else if (filesDatabase[objZ2].resType == 1) //(num plan == 1) + { + } else if (filesDatabase[objZ2].subData.resourceType == 4) { + objX1 = filesDatabase[objZ2].width; // width + spriteHeight = filesDatabase[objZ2].height; // height + + if (filesDatabase[objZ2].subData.ptr) { + currentTransparent = filesDatabase[objZ2].subData.transparency; + + mainDrawSub4(objX1, spriteHeight, currentObjPtr, (char *)filesDatabase[objZ2].subData.ptr, objY2, objX2,(char *)gfxModuleData.pPage10,(char *)filesDatabase[objZ2].subData.ptr); + } + } + } + + // automatic animation process + if (currentObjPtr->animStep && !param) { + if (currentObjPtr->animCounter <= 0) { + + bool change = true; + + int newVal = getValueFromObjectQuerry(¶ms, currentObjPtr->animChange) + currentObjPtr->animStep; + + if (currentObjPtr->animStep > 0) { + if (newVal > currentObjPtr->animEnd) { + if (currentObjPtr->animLoop) { + newVal = currentObjPtr->animStart; + if(currentObjPtr->animLoop>0) + currentObjPtr->animLoop--; + } else { + int16 data2; + data2 = currentObjPtr->animStart; + + change = false; + currentObjPtr->animStep = 0; + + if (currentObjPtr->animType) // should we resume the script ? + { + if (currentObjPtr->parentType == 20) { + changeScriptParamInList(currentObjPtr->parentOverlay, currentObjPtr->parent, &procHead, 0, -1); + } + else if(currentObjPtr->parentType == 30) { + changeScriptParamInList(currentObjPtr->parentOverlay, currentObjPtr->parent, &relHead, 0, -1); + } + } + } + } + } else { + ASSERT(0); + /* if(currentObjPtr->field_22>newVal) + * { + * } */ + } + + if (currentObjPtr->animWait >= 0) { + currentObjPtr->animCounter = currentObjPtr->animWait; + } + + if ((currentObjPtr->animSignal >= 0) && (currentObjPtr->animSignal == newVal) && (currentObjPtr->animType != 0)) { + if (currentObjPtr->parentType == 20) { + changeScriptParamInList(currentObjPtr->parentOverlay, currentObjPtr->parent, &procHead, 0, -1); + } else if (currentObjPtr->parentType == 30) { + changeScriptParamInList(currentObjPtr->parentOverlay, currentObjPtr->parent, &relHead, 0, -1); + } + + currentObjPtr->animType = 0; + } + + if (change) { + addAutoCell(currentObjPtr->overlay, currentObjPtr->idx, currentObjPtr->animChange, newVal, currentObjPtr); + } + } else { + currentObjPtr->animCounter--; + } + } + } + + currentObjPtr = currentObjPtr->next; + } + + //----------------------------------------------------------------------------------------------------------------// + + freeAutoCell(); + var20 = 0; + + //-------------------------------------------------- DRAW OBJECTS TYPE 5 (MSG)-----------------------------------------// + + currentObjPtr = cellHead.next; + + while (currentObjPtr) { + if (currentObjPtr->type == 5 && currentObjPtr->freeze == 0) { + mainSprite(currentObjPtr->x, currentObjPtr->field_C, currentObjPtr->gfxPtr, gfxModuleData.pPage10, currentObjPtr->color, currentObjPtr->spriteIdx); + var20 = 1; + } + currentObjPtr = currentObjPtr->next; + } + + //----------------------------------------------------------------------------------------------------------------// + + if (currentActiveMenu != -1) { + if (menuTable[currentActiveMenu]) { + drawMenu(menuTable[currentActiveMenu]); + return; + } + } + + if (mouseVar1) { + ASSERT(0); + // TODO: draw mouse here + } +} + +} // End of namespace Cruise diff --git a/engines/cruise/mainDraw.h b/engines/cruise/mainDraw.h new file mode 100644 index 0000000000..ae6194a568 --- /dev/null +++ b/engines/cruise/mainDraw.h @@ -0,0 +1,50 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_MAINDRAW_H +#define CRUISE_MAINDRAW_H + +namespace Cruise { + +extern int currentTransparent; +extern int16 polyBuffer3[404]; +extern int16 polyBuffer2[512]; +extern int m_color; + +int upscaleValue(int value, int scale); + +void pixel(int x, int y, char color); +void mainDraw(int16 param); +void flipScreen(void); +void buildPolyModel(int X, int Y, int scale, char *ptr2, char *destBuffer, + char *dataPtr); +void getPolyData(int fileIndex, int X, int Y, int *newScale, int *newY, + int *newX, char **newDataPtr, int scale, char *dataPtr); +void mainDrawSub4(int objX1, int var_6, cellStruct * currentObjPtr, + char *data1, int objY2, int objX2, char *output, char *data2); +char *drawPolyMode2(char *si, int cx); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp new file mode 100644 index 0000000000..d76934439b --- /dev/null +++ b/engines/cruise/menu.cpp @@ -0,0 +1,312 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +menuStruct *menuTable[8]; + +menuStruct *createMenu(int X, int Y, const char *menuName) { + menuStruct *entry; + + entry = (menuStruct *) malloc(sizeof(menuStruct)); + ASSERT(entry); + + entry->x = X - 80; + entry->y = Y; + entry->stringPtr = menuName; + entry->numElements = 0; + entry->ptrNextElement = NULL; + entry->gfx = renderText(160, (uint8 *) menuName); + + return entry; +} + +// TODO: rewrite to remove the goto +void addSelectableMenuEntry(int param0, int param1, menuStruct *pMenu, + int param2, int color, const char *menuText) { + menuElementStruct *di; + menuElementStruct *var_6; + menuElementStruct *pNewElement; + menuElementSubStruct *pSubStruct; + menuElementSubStruct *pSubStructCurrent; + + if (pMenu->numElements <= 48) { + var_6 = pMenu->ptrNextElement; + + if (var_6) { + do { + di = var_6; + if (param2) { + if (!strcmp(var_6->string, menuText)) { + pNewElement = var_6; + pSubStruct = + (menuElementSubStruct *) + allocAndZero(sizeof + (menuElementSubStruct)); + ASSERT(pSubStruct); + + pSubStruct->pNext = NULL; + pSubStruct->var2 = param0; + pSubStruct->var4 = param1; + + pSubStructCurrent = + pNewElement->ptrSub; + + if (!pSubStructCurrent) { + pNewElement->ptrSub = + pSubStruct; + return; + } + + if (pSubStructCurrent->pNext) { + do { + pSubStructCurrent + = + pSubStructCurrent-> + pNext; + } while + (pSubStructCurrent-> + pNext); + } + + pSubStructCurrent->pNext = + pSubStruct; + return; + } + } + var_6 = var_6->next; + } + while (var_6); + + var_6 = di; + } + + pNewElement = + (menuElementStruct *) + allocAndZero(sizeof(menuElementStruct)); + ASSERT(pNewElement); + pSubStruct = + (menuElementSubStruct *) + allocAndZero(sizeof(menuElementSubStruct)); + ASSERT(pSubStruct); + + pNewElement->string = menuText; + pNewElement->next = NULL; + pNewElement->varC = 0; + pNewElement->color = color; + pNewElement->gfx = renderText(160, (uint8 *) menuText); + + if (var_6 == NULL) { + pMenu->ptrNextElement = pNewElement; + } else { + var_6->next = pNewElement; + } + + pNewElement->ptrSub = pSubStruct; + + pSubStruct->pNext = NULL; + pSubStruct->var2 = param0; + pSubStruct->var4 = param1; + + pMenu->numElements++; + } +} + +void updateMenuMouse(int mouseX, int mouseY, menuStruct *pMenu) { + if (pMenu) { + if (pMenu->gfx) { + int height = pMenu->gfx->height; // rustine + int var_2 = 0; + menuElementStruct *pCurrentEntry = + pMenu->ptrNextElement; + + while (pCurrentEntry) { + pCurrentEntry->varC = 0; + + if (var_2 == 0) { + if ((mouseX > pCurrentEntry->x) + && ((pCurrentEntry->x + 160) >= + mouseX)) { + if ((mouseY > pCurrentEntry->y) + && ((pCurrentEntry->y + + height) >= + mouseY)) { + var_2 = 1; + pCurrentEntry->varC = + 1; + } + } + } + + pCurrentEntry = pCurrentEntry->next; + } + } + } +} + +int processMenu(menuStruct *pMenu) { + int16 mouseX; + int16 mouseY; + int16 mouseButton; + int di; + int si; + currentActiveMenu = 0; + + mainDraw(1); + flipScreen(); + + di = 0; + si = 0; + + do { + getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY); + + updateMenuMouse(mouseX, mouseY, pMenu); + + if (mouseButton) { + if (di) { + si = 1; + } + } else { + di = 1; + } + + mainDraw(1); + flipScreen(); + +// readKeyboard(); + } while (!si); + + currentActiveMenu = -1; + + mainDraw(1); + flipScreen(); + + return 0; +} + +int playerMenu(int menuX, int menuY) { + int retourMenu; + //int restartGame = 0; + + if (entrerMenuJoueur && affichePasMenuJoueur) { + if (var0) { + systemStrings.param = 0; + var24 = 0; + var23 = 0; + freeStuff2(); + } +/* + if(currentMenu) + { + freeMenu(currentMenu); + currentMenu = 0; + var37 = 0; + var38 = 0; + main9 = -1; + } + + if(inventoryMenu) + { + freeMenu(inventoryMenu); + inventoryMenu = 0; + var37 = 0; + var38 = 0; + main9 = -1; + }*/ + +/* if(mouseVar2) + { + free3(mouseVar2); + } */ + +/* mouseVar2 = 0; + mouseVar1 = 0; */ + freeDisk(); + + menuTable[0] = createMenu(menuX, menuY, "Menu Joueur"); + ASSERT(menuTable[0]); + + addSelectableMenuEntry(0, 3, menuTable[0], 1, -1, + "Lecteur de Sauvegarde"); + if (userEnabled) { + addSelectableMenuEntry(0, 4, menuTable[0], 1, -1, + "Sauvegarde"); + } + addSelectableMenuEntry(0, 5, menuTable[0], 1, -1, + "Chargement"); + addSelectableMenuEntry(0, 6, menuTable[0], 1, -1, + "Recommencer le jeu"); + addSelectableMenuEntry(0, 7, menuTable[0], 1, -1, + "Chargement"); + + retourMenu = processMenu(menuTable[0]); + } + + return 0; +} + +void freeGfx(gfxEntryStruct *pGfx) { + if (pGfx->imagePtr) { + free(pGfx->imagePtr); + } + + free(pGfx); +} + +void freeMenu(menuStruct *pMenu) { + menuElementStruct *pElement = pMenu->ptrNextElement; + + while (pElement) { + menuElementStruct *next; + menuElementSubStruct *pSub = pElement->ptrSub; + + next = pElement->next; + + while (pSub) { + menuElementSubStruct *nextSub; + + nextSub = pSub->pNext; + + free(pSub); + + pSub = nextSub; + } + + if (pElement->gfx) { + freeGfx(pElement->gfx); + } + + free(pElement); + + pElement = next; + } + + freeGfx(pMenu->gfx); + free(pMenu); +} + +} // End of namespace Cruise diff --git a/engines/cruise/menu.h b/engines/cruise/menu.h new file mode 100644 index 0000000000..cf4941c96b --- /dev/null +++ b/engines/cruise/menu.h @@ -0,0 +1,51 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_MENU_H +#define CRUISE_MENU_H + +namespace Cruise { + +struct menuStruct { + const char *stringPtr; + gfxEntryStruct *gfx; + int x; + int y; + int numElements; + menuElementStruct *ptrNextElement; +}; + +extern menuStruct *menuTable[8]; + +menuStruct *createMenu(int X, int Y, const char *menuName); +void addSelectableMenuEntry(int var0, int var1, menuStruct * pMenu, int var2, + int color, const char *menuText); +void updateMenuMouse(int mouseX, int mouseY, menuStruct * pMenu); +int processMenu(menuStruct * pMenu); +void freeMenu(menuStruct * pMenu); +int playerMenu(int menuX, int menuY); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/module.mk b/engines/cruise/module.mk new file mode 100644 index 0000000000..0af8678b4a --- /dev/null +++ b/engines/cruise/module.mk @@ -0,0 +1,42 @@ +MODULE := engines/cruise + +MODULE_OBJS := \ + actor.o \ + background.o \ + backgroundIncrust.o \ + cell.o \ + cruise.o \ + cruise_main.o \ + ctp.o \ + dataLoader.o \ + decompiler.o \ + delphine-unpack.o \ + detection.o \ + font.o \ + fontCharacterTable.o \ + function.o \ + gfxModule.o \ + linker.o \ + mainDraw.o \ + menu.o \ + mouse.o \ + object.o \ + overlay.o \ + perso.o \ + polys.o \ + saveload.o \ + script.o \ + stack.o \ + stringSupport.o \ + various.o \ + vars.o \ + volume.o + +# This module can be built as a plugin +ifdef BUILD_PLUGINS +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk + diff --git a/backends/platform/PalmOS/Src/missing/ext_unistd.c b/engines/cruise/mouse.cpp index 91f2e8e3e5..9d296b9c77 100644 --- a/backends/platform/PalmOS/Src/missing/ext_unistd.c +++ b/engines/cruise/mouse.cpp @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,20 +22,30 @@ * */ -#include <unistd.h> +#include "cruise/cruise_main.h" + +namespace Cruise { + +int16 main10; -const Char *gUnistdCWD = NULL; +void getMouseStatus(int16 *pMouseVar, int16 *pMouseX, int16 *pMouseButton, + int16 *pMouseY) { + // mouseStatusStruct localStatus; -// currently used only to retreive savepath -Char *getcwd(Char *buf, UInt32 size) { - Char *copy = buf; + // OSystem_GetMouseStatus(&localStatus); - if (gUnistdCWD) { - if (!copy) - copy = (Char *)MemPtrNew(StrLen(gUnistdCWD)); // this may never occured + *pMouseX = 0; + *pMouseY = 0; - StrCopy(copy, gUnistdCWD); - } + *pMouseButton = 0; +/* + if(localStatus.left) + *pMouseButton |= 1; + if(localStatus.right) + *pMouseButton |= 2; + if(localStatus.middle) + *pMouseButton |= 4; + */ +} - return copy; -}
\ No newline at end of file +} // End of namespace Cruise diff --git a/backends/platform/PalmOS/Src/missing/math.h b/engines/cruise/mouse.h index eca2d9de08..12d3ba2ba0 100644 --- a/backends/platform/PalmOS/Src/missing/math.h +++ b/engines/cruise/mouse.h @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,17 +22,16 @@ * */ -#ifndef __MATH_H__ -#define __MATH_H__ +#ifndef CRUISE_MOUSE_H +#define CRUISE_MOUSE_H -#ifndef PALMOS_ARM -# include "mathlib.h" -#else -# include "matharm.h" -#endif +namespace Cruise { -#ifndef M_PI -# define M_PI 3.14159265358979323846 -#endif +extern int16 main10; + +void getMouseStatus(int16 * pMouseVar, int16 * pMouseX, int16 * pMouseButton, + int16 * pMouseY); + +} // End of namespace Cruise #endif diff --git a/engines/cruise/object.cpp b/engines/cruise/object.cpp new file mode 100644 index 0000000000..2014ab1e4d --- /dev/null +++ b/engines/cruise/object.cpp @@ -0,0 +1,311 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +//10 values: +/* + +0 = X +1 = Y +3 = fileIdx +4 = scale + +*/ + +objDataStruct *getObjectDataFromOverlay(int ovlIdx, int objIdx) { + objDataStruct *var_6; + + if (ovlIdx < 1 || objIdx < 0) + return NULL; + + if (!overlayTable[ovlIdx].ovlData) + return NULL; + + if (overlayTable[ovlIdx].ovlData->numObjData <= objIdx) + return NULL; + + var_6 = overlayTable[ovlIdx].ovlData->objDataTable; + + if (!var_6) + return NULL; + + return (&var_6[objIdx]); +} + +int16 getMultipleObjectParam(int16 overlayIdx, int16 objectIdx, + objectParamsQuery *returnParam) { + int16 size; + int16 var_A; + int16 var_14; + objectParams *ptr2; + objDataStruct *ptr; + ovlDataStruct *ovlData; +// int16 type; + + ptr = getObjectDataFromOverlay(overlayIdx, objectIdx); + + if (!ptr) + return -11; + + ovlData = overlayTable[overlayIdx].ovlData; + + switch (ptr->type) { + case 0: + { + ptr2 = &ovlData->objData2SourceTable[ptr->var5]; + + var_14 = globalVars[*(int16 *) (&overlayTable[overlayIdx].state + ptr->stateTableIdx)]; + + var_A = ptr2->state; + + break; + } + case 1: + { + ptr2 = &ovlData->objData2WorkTable[ptr->var4]; + + var_A = var_14 = ptr2->state; + size = var_A + ptr->var5; + + if (ptr->var5 + var_14 <= ovlData->size8) { + var_A = ovlData->objData2SourceTable[ptr->var5 + var_14].state; + } + break; + } + default: + { + printf("unsupported case %d in getMultipleObjectParam\n", ptr->type); + exit(1); + } + } + + returnParam->X = ptr2->X; + returnParam->Y = ptr2->Y; + returnParam->baseFileIdx = ptr2->Z; + returnParam->fileIdx = ptr2->frame; + returnParam->scale = ptr2->scale; + returnParam->var5 = var_14; + returnParam->var6 = var_A; + returnParam->var7 = ptr->var3; + + return 0; +} + +void setObjectPosition(int16 ovlIdx, int16 objIdx, int16 param3, int16 param4) { + objDataStruct *ptr; + objectParams *ptr2; + + ptr = getObjectDataFromOverlay(ovlIdx, objIdx); + + if (!ptr) { + return; + ASSERT(0); + } + //overlayTable[param1].ovlData + + switch (ptr->type) { + case 1: + { + ptr2 = &overlayTable[ovlIdx].ovlData->objData2WorkTable[ptr->var4]; + + switch (param3) { + case 0: // x + { + ptr2->X = param4; + break; + } + case 1: // y + { + ptr2->Y = param4; + break; + } + case 2: // z + { + ptr2->Z = param4; + sortCells(ovlIdx, objIdx, &cellHead); + break; + } + case 3: + { + ptr2->frame = param4; + break; + } + case 4: // scale + { + ptr2->scale = param4; + break; + } + case 5: // box colision + { + ptr2->state = param4; + break; + } + default: + { + ASSERT(0); + } + } + + break; + } + default: + { + ASSERT(0); + } + } +} + +int16 objInit(int ovlIdx, int objIdx, int newState) { + objDataStruct *ptr; +// uint16 param; + ovlDataStruct *ovlData; + + ptr = getObjectDataFromOverlay(ovlIdx, objIdx); + + if (!ptr) + return -11; + + ovlData = overlayTable[ovlIdx].ovlData; + + switch (ptr->type) { + case THEME: + case MULTIPLE: + { + globalVars[overlayTable[ovlIdx].state + ptr->stateTableIdx] = newState; + sortCells(ovlIdx, objIdx, &cellHead); + break; + } + case UNIQUE: + break; + case VARIABLE: + { + objectParams *destEntry; + objectParams *sourceEntry; + + if (ptr->var5 + newState > ovlData->size8) { + return 0; + } + + destEntry = &ovlData->objData2WorkTable[ptr->var4]; + sourceEntry = &ovlData->objData2SourceTable[ptr->var5 + newState]; + + memcpy(destEntry, sourceEntry, sizeof(objectParams)); + + destEntry->state = newState; + + sortCells(ovlIdx, objIdx, &cellHead); + break; + } + default: + { + printf("Unsupported param = %d in objInit\n", ptr->type); + // exit(1); + } + } + + return 0; +} + +int16 getSingleObjectParam(int16 overlayIdx, int16 param2, int16 param3, int16 *returnParam) { + int var_A = 0; + //char* ptr3 = NULL; + objDataStruct *ptr; + ovlDataStruct *ovlData; + objectParams *ptr2; + + ptr = getObjectDataFromOverlay(overlayIdx, param2); + + if (!ptr) + return -11; + + ovlData = overlayTable[overlayIdx].ovlData; + + switch (ptr->type) { + case 0: + case 3: + { + var_A = globalVars[ptr->stateTableIdx]; + + ptr2 = &ovlData->objData2SourceTable[ptr->var5]; + break; + } + case 1: + { + ptr2 = &ovlData->objData2WorkTable[ptr->var4]; + + var_A = ptr2->state; + break; + } + default: + { + printf("Unsupported case %d in getSingleObjectParam\n",ptr->type); + exit(1); + } + } + + switch (param3) { + case 0: + { + *returnParam = ptr2->X; + break; + } + case 1: + { + *returnParam = ptr2->Y; + break; + } + case 2: + { + *returnParam = ptr2->Z; + break; + } + case 3: + { + *returnParam = ptr2->frame; + break; + } + case 4: + { + *returnParam = ptr2->scale; + break; + } + case 5: + { + *returnParam = var_A; + break; + } + default: + { + printf("Unsupported case %d in getSingleObjectParam case 1\n", param3); + exit(1); + } + } + + return 0; +} + +} // End of namespace Cruise diff --git a/engines/cine/sfx_player.h b/engines/cruise/object.h index 373b2d30cc..439cdcf3a2 100644 --- a/engines/cine/sfx_player.h +++ b/engines/cruise/object.h @@ -22,53 +22,36 @@ * */ -#ifndef CINE_SFXPLAYER_H -#define CINE_SFXPLAYER_H +#ifndef CRUISE_OBJECT_H +#define CRUISE_OBJECT_H -namespace Cine { +namespace Cruise { -class SoundDriver; - -class SfxPlayer { -public: - - enum { - NUM_INSTRUMENTS = 15, - NUM_CHANNELS = 4 - }; - - SfxPlayer(SoundDriver *driver); - ~SfxPlayer(); - - bool load(const char *song); - void play(); - void stop(); - void fadeOut(); - - static void updateCallback(void *ref); - -private: - - void update(); - void handleEvents(); - void handlePattern(int channel, const byte *patternData); - void unload(); +struct gfxEntryStruct { + uint8 *imagePtr; + int imageSize; + int fontIndex; + int height; + int width; // for font: max right border; for sprite: just width +}; - bool _playing; - int _currentPos; - int _currentOrder; - int _numOrders; - int _eventsDelay; - int _fadeOutCounter; - int _updateTicksCounter; - int _instrumentsChannelTable[NUM_CHANNELS]; - byte *_sfxData; - byte *_instrumentsData[NUM_INSTRUMENTS]; - SoundDriver *_driver; +#define OBJ_SPRITE 4 + +struct objectParamsQuery { + int16 X; + int16 Y; + int16 baseFileIdx; + int16 fileIdx; + int16 scale; + int16 var5; + int16 var6; + int16 var7; }; -extern SfxPlayer *g_sfxPlayer; // TEMP +objDataStruct *getObjectDataFromOverlay(int ovlIdx, int objIdx); +int16 getSingleObjectParam(int16 overlayIdx, int16 param2, int16 param3, int16 * returnParam); +int16 getMultipleObjectParam(int16 overlayIdx, int16 objectIdx, objectParamsQuery * returnParam); -} // End of namespace Cine +} // End of namespace Cruise -#endif /* _SFXPLAYER_H_ */ +#endif diff --git a/engines/cruise/overlay.cpp b/engines/cruise/overlay.cpp new file mode 100644 index 0000000000..10e807380a --- /dev/null +++ b/engines/cruise/overlay.cpp @@ -0,0 +1,749 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +overlayStruct overlayTable[90]; +int numOfLoadedOverlay; + +void initOverlayTable(void) { + int i; + + for (i = 0; i < 90; i++) { + overlayTable[i].overlayName[0] = 0; + overlayTable[i].ovlData = NULL; + overlayTable[i].alreadyLoaded = 0; + overlayTable[i].executeScripts = 0; + } + + numOfLoadedOverlay = 1; +} + +int loadOverlay(uint8 *scriptName) { + int newNumberOfScript; + bool scriptNotLoadedBefore; + int scriptIdx; + uint8 fileName[50]; + int fileIdx; + int unpackedSize; + char *unpackedBuffer; + char *scriptPtr; + ovlDataStruct *ovlData; + + printf("Load overlay: %s\n", scriptName); + + newNumberOfScript = numOfLoadedOverlay; + + scriptNotLoadedBefore = false; + + scriptIdx = findOverlayByName((char *)scriptName); + + if (scriptIdx == -4) { + scriptIdx = numOfLoadedOverlay; + + newNumberOfScript++; + + scriptNotLoadedBefore = true; + } + + if (overlayTable[scriptIdx].alreadyLoaded) { + return (scriptIdx); + } + + overlayTable[scriptIdx].ovlData = + (ovlDataStruct *) mallocAndZero(sizeof(ovlDataStruct)); + + if (!overlayTable[scriptIdx].ovlData) + return (-2); + + strcpyuint8(overlayTable[scriptIdx].overlayName, scriptName); + + overlayTable[scriptIdx].alreadyLoaded = 1; + + numOfLoadedOverlay = newNumberOfScript; + + overlayTable[scriptIdx].ovlData->scriptNumber = scriptIdx; + + strcpyuint8(fileName, scriptName); + + strcatuint8(fileName, ".OVL"); + + printf("Attempting to load overlay file %s...\n", fileName); + + fileIdx = findFileInDisks(fileName); + + if (fileIdx < 0) { + printf("Unable to load overlay %s !\n", scriptName); + //releaseScript(scriptName); + return (-18); + } + + unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2; + + // TODO: here, can unpack in gfx module buffer + unpackedBuffer = (char *)mallocAndZero(unpackedSize); + + if (!unpackedBuffer) { + return (-2); + } + + if (volumePtrToFileDescriptor[fileIdx].size + 2 != unpackedSize) { + char *pakedBuffer = + (char *)mallocAndZero(volumePtrToFileDescriptor[fileIdx]. + size + 2); + + loadPakedFileToMem(fileIdx, (uint8 *) pakedBuffer); + + delphineUnpack((uint8 *)unpackedBuffer, (const uint8 *)pakedBuffer, volumePtrToFileDescriptor[fileIdx].size); + + free(pakedBuffer); + } else { + loadPakedFileToMem(fileIdx, (uint8 *) unpackedBuffer); + } + + printf("OVL loading done...\n"); + + scriptPtr = unpackedBuffer; + + ovlData = overlayTable[scriptIdx].ovlData; + + memcpy(ovlData, scriptPtr, sizeof(ovlDataStruct)); + + ovlData->data3Table = NULL; + ovlData->ptr1 = NULL; + ovlData->objDataTable = NULL; + ovlData->objData2SourceTable = NULL; + ovlData->objData2WorkTable = NULL; + ovlData->stringTable = NULL; + ovlData->exportDataPtr = NULL; + ovlData->importDataPtr = NULL; + ovlData->linkDataPtr = NULL; + ovlData->specialString1 = NULL; + ovlData->specialString2 = NULL; + ovlData->importNamePtr = NULL; + ovlData->exportNamesPtr = NULL; + ovlData->data4Ptr = NULL; + ovlData->ptr8 = NULL; + ovlData->numScripts1 = readB16(scriptPtr + 60); + ovlData->numScripts2 = readB16(scriptPtr + 62); + ovlData->numExport = readB16(scriptPtr + 64); + ovlData->numImport = readB16(scriptPtr + 66); + ovlData->numLinkData = readB16(scriptPtr + 68); + ovlData->numObjData = readB16(scriptPtr + 70); + ovlData->numStrings = readB16(scriptPtr + 72); + ovlData->size8 = readB16(scriptPtr + 74); + ovlData->size9 = readB16(scriptPtr + 76); + ovlData->nameExportSize = readB16(scriptPtr + 78); + ovlData->exportNamesSize = readB16(scriptPtr + 80); + ovlData->specialString2Length = readB16(scriptPtr + 82); + ovlData->sizeOfData4 = readB16(scriptPtr + 84); + ovlData->size12 = readB16(scriptPtr + 86); + ovlData->specialString1Length = readB16(scriptPtr + 88); + ovlData->scriptNumber = readB16(scriptPtr + 90); + + scriptPtr += 92; + + if (ovlData->numExport) { // export data + int i; + ovlData->exportDataPtr = + (exportEntryStruct *) mallocAndZero(ovlData->numExport * + sizeof(exportEntryStruct)); + + if (!ovlData->exportDataPtr) { + return (-2); + } + + for (i = 0; i < ovlData->numExport; i++) { + ovlData->exportDataPtr[i].var0 = readB16(scriptPtr); + ovlData->exportDataPtr[i].var2 = + readB16(scriptPtr + 2); + ovlData->exportDataPtr[i].var4 = + readB16(scriptPtr + 4); + ovlData->exportDataPtr[i].idx = readB16(scriptPtr + 6); + ovlData->exportDataPtr[i].offsetToName = + readB16(scriptPtr + 8); + + scriptPtr += 10; + } + } + + if (ovlData->exportNamesSize) { // export names + ovlData->exportNamesPtr = + (uint8 *) mallocAndZero(ovlData->exportNamesSize); + + if (!ovlData->exportNamesPtr) { + return (-2); + } + + memcpy(ovlData->exportNamesPtr, scriptPtr, + ovlData->exportNamesSize); + scriptPtr += ovlData->exportNamesSize; + } + + if (ovlData->numImport) { // import data + int i; + + ovlData->importDataPtr = + (importDataStruct *) mallocAndZero(ovlData->numImport * + sizeof(importDataStruct)); + + if (!ovlData->importDataPtr) { + return (-2); + } + + for (i = 0; i < ovlData->numImport; i++) { + ovlData->importDataPtr[i].var0 = readB16(scriptPtr); + ovlData->importDataPtr[i].var1 = + readB16(scriptPtr + 2); + ovlData->importDataPtr[i].linkType = + readB16(scriptPtr + 4); + ovlData->importDataPtr[i].linkIdx = + readB16(scriptPtr + 6); + ovlData->importDataPtr[i].nameOffset = + readB16(scriptPtr + 8); + + scriptPtr += 10; + } + } + + if (ovlData->nameExportSize) { // import name + ovlData->importNamePtr = + (uint8 *) mallocAndZero(ovlData->nameExportSize); + + if (!ovlData->importNamePtr) { + return (-2); + } + + memcpy(ovlData->importNamePtr, scriptPtr, + ovlData->nameExportSize); + scriptPtr += ovlData->nameExportSize; + } + + if (ovlData->numLinkData) { // link data + ASSERT(sizeof(linkDataStruct) == 0x22); + + ovlData->linkDataPtr = + (linkDataStruct *) mallocAndZero(ovlData->numLinkData * + sizeof(linkDataStruct)); + + if (!ovlData->linkDataPtr) { + return (-2); + } + + memcpy(ovlData->linkDataPtr, scriptPtr, + ovlData->numLinkData * sizeof(linkDataStruct)); + scriptPtr += ovlData->numLinkData * sizeof(linkDataStruct); + flipGen(ovlData->linkDataPtr, + ovlData->numLinkData * sizeof(linkDataStruct)); + } + + if (ovlData->numScripts1) { // script + ovlData3Struct *tempPtr; + int i; + + ovlData->data3Table = + (ovlData3Struct *) mallocAndZero(ovlData->numScripts1 * + sizeof(ovlData3Struct)); + + if (!ovlData->data3Table) { +/* releaseScript(scriptIdx,scriptName); + + if(freeIsNeeded) { + freePtr(unpackedBuffer); + } */ + + return (-2); + } + + memcpy(ovlData->data3Table, scriptPtr, + ovlData->numScripts1 * sizeof(ovlData3Struct)); + scriptPtr += ovlData->numScripts1 * 0x1C; + + flipGen(ovlData->data3Table, + ovlData->numScripts1 * sizeof(ovlData3Struct)); + + tempPtr = ovlData->data3Table; + + for (i = 0; i < ovlData->numScripts1; i++) { + uint8 *ptr = tempPtr->dataPtr = + (uint8 *) mallocAndZero(tempPtr->sizeOfData); + + if (!ptr) { + /* releaseScript(scriptIdx,scriptName); + * + * if(freeIsNeeded) + * { + * freePtr(unpackedBuffer); + * } */ + + return (-2); + } + + memcpy(ptr, scriptPtr, tempPtr->sizeOfData); + scriptPtr += tempPtr->sizeOfData; + + if (tempPtr->offsetToImportData) { + flipGen(ptr + tempPtr->offsetToImportData, + tempPtr->numImport * 10); + } + + if (tempPtr->offsetToSubData2) { + flipGen(ptr + tempPtr->offsetToImportData, + tempPtr->subData2Size * 10); + } + + tempPtr++; + } + } + + if (ovlData->numScripts2) { + ovlData3Struct *tempPtr; + int i; + + ovlData->ptr1 = + (uint8 *) mallocAndZero(ovlData->numScripts2 * 0x1C); + + if (!ovlData->ptr1) { + return (-2); + } + + memcpy(ovlData->ptr1, scriptPtr, ovlData->numScripts2 * 0x1C); + scriptPtr += ovlData->numScripts2 * 0x1C; + flipGen(ovlData->ptr1, ovlData->numScripts2 * 0x1C); + + tempPtr = (ovlData3Struct *) ovlData->ptr1; + + for (i = 0; i < ovlData->numScripts2; i++) { + uint8 *ptr = tempPtr->dataPtr = + (uint8 *) mallocAndZero(tempPtr->sizeOfData); + + if (!ptr) { + /* releaseScript(scriptIdx,scriptName); + * + * if(freeIsNeeded) + * { + * freePtr(unpackedBuffer); + * } */ + + return (-2); + } + + memcpy(ptr, scriptPtr, tempPtr->sizeOfData); + scriptPtr += tempPtr->sizeOfData; + + if (tempPtr->offsetToImportData) { + flipGen(ptr + tempPtr->offsetToImportData, + tempPtr->numImport * 10); + } + + if (tempPtr->offsetToSubData2) { + flipGen(ptr + tempPtr->offsetToImportData, + tempPtr->subData2Size * 10); + } + + tempPtr++; + } + } + + if (ovlData->size12) { + ovlData->ptr8 = (uint8 *) mallocAndZero(ovlData->size12); + + if (!ovlData->ptr8) { +/* releaseScript(scriptIdx,scriptName); + + if(freeIsNeeded) + { + freePtr(unpackedBuffer); + } */ + + return (-2); + } + + memcpy(ovlData->ptr8, scriptPtr, ovlData->size12); + scriptPtr += ovlData->size12; + } + + if (ovlData->numObjData) { + int i; + ovlData->objDataTable = + (objDataStruct *) mallocAndZero(ovlData->numObjData * + sizeof(objDataStruct)); + + if (!ovlData->objDataTable) { +/* releaseScript(scriptIdx,scriptName); + + if(freeIsNeeded) + { + freePtr(unpackedBuffer); + } */ + + return (-2); + } + + for (i = 0; i < ovlData->numObjData; i++) { + ovlData->objDataTable[i].var0 = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].var0); + + ovlData->objDataTable[i].type = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].type); + + ovlData->objDataTable[i].var2 = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].var2); + + ovlData->objDataTable[i].var3 = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].var3); + + ovlData->objDataTable[i].var4 = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].var4); + + ovlData->objDataTable[i].var5 = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].var5); + + ovlData->objDataTable[i].stateTableIdx = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->objDataTable[i].stateTableIdx); + } + + if (scriptNotLoadedBefore) { + //int var1; + //int var2; + + overlayTable[scriptIdx].state = (char)setup1; + + var1 = loadScriptSub1(scriptIdx, 3); + var2 = loadScriptSub1(scriptIdx, 0); + + setup1 = var1 + var2; + } + } + + if (ovlData->size9) { + ovlData->objData2WorkTable = + (objectParams *) mallocAndZero(ovlData->size9 * + sizeof(objectParams)); + memset(ovlData->objData2WorkTable, 0, + ovlData->size9 * sizeof(objectParams)); + + if (!ovlData->objData2WorkTable) { +/* releaseScript(scriptIdx,scriptName); + + if(freeIsNeeded) + { + freePtr(unpackedBuffer); + } */ + + return (-2); + } + } + + if (ovlData->size8) { + ovlData->objData2SourceTable = + (objectParams *) mallocAndZero(ovlData->size8 * + sizeof(objectParams)); + + if (!ovlData->objData2SourceTable) { +/* releaseScript(scriptIdx,scriptName); + + if(freeIsNeeded) + { + freePtr(unpackedBuffer); + } */ + + return (-2); + } + + memcpy(ovlData->objData2SourceTable, scriptPtr, ovlData->size8 * 12); // TODO: made read item by item + scriptPtr += ovlData->size8 * 12; + flipGen(ovlData->objData2SourceTable, ovlData->size8 * 12); + } + + if (ovlData->numStrings) { + int i; + + ovlData->stringTable = + (stringEntryStruct *) mallocAndZero(ovlData->numStrings * + sizeof(stringEntryStruct)); + + for (i = 0; i < ovlData->numStrings; i++) { + ovlData->stringTable[i].idx = *(int16 *) scriptPtr; + flipShort(&ovlData->stringTable[i].idx); + scriptPtr += 2; + } + } + +/* if(freeIsNeeded) + { + freePtr(unpackedBuffer); + } */ + + if (ovlData->sizeOfData4) { + ovlData->data4Ptr = + (uint8 *) mallocAndZero(ovlData->sizeOfData4); + memset(ovlData->data4Ptr, 0, ovlData->sizeOfData4); + + if (!ovlData->data4Ptr) { + //releaseScript(scriptIdx,scriptName); + return (-2); + } + } + + if (ovlData-> + specialString1Length /*|| ovlData->specialString2Length */ + || ovlData->stringTable) { + int i; + //int unpackedSize; + //int fileIdx; + //uint8 fileName[50]; + //char* unpackedBuffer; + + strcpyuint8(fileName, scriptName); + + strcatuint8(fileName, ".FR"); + + fileIdx = findFileInDisks(fileName); + + if (fileIdx < 0) { + //releaseScript(scriptName); + return (-18); + } + + unpackedSize = volumePtrToFileDescriptor[fileIdx].extSize + 2; + + // TODO: here, can unpack in gfx module buffer + unpackedBuffer = (char *)mallocAndZero(unpackedSize); + + if (!unpackedBuffer) { + return (-2); + } + + if (volumePtrToFileDescriptor[fileIdx].size + 2 != + unpackedSize) { + char *pakedBuffer = + (char *) + mallocAndZero(volumePtrToFileDescriptor[fileIdx]. + size + 2); + + loadPakedFileToMem(fileIdx, (uint8 *) pakedBuffer); + + delphineUnpack((uint8 *) unpackedBuffer, (const uint8 *)pakedBuffer, volumePtrToFileDescriptor[fileIdx].size); + + free(pakedBuffer); + } else { + loadPakedFileToMem(fileIdx, (uint8 *) unpackedBuffer); + } + + scriptPtr = unpackedBuffer; + + memcpy(&ovlData->specialString1Length, scriptPtr, 2); + scriptPtr += 2; + flipShort(&ovlData->specialString1Length); // recheck if needed + + if (ovlData->specialString1Length) { + ovlData->specialString1 = + (uint8 *) mallocAndZero(ovlData-> + specialString1Length); + + if (!ovlData->specialString1) { + /* releaseScript(scriptIdx,scriptName); + * + * if(freeIsNeeded) + * { + * freePtr(unpackedBuffer); + * } */ + + return (-2); + } + + memcpy(ovlData->specialString1, scriptPtr, + ovlData->specialString1Length); + scriptPtr += ovlData->specialString1Length; + } + + memcpy(&ovlData->specialString2Length, scriptPtr, 2); + scriptPtr += 2; + flipShort(&ovlData->specialString2Length); // recheck if needed + + if (ovlData->specialString2Length) { + ovlData->specialString2 = + (uint8 *) mallocAndZero(ovlData-> + specialString2Length); + + if (!ovlData->specialString2) { + /* releaseScript(scriptIdx,scriptName); + * + * if(freeIsNeeded) + * { + * freePtr(unpackedBuffer); + * } */ + + return (-2); + } + + memcpy(ovlData->specialString2, scriptPtr, + ovlData->specialString2Length); + scriptPtr += ovlData->specialString2Length; + } + + for (i = 0; i < ovlData->numStrings; i++) { + ovlData->stringTable[i].length = *(int16 *) scriptPtr; + scriptPtr += 2; + flipShort(&ovlData->stringTable[i].length); + + if (ovlData->stringTable[i].length) { + ovlData->stringTable[i].string = + (char *)mallocAndZero(ovlData-> + stringTable[i].length); + + if (!ovlData->stringTable[i].string) { + /* releaseScript(scriptIdx,scriptName); + * + * if(freeIsNeeded) + * { + * freePtr(unpackedBuffer); + * } */ + + return (-2); + } + + memcpy(ovlData->stringTable[i].string, + scriptPtr, ovlData->stringTable[i].length); + scriptPtr += ovlData->stringTable[i].length; + } + } + } +#ifdef DUMP_SCRIPT + { + int i; + for (i = 0; i < ovlData->numScripts1; i++) { + dumpScript(scriptName, ovlData, i); + } + } +#endif +#ifdef DUMP_OBJECT + { + int i; + FILE *fHandle; + char nameBundle[100]; + sprintf(nameBundle, "%s-objs.txt", scriptName); + + fHandle = fopen(nameBundle, "w+"); + ASSERT(fHandle); + + for (i = 0; i < ovlData->numLinkData; i++) { + linkDataStruct *var_34; + var_34 = &ovlData->linkDataPtr[i]; + + if (ovlData->specialString2) { + fprintf(fHandle, "----- object %02d -----\n", + i); + if (var_34->stringNameOffset != 0xFFFF) { + fprintf(fHandle, "name: %s\n", + getObjectName(var_34-> + stringNameOffset, + ovlData->specialString2)); + } + } + } + + fclose(fHandle); + } +#endif + + return (scriptIdx); +} + +int releaseOverlay(const char *name) { + int overlayIdx; + ovlDataStruct *ovlDataPtr; + + overlayIdx = findOverlayByName(name); + + if (overlayIdx == -4) + return -4; + + if (overlayTable[overlayIdx].alreadyLoaded == 0) + return -4; + + overlayTable[overlayIdx].alreadyLoaded = 0; + + ovlDataPtr = overlayTable[overlayIdx].ovlData; + + if (!ovlDataPtr) + return -4; +/* + if(overlayTable[overlayIdx].var1E) + { + free(overlayTable[overlayIdx].var1E); + overlayTable[overlayIdx].var1E = NULL; + } + + if(overlayTable[overlayIdx].var16) + { + free(overlayTable[overlayIdx].var16); + overlayTable[overlayIdx].var16 = NULL; + } */ + + removeScript(overlayIdx, -1, &procHead); + removeScript(overlayIdx, -1, &procHead); + + removeScript(overlayIdx, -1, &relHead); + removeScript(overlayIdx, -1, &relHead); + + printf("releaseOverlay: finish !\n"); + + return 0; +} + +int32 findOverlayByName2(uint8 *name) { + int i; + + for (i = 1; i < numOfLoadedOverlay; i++) { + if (!strcmpuint8(overlayTable[i].overlayName, name)) + return (i); + } + + return (-4); +} + +int findOverlayByName(const char *overlayName) { + int i; + + for (i = 1; i < numOfLoadedOverlay; i++) { + if (!strcmp(overlayTable[i].overlayName, overlayName)) { + return (i); + } + } + + return (-4); +} + +} // End of namespace Cruise diff --git a/engines/cruise/overlay.h b/engines/cruise/overlay.h new file mode 100644 index 0000000000..07f814701c --- /dev/null +++ b/engines/cruise/overlay.h @@ -0,0 +1,191 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_OVERLAY_H +#define CRUISE_OVERLAY_H + +namespace Cruise { + +struct importScriptStruct { + uint16 var0; + uint16 var1; + uint16 type; + uint16 offset; + uint16 offsetToName; +}; + +struct exportEntryStruct { + uint16 var0; + uint16 var2; + uint16 var4; + uint16 idx; + uint16 offsetToName; +}; + +struct ovlData3Struct { + uint8 *dataPtr; //0 + short int sizeOfData; //4 + short int offsetToSubData3; //6 + short int offsetToImportData; //8 + short int offsetToSubData2; + short int offsetToImportName; + short int offsetToSubData5; + short int sysKey; + short int var12; + short int numImport; + short int subData2Size; + short int var18; + short int var1A; +}; + +struct stringEntryStruct { + char *string; + short int length; + short int idx; +}; + +struct linkDataStruct { + uint16 field_0; + uint16 field_2; + uint16 field_4; + uint16 varIdx; + uint16 varNameOffset; + uint16 stringIdx; + uint16 stringNameOffset; + uint16 procIdx; + uint16 procNameOffset; + + int16 field_12; + int16 field_14; + int16 field_16; + int16 field_18; + int16 field_1A; + int16 field_1C; + int16 field_1E; + int16 field_20; +}; + +struct importDataStruct { + uint16 var0; // 0 + uint16 var1; // 2 + uint16 linkType; // 4 + uint16 linkIdx; // 6 + uint16 nameOffset; +}; + +#define MULTIPLE 0 +#define VARIABLE 1 +#define UNIQUE 2 +#define THEME 3 + +struct objDataStruct { + int16 var0; + int16 type; + int16 var2; + int16 var3; + int16 var4; + int16 var5; + int16 stateTableIdx; +}; + +struct objectParams { + int16 X; + int16 Y; + int16 Z; + int16 frame; + int16 scale; + int16 state; +}; + +struct ovlDataStruct { + ovlData3Struct *data3Table; + uint8 *ptr1; + objDataStruct *objDataTable; + objectParams *objData2SourceTable; + objectParams *objData2WorkTable; + stringEntryStruct *stringTable; + exportEntryStruct *exportDataPtr; + importDataStruct *importDataPtr; + linkDataStruct *linkDataPtr; + uint8 *specialString1; + uint8 *specialString2; + uint8 *importNamePtr; + uint8 *exportNamesPtr; + uint8 *data4Ptr; + uint8 *ptr8; + unsigned short int numScripts1; + unsigned short int numScripts2; + unsigned short int numExport; + unsigned short int numImport; + unsigned short int numLinkData; + unsigned short int numObjData; + unsigned short int numStrings; + unsigned short int size8; + unsigned short int size9; + unsigned short int nameExportSize; + unsigned short int exportNamesSize; + unsigned short int specialString2Length; + unsigned short int sizeOfData4; + unsigned short int size12; + unsigned short int specialString1Length; + unsigned short int scriptNumber; +}; + +struct overlayStruct { + char overlayName[14]; + ovlDataStruct *ovlData; + short int alreadyLoaded; + char state; + char field_15; + char field_16; + char field_17; + char field_18; + char field_19; + char field_1A; + char field_1B; + char field_1C; + char field_1D; + char field_1E; + char field_1F; + char field_20; + char field_21; + char field_22; + char field_23; + char field_24; + char field_25; + short int executeScripts; +}; + +extern overlayStruct overlayTable[90]; +extern int numOfLoadedOverlay; + +void initOverlayTable(void); +int loadOverlay(uint8 * scriptName); +int32 findOverlayByName2(uint8 * name); +int findOverlayByName(const char *overlayName); +int releaseOverlay(const char *name); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/perso.cpp b/engines/cruise/perso.cpp new file mode 100644 index 0000000000..e8f8c91743 --- /dev/null +++ b/engines/cruise/perso.cpp @@ -0,0 +1,250 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" +#include "common/util.h" + +namespace Cruise { + +persoStruct *persoTable[NUM_PERSONS]; + +int16 computedVar14; + +void freePerso(int persoIdx) { + if (persoTable[persoIdx]) { + free(persoTable[persoIdx]); + persoTable[persoIdx] = NULL; + } +} + +void freeAllPerso(void) { + int i; + + for (i = 0; i < NUM_PERSONS; i++) { + freePerso(i); + } + + if (polyStruct) { + free(polyStruct); + } + + ctpVar17 = NULL; + polyStruct = NULL; + + strcpy((char *)currentCtpName, ""); +} + +int pathVar0; + +unsigned int inc_droite2, inc_jo; + +int direction(int x1, int y1, int x2, int y2, int inc_jo1, int inc_jo2) { + int h, v, h1, v1; + + h1 = x1 - x2; + h = ABS(h1); + v1 = y1 - y2; + v = ABS(v1); + + if (v > h) { + if (h > 30) + inc_jo = inc_jo1 - inc_jo2; + else + inc_jo = inc_jo2; + + if (v1 < 0) + return (2); + else + return (0); + } else { + inc_jo = inc_jo1; + + if (h1 < 0) + return (1); + else + return (3); + } +} + +void cor_droite(int x1, int y1, int x2, int y2, int16 cor_joueur[400][2]) { + int16 *di = (int16 *) cor_joueur; + int dx; + int dy; + + int mD0; + int mD1; + + int mA0; + int mA1; + + int bp; + int cx; + int si; + + int ax; + int bx; + + di[0] = x1; + di[1] = y1; + di += 2; + + dx = x2 - x1; + dy = y2 - y1; + + mD0 = mD1 = 1; + + if (dx < 0) { + dx = -dx; + mD0 = -1; + } + + if (dy < 0) { + dy = -dy; + mD1 = -1; + } + + if (dx < dy) { + mA0 = 0; + bp = dx; + cx = dy; + + mA1 = mD1; + } else { + mA1 = 0; + bp = dy; + cx = dx; + + mA0 = mD0; + } + + bp = bp * 2; + dx = bp - cx; + si = dx - cx; + + ax = x1; + bx = y1; + + while (--cx) { + if (dx > 0) { + ax += mD0; + bx += mD1; + dx += si; + } else { + ax += mA0; + bx += mA1; + dx += bp; + } + + di[0] = ax; + di[1] = bx; + di += 2; + } + + flag_obstacle = 0; + inc_droite2 = (di - (int16 *) cor_joueur) / 2; +} + +void processActorWalk(int16 resx_y[4], int16 *inc_droite, int16 *inc_droite0, + int16 *inc_chemin, int16 cor_joueur[400][2], + int16 solution0[NUM_NODES + 3][2], int16 *inc_jo1, int16 *inc_jo2, + int16 *dir_perso, int16 *inc_jo0, int16 num) { + int x1, x2, y1, y2; + int i, u; + + u = 0; + inc_jo = *inc_jo0; + + i = *inc_chemin; + + if (!*inc_droite) { + x1 = solution0[i][0]; + y1 = solution0[i][1]; + i++; + if (solution0[i][0] != -1) { + do { + if (solution0[i][0] != -2) { + x2 = solution0[i][0]; + y2 = solution0[i][1]; + if ((x1 == x2) && (y1 == y2)) { + resx_y[0] = -1; + resx_y[1] = -1; + freePerso(num); + + return; + } + cor_droite(x1, y1, x2, y2, cor_joueur); + *inc_droite0 = inc_droite2; + *dir_perso = resx_y[2] = + direction(x1, y1, x2, y2, *inc_jo1, + *inc_jo2); + *inc_jo0 = inc_jo; + u = 1; + } else + i++; + + } while (solution0[i][0] != -1 && !u); + } + if (!u) { + resx_y[0] = -1; + resx_y[1] = -1; + freePerso(num); + + return; + } + *inc_chemin = i; + } + + resx_y[0] = cor_joueur[*inc_droite][0]; + resx_y[1] = cor_joueur[*inc_droite][1]; + resx_y[2] = *dir_perso; + resx_y[3] = computeZoom(resx_y[1]); + + getPixel(resx_y[0], resx_y[1]); + resx_y[4] = computedVar14; + + u = subOp23(resx_y[3], inc_jo); + if (!u) + u = 1; + *inc_droite += u; + + if ((*inc_droite) >= (*inc_droite0)) { + *inc_droite = 0; + resx_y[0] = solution0[*inc_chemin][0]; + resx_y[1] = solution0[*inc_chemin][1]; + } + +} + +void affiche_chemin(int16 persoIdx, int16 *returnVar) { + persoStruct *pPerso = persoTable[persoIdx]; + + ASSERT(pPerso); + + processActorWalk(returnVar, &pPerso->inc_droite, &pPerso->inc_droite0, + &pPerso->inc_chemin, pPerso->coordinates, pPerso->solution, + &pPerso->inc_jo1, &pPerso->inc_jo2, &pPerso->dir_perso, + &pPerso->inc_jo0, persoIdx); +} + +} // End of namespace Cruise diff --git a/backends/platform/wince/CEKeysDialog.h b/engines/cruise/perso.h index 37566bf431..5a600e2d7f 100644 --- a/backends/platform/wince/CEKeysDialog.h +++ b/engines/cruise/perso.h @@ -1,5 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,27 +22,35 @@ * */ -#ifndef CEKEYSDIALOG -#define CEKEYSDIALOG +#ifndef CRUISE_PERSO_H +#define CRUISE_PERSO_H -#include "gui/newgui.h" -#include "gui/dialog.h" -#include "gui/ListWidget.h" -#include "common/str.h" +namespace Cruise { -class CEKeysDialog : public GUI::Dialog { -public: - CEKeysDialog(const Common::String &title = "Choose an action to map"); +enum { + NUM_NODES = 20, + NUM_PERSONS = 10 +}; - virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers); +struct persoStruct { + int16 inc_droite; // 2 + int16 inc_droite0; // 2 + int16 inc_chemin; // 2 + int16 coordinates[400][2]; // 1600 + int16 solution[NUM_NODES + 3][2]; //((20+3)*2*2) + int16 inc_jo1; // 2 + int16 inc_jo2; // 2 + int16 dir_perso; // 2 + int16 inc_jo0; // 2 +}; -protected: +extern persoStruct *persoTable[NUM_PERSONS]; +extern int16 computedVar14; - GUI::ListWidget *_actionsList; - GUI::StaticTextWidget *_actionTitle; - GUI::StaticTextWidget *_keyMapping; - int _actionSelected; -}; +void freePerso(int persoIdx); +void freeAllPerso(void); +void affiche_chemin(int16 persoIdx, int16 * returnVar); + +} // End of namespace Cruise #endif diff --git a/engines/cruise/polys.cpp b/engines/cruise/polys.cpp new file mode 100644 index 0000000000..a28ff52d15 --- /dev/null +++ b/engines/cruise/polys.cpp @@ -0,0 +1,279 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" +#include "common/util.h" + +namespace Cruise { + +typedef char ColorP; + +#define SCREENHEIGHT 200 +#define MAXPTS 10 +#define putdot(x,y) {if ((y >= 0) && (y < SCREENHEIGHT)) dots[y][counters[y]++] = x;} + +void hline(int x1, int x2, int y, char c) { + for (; x1 <= x2; x1++) { + pixel(x1, y, c); + } +} + +void vline(int x, int y1, int y2, char c) { + for (; y1 <= y2; y1++) { + pixel(x, y1, c); + } +} + +void bsubline_1(int x1, int y1, int x2, int y2, char c) { + int x, y, ddx, ddy, e; + ddx = ABS(x2 - x1); + ddy = ABS(y2 - y1) << 1; + e = ddx - ddy; + ddx <<= 1; + + if (x1 > x2) { + SWAP(x1, x2); + SWAP(y1, y2); + } + + for (x = x1, y = y1; x <= x2; x++) { + + pixel(x, y, c); + if (e < 0) { + y++; + e += ddx - ddy; + } else { + e -= ddy; + } + } + +} + +void bsubline_2(int x1, int y1, int x2, int y2, char c) { + + int x, y, ddx, ddy, e; + ddx = ABS(x2 - x1) << 1; + ddy = ABS(y2 - y1); + e = ddy - ddx; + ddy <<= 1; + + if (y1 > y2) { + SWAP(x1, x2); + SWAP(y1, y2); + } + + for (y = y1, x = x1; y <= y2; y++) { + + pixel(x, y, c); + if (e < 0) { + x++; + e += ddy - ddx; + } else { + e -= ddx; + } + } + +} + +void bsubline_3(int x1, int y1, int x2, int y2, char c) { + + int x, y, ddx, ddy, e; + + ddx = ABS(x1 - x2) << 1; + ddy = ABS(y2 - y1); + e = ddy - ddx; + ddy <<= 1; + + if (y1 > y2) { + SWAP(x1, x2); + SWAP(y1, y2); + } + + for (y = y1, x = x1; y <= y2; y++) { + + pixel(x, y, c); + if (e < 0) { + x--; + e += ddy - ddx; + } else { + e -= ddx; + } + } + +} + +void bsubline_4(int x1, int y1, int x2, int y2, char c) { + + int x, y, ddx, ddy, e; + + ddy = ABS(y2 - y1) << 1; + ddx = ABS(x1 - x2); + e = ddx - ddy; + ddx <<= 1; + + if (x1 > x2) { + SWAP(x1, x2); + SWAP(y1, y2); + } + + for (x = x1, y = y1; x <= x2; x++) { + + pixel(x, y, c); + if (e < 0) { + y--; + e += ddx - ddy; + } else { + e -= ddy; + } + } +} + +void line(int x1, int y1, int x2, int y2, char c) { + + float k; + + if ((x1 == x2) && (y1 == y2)) { + pixel(x1, y1, c); + return; + } + + if (x1 == x2) { + vline(x1, MIN(y1, y2), MAX(y1, y2), c); + return; + } + + if (y1 == y2) { + hline(MIN(x1, x2), MAX(x1, x2), y1, c); + return; + } + + k = (float)(y2 - y1) / (float)(x2 - x1); + + if ((k >= 0) && (k <= 1)) { + bsubline_1(x1, y1, x2, y2, c); + } else if (k > 1) { + bsubline_2(x1, y1, x2, y2, c); + } else if ((k < 0) && (k >= -1)) { + bsubline_4(x1, y1, x2, y2, c); + } else { + bsubline_3(x1, y1, x2, y2, c); + } +} + +// Filled polygons. This probably isn't pixel-perfect compared to the original, +// but it seems to work a bit better than the previous version. + +static void add_intersect(int *intersect, int x, byte &num) { + if (num < MAXPTS) { + int i; + + for (i = num; i > 0 && intersect[i - 1] > x; i--) { + intersect[i] = intersect[i - 1]; + } + + intersect[i] = x; + num++; + } +} + +void fillpoly(int16 *point_data, int lineCount, ColorP color) { + static int intersect[SCREENHEIGHT][MAXPTS]; + static byte num_intersect[SCREENHEIGHT]; + + switch (lineCount) { + case 0: // do nothing + return; + case 1: // draw pixel + pixel(point_data[0], point_data[1], color); + return; + case 2: // draw line + line(point_data[0], point_data[1], point_data[2], point_data[3], color); + return; + default: // go on and draw polygon + break; + } + + // Reinit array counters + + int x1, y1, x2, y2; + int y, i; + + for (i = 0; i < SCREENHEIGHT; i++) { + num_intersect[i] = 0; + } + + // Find the top/bottom of the polygon. + + int top = point_data[1]; + int bottom = point_data[1]; + + for (i = 1; i < lineCount; i++) { + if (point_data[2 * i + 1] < top) + top = point_data[2 * i + 1]; + else if (point_data[2 * i + 1] > bottom) + bottom = point_data[2 * i + 1]; + } + + if (top < 0) + top = 0; + if (bottom >= SCREENHEIGHT) + bottom = SCREENHEIGHT - 1; + + // Calculate intersections for each scan line + + for (y = top; y <= bottom; y++) { + x2 = point_data[2 * lineCount - 2]; + y2 = point_data[2 * lineCount - 1]; + + for (i = 0; i < lineCount; i++) { + x1 = x2; + y1 = y2; + x2 = point_data[2 * i]; + y2 = point_data[2 * i + 1]; + + // Test if the line intersects the scan line + + if ((y < y1) != (y < y2)) { + if (y1 == y2) { + add_intersect(intersect[y], x1, num_intersect[y]); + add_intersect(intersect[y], x2, num_intersect[y]); + } else if (x1 == x2) { + add_intersect(intersect[y], x1, num_intersect[y]); + } else { + add_intersect(intersect[y], x1 + ((y - y1) * (x2 - x1)) / (y2 - y1), num_intersect[y]); + } + } + } + } + + // Drawing. + + for (y = top; y <= bottom; y++) { + for (i = 0; i < num_intersect[y]; i += 2) { + hline(intersect[y][i], intersect[y][i + 1], y, color); + } + } +} + +} // End of namespace Cruise diff --git a/backends/platform/PalmOS/Src/extend.h b/engines/cruise/polys.h index c5c74852a2..f8d192fae0 100644 --- a/backends/platform/PalmOS/Src/extend.h +++ b/engines/cruise/polys.h @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,13 +22,16 @@ * */ -#ifndef EXTEND_H -#define EXTEND_H +#ifndef CRUISE_POLYS_H +#define CRUISE_POLYS_H + +namespace Cruise { + +typedef char ColorP; -extern const Char *SCUMMVM_SAVEPATH; +void fillpoly(int16 *point_data, int n, ColorP c); +void line(int x1, int y1, int x2, int y2, ColorP color); -int main(int argc, char **argv); -void PalmFatalError(const Char *err); -void DrawStatus(Boolean show); +} // End of namespace Cruise #endif diff --git a/engines/cruise/saveload.cpp b/engines/cruise/saveload.cpp new file mode 100644 index 0000000000..21882a096d --- /dev/null +++ b/engines/cruise/saveload.cpp @@ -0,0 +1,413 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +void loadSavegameDataSub1(FILE *fileHandle) { + int i; + + for (i = 1; i < numOfLoadedOverlay; i++) { + filesData[i].field_4 = NULL; + filesData[i].field_0 = NULL; + filesData2[i].field_0 = 0; + + if (overlayTable[i].alreadyLoaded) { + fread(&filesData2[i].field_0, 2, 1, fileHandle); + + if (filesData2[i].field_0) { + filesData[i].field_0 = + (uint8 *) mallocAndZero(filesData2[i]. + field_0); + if (filesData[i].field_0) { + fread(filesData[i].field_0, + filesData2[i].field_0, 1, + fileHandle); + } + } + + fread(&filesData2[i].field_2, 2, 1, fileHandle); + + if (filesData2[i].field_2) { + filesData[i].field_4 = + (uint8 *) mallocAndZero(filesData2[i]. + field_2 * 12); + if (filesData[i].field_4) { + fread(filesData[i].field_4, + filesData2[i].field_2 * 12, 1, + fileHandle); + } + } + } + } +} + +void loadScriptsFromSave(FILE *fileHandle, scriptInstanceStruct *entry) { + short int numScripts; + int i; + + fread(&numScripts, 2, 1, fileHandle); + + for (i = 0; i < numScripts; i++) { + scriptInstanceStruct *ptr = + (scriptInstanceStruct *) + mallocAndZero(sizeof(scriptInstanceStruct)); + + fread(ptr, 0x1C, 1, fileHandle); // use 0x1C as our scriptInstanceStruct is bigger than in original because of cross platform problems + + fread(&ptr->varA, 2, 1, fileHandle); + + if (ptr->varA) { + ptr->var6 = (uint8 *) mallocAndZero(ptr->varA); + + fread(ptr->var6, ptr->varA, 1, fileHandle); + } + ///////// + ptr->bitMask = *((int16 *) ptr + 1); + ///////// + + ptr->nextScriptPtr = 0; + + entry->nextScriptPtr = ptr; + entry = ptr; + } +} + +void loadSavegameActor(FILE *fileHandle) { + short int numEntry; + actorStruct *ptr; + int i; + + fread(&numEntry, 2, 1, fileHandle); + + ptr = &actorHead; + + for (i = 0; i < numEntry; i++) { + actorStruct *current = + (actorStruct *) mallocAndZero(sizeof(actorStruct)); + fseek(fileHandle, 4, SEEK_CUR); + fread(current, 0x26, 1, fileHandle); + + current->next = NULL; + ptr->next = current; + current->prev = actorHead.prev; + actorHead.prev = current; + ptr = current->next; + } +} + +void loadSavegameDataSub5(FILE *fileHandle) { + if (var1) { + fread(&saveVar1, 1, 1, fileHandle); + + if (saveVar1) { + fread(saveVar2, saveVar1, 1, fileHandle); + } + } else { + fread(&saveVar1, 1, 1, fileHandle); + } + +} + +void loadSavegameDataSub6(FILE *fileHandle) { + int32 var; + + fread(&var, 4, 1, fileHandle); + flipLong(&var); + + if (var) { + int i; + + fread(&numberOfWalkboxes, 2, 1, fileHandle); + + if (numberOfWalkboxes) { + fread(walkboxType, numberOfWalkboxes * 2, 1, + fileHandle); + fread(walkboxType, numberOfWalkboxes * 2, 1, + fileHandle); + } + + for (i = 0; i < 10; i++) { + fread(&persoTable[i], 4, 1, fileHandle); + + if (persoTable[i]) { + assert(sizeof(persoStruct) == 0x6AA); + persoTable[i] = + (persoStruct *) + mallocAndZero(sizeof(persoStruct)); + fread(persoTable[i], 0x6AA, 1, fileHandle); + } + } + } +} + +int loadSavegameData(int saveGameIdx) { + char buffer[256]; + FILE *fileHandle; + char saveIdentBuffer[6]; + int j; + int initVar1Save; + cellStruct *currentcellHead; + + sprintf(buffer, "CR.%d", saveGameIdx); + + fileHandle = fopen(buffer, "rb"); + + if (!fileHandle) { + printInfoBlackBox("Sauvegarde non trouve..."); + waitForPlayerInput(); + return (-1); + } + + printInfoBlackBox("Chargement en cours..."); + + fread(saveIdentBuffer, 6, 1, fileHandle); + + if (strcmp(saveIdentBuffer, "SAVPC")) { + fclose(fileHandle); + return (-1); + } + //initVars(); + + fread(&var1, 2, 1, fileHandle); + fread(&var2, 2, 1, fileHandle); + fread(&var3, 2, 1, fileHandle); + fread(&var4, 2, 1, fileHandle); + fread(&userEnabled, 2, 1, fileHandle); + fread(&var6, 2, 1, fileHandle); + fread(&var7, 2, 1, fileHandle); + fread(&var8, 2, 1, fileHandle); + fread(&userDelay, 2, 1, fileHandle); + fread(&sysKey, 2, 1, fileHandle); + fread(&var11, 2, 1, fileHandle); + fread(&var12, 2, 1, fileHandle); + fread(&var13, 2, 1, fileHandle); + fread(&var14, 2, 1, fileHandle); + fread(&affichePasMenuJoueur, 2, 1, fileHandle); + fread(&var20, 2, 1, fileHandle); + fread(&var22, 2, 1, fileHandle); + fread(&var23, 2, 1, fileHandle); + fread(&var24, 2, 1, fileHandle); + fread(&automaticMode, 2, 1, fileHandle); + + // video param (not loaded in EGA mode) + + fread(&video4, 2, 1, fileHandle); + fread(&video2, 2, 1, fileHandle); + fread(&video3, 2, 1, fileHandle); + fread(&colorOfSelectedSaveDrive, 2, 1, fileHandle); + + // + + fread(&var30, 2, 1, fileHandle); + fread(&var31, 2, 1, fileHandle); + fread(&var34, 2, 1, fileHandle); + fread(&var35, 2, 1, fileHandle); + int16 bTemp; + fread(&bTemp, 2, 1, fileHandle); + animationStart = bTemp != 0; + fread(¤tActiveBackgroundPlane, 2, 1, fileHandle); + fread(&initVar3, 2, 1, fileHandle); + fread(&initVar2, 2, 1, fileHandle); + fread(&var22, 2, 1, fileHandle); + fread(&main5, 2, 1, fileHandle); + fread(&numOfLoadedOverlay, 2, 1, fileHandle); + fread(&setup1, 2, 1, fileHandle); + fread(&fontFileIndex, 2, 1, fileHandle); + fread(¤tActiveMenu, 2, 1, fileHandle); + fread(&main7, 2, 1, fileHandle); // ok + fread(&main17, 2, 1, fileHandle); + fread(&main14, 2, 1, fileHandle); + fread(&main8, 2, 1, fileHandle); + fread(&var39, 2, 1, fileHandle); + fread(&var42, 2, 1, fileHandle); + fread(&var45, 2, 1, fileHandle); + fread(&var46, 2, 1, fileHandle); + fread(&var47, 2, 1, fileHandle); + fread(&var48, 2, 1, fileHandle); + fread(&flagCt, 2, 1, fileHandle); + fread(&var41, 2, 1, fileHandle); + fread(&entrerMenuJoueur, 2, 1, fileHandle); + + fread(var50, 64, 1, fileHandle); + fread(var50, 64, 1, fileHandle); // Hu ? why 2 times ? + fread(&systemStrings, sizeof(systemStrings), 1, fileHandle); // ok + fread(currentCtpName, 40, 1, fileHandle); + fread(backgroundTable, 120, 1, fileHandle); + fread(palette, 256, 2, fileHandle); // ok + fread(initVar5, 24, 1, fileHandle); + fread(globalVars, setup1 * 2, 1, fileHandle); + fread(filesDatabase, 9766, 1, fileHandle); + fread(overlayTable, 40 * numOfLoadedOverlay, 1, fileHandle); // ok + fread(mediumVar, 0x880, 1, fileHandle); + + loadSavegameDataSub1(fileHandle); + loadScriptsFromSave(fileHandle, &procHead); + loadScriptsFromSave(fileHandle, &relHead); + + loadSavegameDataSub2(fileHandle); + loadBackgroundIncrustFromSave(fileHandle); + loadSavegameActor(fileHandle); + loadSavegameDataSub5(fileHandle); + loadSavegameDataSub6(fileHandle); + + fclose(fileHandle); // finished with loading !!!!! Yatta ! + + for (j = 0; j < 64; j++) { + mediumVar[j].ptr = NULL; + } + + for (j = 1; j < numOfLoadedOverlay; j++) { + if (overlayTable[j].alreadyLoaded) { + overlayTable[j].alreadyLoaded = 0; + loadOverlay((uint8 *) overlayTable[j].overlayName); + + if (overlayTable[j].alreadyLoaded) { + ovlDataStruct *ovlData = + overlayTable[j].ovlData; + + if (filesData[j].field_0) { + if (ovlData->data4Ptr) { + free(ovlData->data4Ptr); + } + + ovlData->data4Ptr = + (uint8 *) filesData[j].field_0; + ovlData->sizeOfData4 = + filesData2[j].field_0; + } + + if (filesData[j].field_4) { + if (ovlData->objData2WorkTable) { + free(ovlData-> + objData2WorkTable); + } + + ovlData->objData2WorkTable = (objectParams *) filesData[j].field_4; // TODO: fix ! + ovlData->size9 = filesData2[j].field_2; + } + + } + } + } + + updateAllScriptsImports(); + + saveVar6[0] = 0; + + initVar1Save = initVar1; + + for (j = 0; j < 257; j++) { + if (filesDatabase[j].subData.ptr) { + int i; + int k; + + for (i = j + 1; i < 257; i++) { + if (filesDatabase[i].subData.ptr) { + if (strcmpuint8(filesDatabase[j]. + subData.name, + filesDatabase[i].subData. + name)) { + break; + } + } else { + break; + } + } + + for (k = j; k < i; k++) { + if (filesDatabase[k].subData.ptr2) + initVar1 = 0; + + filesDatabase[k].subData.ptr = NULL; + filesDatabase[k].subData.ptr2 = NULL; + } + + if (i < 2) { + printf("Unsupported mono file load!\n"); + exit(1); + //loadFileMode1(filesDatabase[j].subData.name,filesDatabase[j].subData.var4); + } else { + loadFileMode2((uint8 *) filesDatabase[j]. + subData.name, + filesDatabase[j].subData.index, j, i - j); + j = i - 1; + } + + initVar1 = initVar1Save; + } + } + + saveVar6[0] = 0; + + currentcellHead = cellHead.next; + + while (currentcellHead) { + if (currentcellHead->type == 5) { + uint8 *ptr = + mainProc14(currentcellHead->overlay, + currentcellHead->idx); + + ASSERT(0); + + if (ptr) { + ASSERT(0); + //*(int16*)(currentcellHead->datas+0x2E) = getSprite(ptr,*(int16*)(currentcellHead->datas+0xE)); + } else { + //*(int16*)(currentcellHead->datas+0x2E) = 0; + } + } + + currentcellHead = currentcellHead->next; + } + + //TODO: here, restart music + + if (strlen((char *)currentCtpName)) { + ctpVar1 = 1; + loadCtp(currentCtpName); + ctpVar1 = 0; + } + //prepareFadeOut(); + //gfxModuleData.gfxFunction8(); + + for (j = 0; j < 8; j++) { + if (strlen((char *)backgroundTable[j].name)) { + loadBackground(backgroundTable[j].name, j); + } + } + + regenerateBackgroundIncrust(&backgroundIncrustHead); + + // to finish + + changeCursor(0); + mainDraw(1); + flipScreen(); + + return (0); +} + +} // End of namespace Cruise diff --git a/engines/cruise/saveload.h b/engines/cruise/saveload.h new file mode 100644 index 0000000000..179c0a78f1 --- /dev/null +++ b/engines/cruise/saveload.h @@ -0,0 +1,34 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_SAVELOAD_H +#define CRUISE_SAVELOAD_H + +namespace Cruise { + +int loadSavegameData(int saveGameIdx); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp new file mode 100644 index 0000000000..f690530a09 --- /dev/null +++ b/engines/cruise/script.cpp @@ -0,0 +1,771 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +scriptInstanceStruct relHead; +scriptInstanceStruct procHead; + +scriptInstanceStruct *currentScriptPtr; + +uint8 getByteFromScript(void) { + uint8 var = currentData3DataPtr[currentScriptPtr->var4]; + + currentScriptPtr->var4 = currentScriptPtr->var4 + 1; + + return (var); +} + +short int getShortFromScript(void) { + short int var = *(int16 *) (currentData3DataPtr + currentScriptPtr->var4); + + currentScriptPtr->var4 = currentScriptPtr->var4 + 2; + + flipShort(&var); + + return (var); +} + +// load opcode +int32 opcodeType0(void) { + switch (currentScriptOpcodeType) { + case 0: + { + pushVar(getShortFromScript()); + return (0); + } + case 1: + { + uint8 *ptr = 0; + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + short int short1 = getShortFromScript(); + + int var_E = byte1 & 7; + + if (!var_E) { + return (-10); + } + + if (!byte2) { + ptr = scriptDataPtrTable[var_E] + short1; + } else // TODO: + { + if (!overlayTable[byte2].alreadyLoaded) { + return (-7); + } + + if (!overlayTable[byte2].ovlData) { + return (-4); + } + + if (var_E == 5) { + ptr = + overlayTable[byte2].ovlData-> + data4Ptr + short1; + } else { + assert(0); + } + } + + if (((byte1 & 0x18) >> 3) == 1) { + pushVar(loadShort(ptr)); + return (0); + } else if (((byte1 & 0x18) >> 3) == 2) { + pushVar(*ptr); + return (0); + } else { + printf + ("Unsupported code in opcodeType0 case 1!\n"); + exit(1); + } + + return (0); + } + case 2: + { + int16 var_16; + int di = getByteFromScript(); + int si = getByteFromScript(); + int var_2 = getShortFromScript(); + + if (!si) { + si = currentScriptPtr->overlayNumber; + } + + if (getSingleObjectParam(si, var_2, di, &var_16)) { + return -10; + } + + pushVar(var_16); + return (0); + + break; + } + case 5: + { + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + short int short1 = getShortFromScript(); + + short int var_12 = short1; + // short int var_10 = saveOpcodeVar; + + int var_E = byte1 & 7; + + uint8 *ptr = 0; + + if (!var_E) { + return (-10); + } + + if (!byte2) { + ptr = scriptDataPtrTable[var_E] + var_12; + } else // TODO: + { + if (!overlayTable[byte2].alreadyLoaded) { + return (-7); + } + + if (!overlayTable[byte2].ovlData) { + return (-4); + } + + if (var_E == 5) { + ptr = + overlayTable[byte2].ovlData-> + data4Ptr + var_12; + } else { + assert(0); + } + } + + if (((byte1 & 0x18) >> 3) == 1) { + pushVar(loadShort(ptr + saveOpcodeVar * 2)); // TODO: check this ! + return (0); + } else if (((byte1 & 0x18) >> 3) == 2) { + pushVar(*(ptr + saveOpcodeVar)); + return (0); + } else { + printf + ("Unsupported code in opcodeType0 case 1!\n"); + exit(1); + } + + return (0); + } + default: + { + printf("Unsupported type %d in opcodeType0\n", + currentScriptOpcodeType); + exit(1); + } + } + + return 0; +} + +// save opcode +int32 opcodeType1(void) { + int var = popVar(); + int offset = 0; + + switch (currentScriptOpcodeType) { + case 0: + { + return (0); // strange, but happens also in original interpreter + } + case 5: + { + offset = saveOpcodeVar; + } + case 1: + { + int var_A = 0; + + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + + int short1 = getShortFromScript(); + + int var_6 = byte1 & 7; + + int var_C = short1; + + uint8 *ptr = 0; + int type2; + + if (!var_6) + return (-10); + + var_C = short1; + + if (byte2) { + if (!overlayTable[byte2].alreadyLoaded) { + return (-7); + } + + if (!overlayTable[byte2].ovlData) { + return (-4); + } + + if (var_6 == 5) { + ptr = + overlayTable[byte2].ovlData-> + data4Ptr + var_C; + } else { + ASSERT(0); + } + } else { + ptr = scriptDataPtrTable[var_6] + var_C; + } + + type2 = ((byte1 & 0x18) >> 3); + + switch (type2) { + case 1: + { + saveShort(ptr + var_A + offset * 2, + var); + return 0; + } + case 2: + { + *(ptr + var_A + offset) = var; + return (0); + } + default: + { + printf + ("Unsupported code in opcodeType1 case 1!\n"); + exit(1); + } + } + + break; + } + case 2: + { + int mode = getByteFromScript(); + int di = getByteFromScript(); + int var_4 = getShortFromScript(); + + if (!di) { + di = currentScriptPtr->overlayNumber; + } + + if (var == 0x85) // Special case to handle... + { + ASSERT(0); + } + + setObjectPosition(di, var_4, mode, var); + + break; + } + case 4: + { + saveOpcodeVar = var; + break; + } + default: + { + printf("Unsupported type %d in opcodeType1\n", + currentScriptOpcodeType); + exit(1); + } + } + + return (0); +} + +int32 opcodeType2(void) { + int offset = saveOpcodeVar; + int byte1 = getByteFromScript(); + int byte2 = getByteFromScript(); + short int short1 = getShortFromScript(); + + ASSERT(currentScriptOpcodeType == 1 || currentScriptOpcodeType == 5); + + if (currentScriptOpcodeType == 5) + short1 += saveOpcodeVar; + + ASSERT(byte1 & 7); + + if (!(byte1 & 7)) { + return (-10); + } + + if (!byte2) { + int type2; + uint8 *ptr = scriptDataPtrTable[byte1 & 7] + short1; + + type2 = ((byte1 & 0x18) >> 3); + + ASSERT(type2 == 1 || type2 == 2); + + switch (type2) { + case 1: + { + pushPtr(ptr + offset); + return (0); + } + case 2: + { + pushPtr(ptr); + return (0); + } + default: + { + return (-10); + } + } + } else { + printf("Unsupported code in opcodeType2 case 1!\n"); + exit(1); + } + + return 0; +} + +int32 opcodeType10(void) { // break + return (0); +} + +int32 opcodeType11(void) { // break + return (1); +} + +int32 opcodeType4(void) { // test + int boolVar = 0; + + var1 = popVar(); + var2 = popVar(); + + switch (currentScriptOpcodeType) { + case 0: + { + if (var2 != var1) + boolVar = 1; + break; + } + case 1: + { + if (var2 == var1) + boolVar = 1; + break; + } + case 2: + { + if (var2 < var1) + boolVar = 1; + break; + } + case 3: + { + if (var2 <= var1) + boolVar = 1; + break; + } + case 4: + { + if (var2 > var1) + boolVar = 1; + break; + } + case 5: + { + if (var2 >= var1) + boolVar = 1; + break; + } + + } + + pushVar(boolVar); + + return (0); +} + +int32 opcodeType6(void) { + int si = 0; + + int pop = popVar(); + + if (!pop) + si = 1; + + if (pop < 0) { + si |= 4; + } + + if (pop > 0) { + si |= 2; + } + + currentScriptPtr->bitMask = si; + + return (0); +} + +int32 opcodeType7(void) { + var1 = popVar(); + var2 = popVar(); + + pushVar(var1); + pushVar(var2); + + return (0); +} + +int32 opcodeType5(void) { + int offset = currentScriptPtr->var4; + int short1 = getShortFromScript(); + int newSi = short1 + offset; + int bitMask = currentScriptPtr->bitMask; + + switch (currentScriptOpcodeType) { + case 0: + { + if (!(bitMask & 1)) { + currentScriptPtr->var4 = newSi; + } + break; + } + case 1: + { + if (bitMask & 1) { + currentScriptPtr->var4 = newSi; + } + break; + } + case 2: + { + if (bitMask & 2) { + currentScriptPtr->var4 = newSi; + } + break; + } + case 3: + { + if (bitMask & 3) { + currentScriptPtr->var4 = newSi; + } + break; + } + case 4: + { + if (bitMask & 4) { + currentScriptPtr->var4 = newSi; + } + break; + } + case 5: + { + if (bitMask & 5) { + currentScriptPtr->var4 = newSi; + } + break; + } + case 6: + { + break; // never + } + case 7: + { + currentScriptPtr->var4 = newSi; //always + } + } + + return (0); +} + +int32 opcodeType3(void) { // math + int pop1 = popVar(); + int pop2 = popVar(); + + switch (currentScriptOpcodeType) { + case 0: + { + pushVar(pop1 + pop2); + return (0); + } + case 1: + { + pushVar(pop1 / pop2); + return (0); + } + case 2: + { + pushVar(pop1 - pop2); + return (0); + } + case 3: + { + pushVar(pop1 * pop2); + return (0); + } + case 4: + { + pushVar(pop1 % pop2); + return (0); + } + case 7: + case 5: + { + pushVar(pop2 | pop1); + return (0); + } + case 6: + { + pushVar(pop2 & pop1); + return (0); + } + } + + return 0; +} + +int32 opcodeType9(void) { // stop script + //printf("Stop a script of overlay %s\n",overlayTable[currentScriptPtr->overlayNumber].overlayName); + currentScriptPtr->scriptNumber = -1; + return (1); +} + +void setupFuncArray() { + int i; + + for (i = 0; i < 64; i++) { + opcodeTypeTable[i] = NULL; + } + + opcodeTypeTable[1] = opcodeType0; + opcodeTypeTable[2] = opcodeType1; + opcodeTypeTable[3] = opcodeType2; + opcodeTypeTable[4] = opcodeType3; + opcodeTypeTable[5] = opcodeType4; + opcodeTypeTable[6] = opcodeType5; + opcodeTypeTable[7] = opcodeType6; + opcodeTypeTable[8] = opcodeType7; + opcodeTypeTable[9] = opcodeType8; + opcodeTypeTable[10] = opcodeType9; + opcodeTypeTable[11] = opcodeType10; + opcodeTypeTable[12] = opcodeType11; +} + +int removeScript(int overlay, int idx, scriptInstanceStruct *headPtr) { + scriptInstanceStruct *scriptPtr; + + scriptPtr = headPtr->nextScriptPtr; + + if (scriptPtr) { + do { + if (scriptPtr->overlayNumber == overlay + && (scriptPtr->scriptNumber == idx || idx == -1)) { + scriptPtr->scriptNumber = -1; + } + + scriptPtr = scriptPtr->nextScriptPtr; + } + while (scriptPtr); + } + + return (0); +} + +uint8 *attacheNewScriptToTail(int16 overlayNumber, + scriptInstanceStruct *scriptHandlePtr, int16 param, int16 arg0, + int16 arg1, int16 arg2, scriptTypeEnum scriptType) { + int useArg3Neg = 0; + ovlData3Struct *data3Ptr; + scriptInstanceStruct *tempPtr; + int var_C; + scriptInstanceStruct *oldTail; + + //printf("Starting script %d of overlay %s\n",param,overlayTable[overlayNumber].overlayName); + + if (scriptType < 0) { + useArg3Neg = 1; + scriptType = (scriptTypeEnum) - scriptType; + } + + if (scriptType == 20) { + data3Ptr = getOvlData3Entry(overlayNumber, param); + } else { + if (scriptType == 30) { + data3Ptr = scriptFunc1Sub2(overlayNumber, param); + } else { + return (NULL); + } + } + + if (!data3Ptr) { + return (NULL); + } + + if (!data3Ptr->dataPtr) { + return (NULL); + } + + var_C = data3Ptr->sysKey; + + oldTail = scriptHandlePtr; + + while (oldTail->nextScriptPtr) // go to the end of the list + { + oldTail = oldTail->nextScriptPtr; + } + + tempPtr = + (scriptInstanceStruct *) + mallocAndZero(sizeof(scriptInstanceStruct)); + + if (!tempPtr) + return (NULL); + + tempPtr->var6 = NULL; + + if (var_C) { + tempPtr->var6 = (uint8 *) mallocAndZero(var_C); + } + + tempPtr->varA = var_C; + tempPtr->nextScriptPtr = NULL; + tempPtr->var4 = 0; + + tempPtr->scriptNumber = param; + tempPtr->overlayNumber = overlayNumber; + + if (scriptType == 20) // Obj or not ? + { + tempPtr->sysKey = useArg3Neg; + } else { + tempPtr->sysKey = 1; + } + + tempPtr->freeze = 0; + tempPtr->type = scriptType; + tempPtr->var18 = arg2; + tempPtr->var16 = arg1; + tempPtr->var1A = arg0; + tempPtr->nextScriptPtr = oldTail->nextScriptPtr; // should always be NULL as it's the tail + + oldTail->nextScriptPtr = tempPtr; // attache the new node to the list + + return (tempPtr->var6); +} + +int executeScripts(scriptInstanceStruct *ptr) { + int numScript2; + ovlData3Struct *ptr2; + ovlDataStruct *ovlData; + uint8 opcodeType; + + numScript2 = ptr->scriptNumber; + + if (ptr->type == 20) { + ptr2 = getOvlData3Entry(ptr->overlayNumber, numScript2); + + if (!ptr2) { + return (-4); + } + } else { + if (ptr->type == 30) { + ptr2 = scriptFunc1Sub2(ptr->overlayNumber, numScript2); + + if (!ptr2) { + return (-4); + } + } else { + return (-6); + } + } + + if (!overlayTable[ptr->overlayNumber].alreadyLoaded) { + return (-7); + } + + ovlData = overlayTable[ptr->overlayNumber].ovlData; + + if (!ovlData) + return (-4); + + currentData3DataPtr = ptr2->dataPtr; + + scriptDataPtrTable[1] = (uint8 *) ptr->var6; + scriptDataPtrTable[2] = getDataFromData3(ptr2, 1); + scriptDataPtrTable[5] = ovlData->data4Ptr; // free strings + scriptDataPtrTable[6] = ovlData->ptr8; + + currentScriptPtr = ptr; + + positionInStack = 0; + + do { + if (currentScriptPtr->var4 == 290 + && currentScriptPtr->overlayNumber == 4 + && currentScriptPtr->scriptNumber == 0) { + currentScriptPtr->var4 = 923; + } + opcodeType = getByteFromScript(); + + //printf("opType: %d\n",(opcodeType&0xFB)>>3); + + currentScriptOpcodeType = opcodeType & 7; + + if (!opcodeTypeTable[(opcodeType & 0xFB) >> 3]) { + printf("Unsupported opcode type %d\n", + (opcodeType & 0xFB) >> 3); + exit(1); + return (-21); + } + } while (!opcodeTypeTable[(opcodeType & 0xFB) >> 3] ()); + + return (0); +} + +void manageScripts(scriptInstanceStruct *scriptHandle) { + scriptInstanceStruct *ptr = scriptHandle; + + if (ptr) { + do { + if (!overlayTable[ptr->overlayNumber].executeScripts) { + if ((ptr->scriptNumber != -1) && (ptr->freeze == 0) && (ptr->sysKey != 0)) { + executeScripts(ptr); + } + + if (ptr->sysKey == 0) { + ptr->sysKey = 1; + } + } + + ptr = ptr->nextScriptPtr; + + } while (ptr); + } +} + +} // End of namespace Cruise diff --git a/engines/cruise/script.h b/engines/cruise/script.h new file mode 100644 index 0000000000..668fcaae74 --- /dev/null +++ b/engines/cruise/script.h @@ -0,0 +1,69 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_SCRIPT_H +#define CRUISE_SCRIPT_H + +namespace Cruise { + +enum scriptTypeEnum { + scriptType_MinusPROC = -20, + scriptType_Minus30 = -30, + scriptType_PROC = 20, + scriptType_REL = 30 +}; + +struct scriptInstanceStruct { + struct scriptInstanceStruct *nextScriptPtr; + int16 var4; + uint8 *var6; + int16 varA; + int16 scriptNumber; + int16 overlayNumber; + int16 sysKey; + int16 freeze; + scriptTypeEnum type; + int16 var16; + int16 var18; + int16 var1A; +////// EXTRA ! not in original code. Needed for cross platform. + int16 bitMask; +}; + +extern scriptInstanceStruct relHead; +extern scriptInstanceStruct procHead; +extern scriptInstanceStruct *currentScriptPtr; + +void setupFuncArray(void); +uint8 getByteFromScript(void); + +int removeScript(int overlay, int idx, scriptInstanceStruct * headPtr); +uint8 *attacheNewScriptToTail(int16 overlayNumber, + scriptInstanceStruct * scriptHandlePtr, int16 param, int16 arg0, + int16 arg1, int16 arg2, scriptTypeEnum scriptType); +void manageScripts(scriptInstanceStruct * scriptHandle); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/stack.cpp b/engines/cruise/stack.cpp new file mode 100644 index 0000000000..6cce7579ed --- /dev/null +++ b/engines/cruise/stack.cpp @@ -0,0 +1,76 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +// 4 type bigger than the old one, but much safer/cleaner +stackElementStruct scriptStack[SIZE_STACK]; + +// VAR + +void pushVar(int16 var) { + if (positionInStack < SIZE_STACK) { + scriptStack[positionInStack].data.shortVar = var; + scriptStack[positionInStack].type = STACK_SHORT; + positionInStack++; + } +} + +int16 popVar(void) { + if (positionInStack <= 0) { + return (0); + } + + positionInStack--; + + ASSERT(scriptStack[positionInStack].type == STACK_SHORT); + + return (scriptStack[positionInStack].data.shortVar); +} + +//// PTR + +void pushPtr(void *ptr) { + if (positionInStack < SIZE_STACK) { + scriptStack[positionInStack].data.ptrVar = ptr; + scriptStack[positionInStack].type = STACK_PTR; + positionInStack++; + } +} + +void *popPtr() { + if (positionInStack <= 0) { + return (0); + } + + positionInStack--; + + ASSERT(scriptStack[positionInStack].type == STACK_PTR); + + return (scriptStack[positionInStack].data.ptrVar); +} + +} // End of namespace Cruise diff --git a/engines/cruise/stack.h b/engines/cruise/stack.h new file mode 100644 index 0000000000..c7635d6d1a --- /dev/null +++ b/engines/cruise/stack.h @@ -0,0 +1,56 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_STACK_H +#define CRUISE_STACK_H + +namespace Cruise { + +// TODO: Replace this with Common::Stack + +#define SIZE_STACK 0x200 + +enum stackElementTypeEnum { + STACK_SHORT, + STACK_PTR +}; + +struct stackElementStruct { + stackElementTypeEnum type; + + union { + void *ptrVar; + int16 shortVar; + } data; +}; + +int16 popVar(void); +void pushVar(int16 var); + +void pushPtr(void *ptr); +void *popPtr(void); + +} // End of namespace Cruise + +#endif diff --git a/backends/platform/PalmOS/Src/missing/ext_string.c b/engines/cruise/stringSupport.cpp index 319017f790..1343ba146d 100644 --- a/backends/platform/PalmOS/Src/missing/ext_string.c +++ b/engines/cruise/stringSupport.cpp @@ -1,7 +1,7 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project - * Copyright (C) 2002-2006 Chris Apers - PalmOS Backend + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,24 +22,20 @@ * */ -#include <string.h> +#include "cruise/cruise_main.h" -#ifdef PALMOS_68K -void *memchr(const void *s, int c, UInt32 n) { - UInt32 chr; - for(chr = 0; chr < n;chr++,((UInt8 *)s)++) - if ( *((UInt8 *)s) == c) - return (void *)s; +namespace Cruise { - return NULL; +void strcpyuint8(void *dest, const void *source) { + strcpy((char *)dest, (const char *)source); } -Char *strdup(const Char *s1) { - Char* buf = (Char *)MemPtrNew(StrLen(s1)+1); - - if(buf) - StrCopy(buf, s1); +void strcatuint8(void *dest, const void *source) { + strcat((char *)dest, (const char *)source); +} - return buf; +uint8 strcmpuint8(const void *string1, const void *string2) { + return strcmp((char *)string1, (char *)string2); } -#endif + +} // End of namespace Cruise diff --git a/engines/cruise/stringSupport.h b/engines/cruise/stringSupport.h new file mode 100644 index 0000000000..bd4c66fff1 --- /dev/null +++ b/engines/cruise/stringSupport.h @@ -0,0 +1,38 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_STRING_SUPPORT_H +#define CRSUIE_STRING_SUPPORT_H + +namespace Cruise { + +// TODO: Get rid of these and this file (either use strcpy directly, or switch to Common::String) + +void strcpyuint8(void *dest, const void *source); +void strcatuint8(void *dest, const void *source); +uint8 strcmpuint8(const void *string1, const void *string2); + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/various.cpp b/engines/cruise/various.cpp new file mode 100644 index 0000000000..2b3aa6855f --- /dev/null +++ b/engines/cruise/various.cpp @@ -0,0 +1,55 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +uint16 var0 = 0; +uint16 fadeVar; +uint16 main15; + +int16 readB16(void *ptr) { + int16 temp; + + temp = *(int16 *) ptr; + flipShort(&temp); + + return temp; +} + +char *getText(int textIndex, int overlayIndex) { + if (!overlayTable[overlayIndex].ovlData) { + return NULL; + } + + if (!overlayTable[overlayIndex].ovlData->stringTable) { + return NULL; + } + + return overlayTable[overlayIndex].ovlData->stringTable[textIndex]. + string; +} + +} // End of namespace Cruise diff --git a/engines/cruise/various.h b/engines/cruise/various.h new file mode 100644 index 0000000000..6b1e589b54 --- /dev/null +++ b/engines/cruise/various.h @@ -0,0 +1,42 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_VARIOUS_H +#define CRUISE_VARIOUS_H + +#include "cruise/cell.h" + +namespace Cruise { + +extern uint16 var0; +extern uint16 fadeVar; +extern uint16 main15; + +int16 readB16(void *ptr); + +int16 objInit(int ovlIdx, int param1, int param2); +char *getText(int textIndex, int overlayIndex); +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/vars.cpp b/engines/cruise/vars.cpp new file mode 100644 index 0000000000..c6cb068306 --- /dev/null +++ b/engines/cruise/vars.cpp @@ -0,0 +1,182 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +uint8 *_systemFNT; + +uint8 video2 = 1; +uint8 video3 = 3; +uint8 video4 = 2; +uint8 colorOfSelectedSaveDrive = 5; + +int16 initVar1; +int16 initVar2; +int16 initVar3; +uint8 initVar4[90]; + +int16 currentActiveBackgroundPlane; +int16 main5; +int16 var22 = 0; + +filesDataStruct filesData[90]; +filesData2Struct filesData2[90]; + +mediumVarStruct mediumVar[64]; + +volumeDataStruct volumeData[20]; + +int32 volumeDataLoaded = 0; + +int16 numOfDisks; + +uint8 scriptNameBuffer[15]; +int16 currentActiveMenu; +int16 main14; +int16 mouseVar1; +int16 main21; +int16 main22; +int16 main7; +int16 main8; + +int16 currentDiskNumber = 1; + +#ifdef PALMOS_MODE +Common::File *_currentVolumeFile; +#else +Common::File currentVolumeFile; +#endif + +int16 currentCursor; + +int16 volumeNumEntry; +fileEntry *volumePtrToFileDescriptor = NULL; + +uint32 volumeFileDescriptorSize; +int16 volumeSizeOfEntry; +int16 volumeNumberOfEntry; + +int16 affichePasMenuJoueur = 1; + +int16 globalVars[2000]; + +dataFileEntry filesDatabase[257]; + +int16 bootOverlayNumber; + +int16 initVar5[12]; + +opcodeTypeFunction opcodeTypeTable[64]; + +int16 positionInStack; + +actorStruct actorHead; + +int16 setup1; + +uint8 *currentData3DataPtr; +uint8 *scriptDataPtrTable[7]; + +int16 currentScriptOpcodeType; + +int16 saveOpcodeVar; + +int16 var30 = 0; +int16 var31 = 0; + +int16 var1; +int16 var2; +int16 var3; +int16 var4; +int16 userEnabled; +int16 var5; +int16 var6; +int16 var7; +int16 var8; +int16 userDelay; +int16 sysKey = -1; +int16 var11 = 0; +int16 var12; +int16 var13; +int16 var14; +int16 var20; +int16 var23; +int16 var24; +int16 automaticMode; +int16 var34; +int16 var35; +bool animationStart; + +int16 main17; +int16 var39; +int16 entrerMenuJoueur; +int16 var41; +int16 var42; +int16 var45; +int16 var46; +int16 var47; +int16 var48; +int16 flagCt; + +int8 var50[64]; +int16 palette[256 * 3]; + +systemStringsStruct systemStrings; + +uint8 currentCtpName[40]; + +int16 saveVar1; +uint8 saveVar2[97]; // recheck size + +int16 numberOfWalkboxes; // saveVar3 +int16 walkboxType[15]; // saveVar4 +int16 walkboxChange[15]; // saveVar5 + +uint8 saveVar6[16]; + +int32 loadFileVar1; + +int16 ctpVar1 = 0; +int16 ctp_routeCoordCount; // ctpVar2 +int16 ctp_routeCoords[20][2]; // ctpVar3 +int16 ctp_routes[20][10]; +uint16 ctp_walkboxTable[15 * 40]; // ctpVar5 +int8 ctpVar6[32]; +int16 ctp_scale[15]; // ctpVar7 +int16 ctpVar8[200]; + +int16 ctpVar14; + +int16 bgVar1; +int16 bgVar2; +int16 bgVar3; + +uint8 globalScreen[320 * 200]; +uint8 scaledScreen[640 * 400]; + +//OSystem *osystem; + +} // End of namespace Cruise diff --git a/engines/cruise/vars.h b/engines/cruise/vars.h new file mode 100644 index 0000000000..71368218ad --- /dev/null +++ b/engines/cruise/vars.h @@ -0,0 +1,304 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_VARS_H +#define CRUISE_VARS_H + +#include "common/file.h" + +namespace Cruise { + +struct menuElementSubStruct { + struct menuElementSubStruct *pNext; + int16 var2; + int16 var4; +}; + +struct menuElementStruct { + struct menuElementStruct *next; + const char *string; + int x; + int y; + int varA; + int varC; + unsigned char color; + gfxEntryStruct *gfx; + menuElementSubStruct *ptrSub; +}; + +typedef int32(*opcodeTypeFunction) (void); +typedef int16(*opcodeFunction) (void); + +extern uint8 *_systemFNT; +extern int16 fontFileIndex; + +extern uint8 video2; +extern uint8 video3; +extern uint8 video4; +extern uint8 colorOfSelectedSaveDrive; + +extern int16 initVar1; +extern int16 initVar2; +extern int16 initVar3; +extern uint8 initVar4[90]; + +extern int16 currentActiveBackgroundPlane; +extern int16 main5; +extern int16 var22; + +struct mediumVarStruct { + uint8 name[16]; + int16 field_10; + int16 field_12; + int16 field_14; + int16 field_16; + uint8 *ptr; + int16 field_1C; + int16 field_1E; + int16 field_20; +}; + +struct filesDataStruct { + uint8 *field_0; + uint8 *field_4; +}; + +struct filesData2Struct { + int16 field_0; + int16 field_2; +}; + +struct fileName { + uint8 name[13]; +}; + +struct setHeaderEntry { + int16 field_0; // offset ptr part 1 + int16 field_2; // offset ptr part 2 + int16 width; + int16 height; + int16 type; // resource type, ie. sprites 0,1,4,5 and 8 + int16 transparency; + int16 field_C; + int16 field_E; +}; + +struct volumeDataStruct { + char ident[10]; + fileName *ptr; + int16 diskNumber; + int32 size; +}; + +struct fileEntry { + uint8 name[14]; + int32 offset; + int32 size; + int32 extSize; + int32 unk3; // unused +}; + +struct dataFileEntrySub { + uint8 *ptr; + int16 index; // sprite index + char name[14]; + int16 transparency; // sprite transparency + uint8 *ptr2; + uint8 resourceType; // sprite and image type 2,4,8 , fnt = 7, spl = 6 + uint8 field_1B; + int16 field_1C; +}; + +struct dataFileEntry { + int16 widthInColumn; + int16 width; + int16 resType; + int16 height; + dataFileEntrySub subData; +}; + +struct systemStringsStruct { + int8 param; + uint8 string[12]; + uint8 bootScriptName[8]; +}; + +extern filesDataStruct filesData[90]; +extern filesData2Struct filesData2[90]; + +extern mediumVarStruct mediumVar[64]; + +extern volumeDataStruct volumeData[20]; + +extern int32 volumeDataLoaded; + +extern int16 numOfDisks; + +extern uint8 scriptNameBuffer[15]; +extern int16 currentActiveMenu; +extern int16 main14; +extern int16 mouseVar1; +extern int16 main21; +extern int16 main22; +extern int16 main7; +extern int16 main8; + +extern int16 currentDiskNumber; + +#ifdef PALMOS_MODE +extern Common::File *_currentVolumeFile; +#define currentVolumeFile (*_currentVolumeFile) +#else +extern Common::File currentVolumeFile; +#endif + +extern int16 currentCursor; + +extern int16 volumeNumEntry; +extern fileEntry *volumePtrToFileDescriptor; + +extern uint32 volumeFileDescriptorSize; +extern int16 volumeSizeOfEntry; +extern int16 volumeNumberOfEntry; + +extern int16 affichePasMenuJoueur; + +extern int16 globalVars[2000]; +extern dataFileEntry filesDatabase[257]; + +extern int16 bootOverlayNumber; + +extern int16 initVar5[12]; + +extern opcodeTypeFunction opcodeTypeTable[64]; + +extern int16 positionInStack; +extern actorStruct actorHead; + +extern int16 setup1; + +extern uint8 *currentData3DataPtr; +extern uint8 *scriptDataPtrTable[7]; + +extern int16 currentScriptOpcodeType; + +extern int16 saveOpcodeVar; + +extern int16 var30; +extern int16 var31; + +extern int16 var1; +extern int16 var2; +extern int16 var3; +extern int16 var4; +extern int16 userEnabled; +extern int16 var5; +extern int16 var6; +extern int16 var7; +extern int16 var8; +extern int16 userDelay; +extern int16 sysKey; +extern int16 var11; +extern int16 var12; +extern int16 var13; +extern int16 var14; +extern int16 var20; +extern int16 var23; +extern int16 var24; +extern int16 automaticMode; +extern int16 var34; +extern int16 var35; +extern bool animationStart; + +extern int16 main17; +extern int16 var39; +extern int16 entrerMenuJoueur; +extern int16 var39; +extern int16 var41; +extern int16 var42; +extern int16 var45; +extern int16 var46; +extern int16 var47; +extern int16 var48; +extern int16 flagCt; + +extern int8 var50[64]; +extern int16 palette[256 * 3]; + +extern systemStringsStruct systemStrings; + +extern uint8 currentCtpName[40]; + +extern int16 saveVar1; +extern uint8 saveVar2[97]; // recheck size + +extern int16 numberOfWalkboxes; // saveVar3 +extern int16 walkboxType[15]; // saveVar4 // Type: 0x00 - non walkable, 0x01 - walkable, 0x02 - exit zone +extern int16 walkboxChange[15]; // saveVar5 // walkbox can change its type: 0x00 - not changeable, 0x01 - changeable + // Assumption: To change the type: walkboxType[i] -= walkboxChane[i] and vice versa +extern uint8 saveVar6[16]; + +extern int32 loadFileVar1; + +extern int16 ctpVar1; +extern int16 ctp_routeCoordCount; // ctpVar2 // number of path-finding coordinates +extern int16 ctp_routeCoords[20][2]; // ctpVar3 // path-finding coordinates array + +/* ctp_routeCoords: + + correct size would be: ctp_routes[routeCoordCount * 4] + coordinate information with x (2 bytes) and y (2 bytes) +*/ + +extern int16 ctp_routes[20][10]; // path-finding line information + +/* ctp_routes: + + correct size would be: ctp_routes[routeCoordCount * 20 * 2] + array is seperate in 20 * 2 bytes slices. + first 2 bytes of the slice indicate how many coordinates/lines are following (lineCount) + after that there are lineCount * 2 bytes following with indexes pointing on the routeCoords table + the root x,y for the lines is the coordinate in the routeCoords array, which fits to the current slice + for the 20 * i slice the root x,y is routeCoords[i], routeCoords[i+2] + the unused rest of the slice if filled up with 0xFF +*/ +extern uint16 ctp_walkboxTable[15 * 40]; // ctpVar5 // walkboxes coordinates and lines +extern int8 ctpVar6[32]; +extern int16 ctp_scale[15]; // ctpVar7 // scaling information for walkboxes +extern int16 ctpVar8[200]; + +extern int16 ctpVar14; + +extern int16 bgVar1; +extern int16 bgVar2; +extern int16 bgVar3; + +extern uint8 globalScreen[320 * 200]; +extern uint8 scaledScreen[640 * 400]; + +//extern OSystem *osystem; + +} // End of namespace Cruise + +#endif diff --git a/engines/cruise/volume.cpp b/engines/cruise/volume.cpp new file mode 100644 index 0000000000..e4a00945e9 --- /dev/null +++ b/engines/cruise/volume.cpp @@ -0,0 +1,455 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "cruise/cruise_main.h" + +namespace Cruise { + +FILE *PAL_fileHandle = NULL; +uint8 *PAL_ptr = NULL; + +int16 numLoadedPal; +int16 fileData2; + +void loadPal(volumeDataStruct *entry) { + char name[20]; + + return; + + if (PAL_fileHandle) { + fclose(PAL_fileHandle); + } + + removeExtention(entry->ident, name); + strcat(name, ".PAL"); + + PAL_fileHandle = fopen(name, "rb"); + + fread(&numLoadedPal, 2, 1, PAL_fileHandle); + fread(&fileData2, 2, 1, PAL_fileHandle); + + flipShort(&numLoadedPal); + flipShort(&fileData2); + + PAL_ptr = (uint8 *) malloc(numLoadedPal * fileData2); +} + +int getVolumeDataEntry(volumeDataStruct *entry) { + char buffer[256]; + int i; + + volumeNumEntry = 0; + volumeNumberOfEntry = 0; + + if (currentVolumeFile.isOpen()) { + freeDisk(); + } + + askDisk(-1); + + strcpyuint8(buffer, entry->ident); + + currentVolumeFile.open(buffer); + + if (!currentVolumeFile.isOpen()) { + return (-14); + } + + changeCursor(1); + + currentVolumeFile.read(&volumeNumberOfEntry, 2); + currentVolumeFile.read(&volumeSizeOfEntry, 2); + + flipShort(&volumeNumberOfEntry); + flipShort(&volumeSizeOfEntry); + + volumeNumEntry = volumeNumberOfEntry; + + assert(volumeSizeOfEntry == 14 + 4 + 4 + 4 + 4); + + volumePtrToFileDescriptor = + (fileEntry *) mallocAndZero(sizeof(fileEntry) * volumeNumEntry); + + for (i = 0; i < volumeNumEntry; i++) { + volumePtrToFileDescriptor[i].name[0] = 0; + volumePtrToFileDescriptor[i].offset = 0; + volumePtrToFileDescriptor[i].size = 0; + volumePtrToFileDescriptor[i].extSize = 0; + volumePtrToFileDescriptor[i].unk3 = 0; + } + + for (i = 0; i < volumeNumEntry; i++) { + currentVolumeFile.read(&volumePtrToFileDescriptor[i].name, 14); + currentVolumeFile.read(&volumePtrToFileDescriptor[i].offset, + 4); + currentVolumeFile.read(&volumePtrToFileDescriptor[i].size, 4); + currentVolumeFile.read(&volumePtrToFileDescriptor[i].extSize, + 4); + currentVolumeFile.read(&volumePtrToFileDescriptor[i].unk3, 4); + } + + for (i = 0; i < volumeNumEntry; i++) { + flipLong(&volumePtrToFileDescriptor[i].offset); + flipLong(&volumePtrToFileDescriptor[i].size); + flipLong(&volumePtrToFileDescriptor[i].extSize); + } + + loadPal(entry); + + return 0; +} + +int searchFileInVolCnf(uint8 *fileName, int32 diskNumber) { + int foundDisk = -1; + int i; + + for (i = 0; i < numOfDisks; i++) { + if (volumeData[i].diskNumber == diskNumber) { + int j; + int numOfEntry = volumeData[i].size / 13; + + for (j = 0; j < numOfEntry; j++) { + if (!strcmpuint8(volumeData[i].ptr[j].name, + fileName)) { + return (i); + } + } + } + } + + return (foundDisk); +} + +int32 findFileInDisksSub1(uint8 *fileName) { + int foundDisk = -1; + int i; + + for (i = 0; i < numOfDisks; i++) { + int j; + int numOfEntry = volumeData[i].size / 13; + + for (j = 0; j < numOfEntry; j++) { + if (!strcmpuint8(volumeData[i].ptr[j].name, fileName)) { + return (i); + } + } + } + + return (foundDisk); +} + +void strToUpper(uint8 *fileName) { + char character; + + do { + character = *fileName; + + if (character >= 'a' && character <= 'z') { + character &= 0xDF; + *fileName = character; + } + + fileName++; + + } while (character); +} + +void freeDisk(void) { + if (currentVolumeFile.isOpen()) { + currentVolumeFile.close(); + free(volumePtrToFileDescriptor); + } + + /* TODO + * if(PAL_fileHandle) + * { + * freeAllDataPtr(); + * } + */ +} + +int16 findFileInList(uint8 *fileName) { + int i; + + if (!currentVolumeFile.isOpen()) { + return (-1); + } + + strToUpper(fileName); + + if (volumeNumEntry <= 0) { + return (-1); + } + + for (i = 0; i < volumeNumEntry; i++) { + if (!strcmpuint8(volumePtrToFileDescriptor[i].name, fileName)) { + return (i); + } + } + + return (-1); +} + +void askDisk(int16 discNumber) { + char diskNumberString[256]; + uint8 fileName[256]; + uint8 string[256]; + char messageDrawn = 0; + + if (discNumber != -1) { + currentDiskNumber = discNumber; + } + // skip drive selection stuff + + strcpyuint8(fileName, "VOL."); + sprintf(diskNumberString, "%d", currentDiskNumber); + strcatuint8(fileName, diskNumberString); + + strcpyuint8(string, "INSERER LE DISQUE "); + strcatuint8(string, diskNumberString); + strcatuint8(string, " EN "); + + //while (Common::File::exists((const char*)fileName)) + { + if (!messageDrawn) { + drawMsgString(string); + messageDrawn = 1; + } + } + + changeCursor(currentCursor); +} + +int16 findFileInDisks(uint8 *fileName) { + int disk; + int fileIdx; + + strToUpper(fileName); + + if (!volumeDataLoaded) { + printf("CNF wasn't loaded, reading now...\n"); + if (currentVolumeFile.isOpen()) { + askDisk(-1); + freeDisk(); + } + + askDisk(1); + readVolCnf(); + } + + if (currentVolumeFile.isOpen()) { + askDisk(-1); + } + + fileIdx = findFileInList(fileName); + + if (fileIdx >= 0) { + return (fileIdx); + } + + disk = searchFileInVolCnf(fileName, currentDiskNumber); + + if (disk >= 0) { + int temp; + + printf("File found on disk %d\n", disk); + + if (currentVolumeFile.isOpen()) { + askDisk(-1); + } + + freeDisk(); + + askDisk(volumeData[disk].diskNumber); + + getVolumeDataEntry(&volumeData[disk]); + + temp = findFileInList(fileName); + + if (temp >= 0) + return (temp); + + return (-1); + + } else { + int temp; + + temp = findFileInDisksSub1(fileName); + + if (temp >= 0) { + int temp2; + + askDisk(volumeData[temp].diskNumber); + + getVolumeDataEntry(&volumeData[temp]); + + temp2 = findFileInList(fileName); + + if (temp2 >= 0) + return (temp2); + } + + return (-1); + } +} + +int16 readVolCnf(void) { + int i; + Common::File fileHandle; + short int sizeHEntry; + + volumeDataLoaded = 0; + + for (i = 0; i < 20; i++) { + volumeData[i].ident[0] = 0; + volumeData[i].ptr = NULL; + volumeData[i].diskNumber = i + 1; + volumeData[i].size = 0; + } + + fileHandle.open("VOL.CNF"); + + if (!fileHandle.isOpen()) { + return (0); + } + + fileHandle.read(&numOfDisks, 2); + flipShort(&numOfDisks); + + fileHandle.read(&sizeHEntry, 2); + flipShort(&sizeHEntry); // size of one header entry - 20 bytes + + for (i = 0; i < numOfDisks; i++) { + // fread(&volumeData[i],20,1,fileHandle); + fileHandle.read(&volumeData[i].ident, 10); + fileHandle.read(&volumeData[i].ptr, 4); + fileHandle.read(&volumeData[i].diskNumber, 2); + fileHandle.read(&volumeData[i].size, 4); + + flipShort(&volumeData[i].diskNumber); + printf("Disk number: %d\n", volumeData[i].diskNumber); + flipLong(&volumeData[i].size); + } + + for (i = 0; i < numOfDisks; i++) { + fileName *ptr; + + fileHandle.read(&volumeData[i].size, 4); + flipLong(&volumeData[i].size); + + ptr = (fileName *) mallocAndZero(volumeData[i].size); + + volumeData[i].ptr = ptr; + + if (!ptr) { + fileHandle.close(); + return (-2); + } + + fileHandle.read(ptr, volumeData[i].size); + } + + fileHandle.close(); + + volumeDataLoaded = 1; + +//#define dumpResources +#ifdef dumpResources + + for (i = 0; i < numOfDisks; i++) { + int j; + char nameBuffer[256]; + fileEntry *buffer; + + sprintf(nameBuffer, "D%d.", i + 1); + + fileHandle = fopen(nameBuffer, "rb"); + + short int numEntry; + short int sizeEntry; + + fread(&numEntry, 2, 1, fileHandle); + fread(&sizeEntry, 2, 1, fileHandle); + + flipShort(&numEntry); + flipShort(&sizeEntry); + + buffer = (fileEntry *) mallocAndZero(numEntry * sizeEntry); + + fread(buffer, numEntry * sizeEntry, 1, fileHandle); + + for (j = 0; j < numEntry; j++) { + flipLong(&buffer[j].offset); + flipLong(&buffer[j].size); + flipLong(&buffer[j].unk2); + flipLong(&buffer[j].unk3); + + fseek(fileHandle, buffer[j].offset, SEEK_SET); + + char *bufferLocal; + bufferLocal = (char *)mallocAndZero(buffer[j].size); + + fread(bufferLocal, buffer[j].size, 1, fileHandle); + + char nameBuffer[256]; + + sprintf(nameBuffer, "D%d.dmp/%s", i + 1, + buffer[j].name); + + if (buffer[j].size == buffer[j].unk2) { + FILE *fOut = fopen(nameBuffer, "wb+"); + fwrite(bufferLocal, buffer[j].size, 1, fOut); + fclose(fOut); + } else { + char *uncompBuffer = + (char *)mallocAndZero(buffer[j].unk2 + + 500); + + delphineUnpack((uint8 *) uncompBuffer, (const uint8 *) bufferLocal, buffer[j].size); + + FILE *fOut = fopen(nameBuffer, "wb+"); + fwrite(uncompBuffer, buffer[j].unk2, 1, + fOut); + fclose(fOut); + + //free(uncompBuffer); + + } + + free(bufferLocal); + } + } + +#endif + + return (1); +} + +///////////////////////////:: + +void drawMsgString(uint8 *string) { + //printf("%s\n",string); +} + +} // End of namespace Cruise diff --git a/engines/cruise/volume.h b/engines/cruise/volume.h new file mode 100644 index 0000000000..1399bc46ab --- /dev/null +++ b/engines/cruise/volume.h @@ -0,0 +1,44 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * cinE Engine is (C) 2004-2005 by CinE Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef CRUISE_VOLUME_H +#define CRUISE_VOLUME_H + +namespace Cruise { + +int16 readVolCnf(void); +int16 findFileInDisks(uint8 * fileName); +void freeDisk(void); +int16 findFileInList(uint8 * fileName); + +//////////////// + +void strToUpper(uint8 * fileName); +void drawMsgString(uint8 * string); +void askDisk(int16 discNumber); +void setObjectPosition(int16 param1, int16 param2, int16 param3, int16 param4); + +} // End of namespace Cruise + +#endif diff --git a/engines/engines.mk b/engines/engines.mk index c291a335c8..b141d66585 100644 --- a/engines/engines.mk +++ b/engines/engines.mk @@ -90,3 +90,9 @@ DEFINES += -DDISABLE_PARALLACTION else MODULES += engines/parallaction endif + +ifdef DISABLE_CRUISE +DEFINES += -DDISABLE_CRUISE +else +MODULES += engines/cruise +endif diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index 3d4610d961..63c25b4659 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -27,6 +27,7 @@ #include "gob/gob.h" #include "gob/dataio.h" #include "gob/global.h" +#include "gob/util.h" namespace Gob { @@ -305,6 +306,13 @@ void DataIO::openDataFile(const char *src, bool itk) { dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE(); dataDesc[i].offset = file_getHandle(_dataFileHandles[file])->readUint32LE(); dataDesc[i].packed = file_getHandle(_dataFileHandles[file])->readByte(); + + // Replacing cyrillic characters + Util::replaceChar(dataDesc[i].chunkName, (char) 0x85, 'E'); + Util::replaceChar(dataDesc[i].chunkName, (char) 0x8A, 'K'); + Util::replaceChar(dataDesc[i].chunkName, (char) 0x8E, 'O'); + Util::replaceChar(dataDesc[i].chunkName, (char) 0x91, 'C'); + Util::replaceChar(dataDesc[i].chunkName, (char) 0x92, 'T'); } for (int i = 0; i < _numDataChunks[file]; i++) diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 6afd79d06f..246ffa3b44 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -414,6 +414,18 @@ static const GOBGameDescription gameDescriptions[] = { GF_GOB2, "intro" }, + { // Supplied by bgk in bug report #1706861 + { + "gob2", + "", + AD_ENTRY1s("intro.stk", "4b13c02d1069b86bcfec80f4e474b98b", 554680), + FR_FRA, + kPlatformAtariST, + Common::ADGF_NO_FLAGS + }, + GF_GOB2, + "intro" + }, { { "gob2cd", @@ -642,6 +654,18 @@ static const GOBGameDescription gameDescriptions[] = { GF_GOB2, "intro" }, + { // Supplied by glorfindel in bugreport #1722142 + { + "ween", + "", + AD_ENTRY1s("intro.stk", "8b57cd510da8a3bbd99e3a0297a8ebd1", 7018771), + IT_ITA, + kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GF_GOB2, + "intro" + }, { { "ween", @@ -714,6 +738,18 @@ static const GOBGameDescription gameDescriptions[] = { GF_BARGON, "intro" }, + { // Supplied by glorfindel in bugreport #1722142 + { + "bargon", + "Fanmade", + AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), + IT_ITA, + kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GF_BARGON, + "intro" + }, { { "gob3", @@ -762,6 +798,18 @@ static const GOBGameDescription gameDescriptions[] = { GF_GOB3, "intro" }, + { // Supplied by Paranoimia on #scummvm + { + "gob3", + "", + AD_ENTRY1s("intro.stk", "fe8144daece35538085adb59c2d29613", 159402), + IT_ITA, + kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GF_GOB3, + "intro" + }, { { "gob3", @@ -791,7 +839,19 @@ static const GOBGameDescription gameDescriptions[] = { "gob3", "", AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), - UNK_LANG, + EN_GRB, + kPlatformAmiga, + Common::ADGF_NO_FLAGS + }, + GF_GOB3, + "menu" + }, + { + { + "gob3", + "", + AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), + DE_DEU, kPlatformAmiga, Common::ADGF_NO_FLAGS }, @@ -807,7 +867,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB3, + GF_GOB3 | GF_CD, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -819,7 +879,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB3, + GF_GOB3 | GF_CD, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -831,7 +891,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB3, + GF_GOB3 | GF_CD, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -843,7 +903,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB3, + GF_GOB3 | GF_CD, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -855,7 +915,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB3, + GF_GOB3 | GF_CD, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -867,7 +927,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB3, + GF_GOB3 | GF_CD, "intro" }, { diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 8e973a8ee5..62a4984267 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -139,6 +139,9 @@ public: _spritesArray[index] = 0; } void adjustCoords(char adjust, int16 *coord1, int16 *coord2); + void adjustCoords(char adjust, uint16 *coord1, uint16 *coord2) { + adjustCoords(adjust, (int16 *) coord1, (int16 *) coord2); + } void drawString(char *str, int16 x, int16 y, int16 color1, int16 color2, int16 transp, SurfaceDesc *dest, Video::FontDesc *font); void printTextCentered(int16 id, int16 left, int16 top, int16 right, @@ -154,7 +157,7 @@ public: virtual void spriteOperation(int16 operation) = 0; Draw(GobEngine *vm); - virtual ~Draw() {}; + virtual ~Draw() {} protected: GobEngine *_vm; @@ -170,7 +173,7 @@ public: virtual void spriteOperation(int16 operation); Draw_v1(GobEngine *vm); - virtual ~Draw_v1() {}; + virtual ~Draw_v1() {} }; class Draw_v2 : public Draw_v1 { @@ -183,7 +186,7 @@ public: virtual void spriteOperation(int16 operation); Draw_v2(GobEngine *vm); - virtual ~Draw_v2() {}; + virtual ~Draw_v2() {} }; class Draw_Bargon: public Draw_v2 { @@ -191,7 +194,7 @@ public: virtual void initScreen(); Draw_Bargon(GobEngine *vm); - virtual ~Draw_Bargon() {}; + virtual ~Draw_Bargon() {} }; // Draw operations diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 58e0a3c2d3..bba9c790d6 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -63,7 +63,7 @@ void Draw_v1::animateCursor(int16 cursor) { if (cursorIndex == -1) { cursorIndex = 0; - for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { + for (ptr = _vm->_game->_collisionAreas; ptr->left != 0xFFFF; ptr++) { if (ptr->flags & 0xFFF0) continue; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 6b7b1db0fd..67b8eb3c13 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -82,7 +82,7 @@ void Draw_v2::animateCursor(int16 cursor) { // .-- _draw_animateCursorSUB1 --- if (cursorIndex == -1) { cursorIndex = 0; - for (ptr = _vm->_game->_collisionAreas; ptr->left != -1; ptr++) { + for (ptr = _vm->_game->_collisionAreas; ptr->left != 0xFFFF; ptr++) { if ((ptr->flags & 0xF00) || (ptr->id & 0x4000)) continue; @@ -558,7 +558,7 @@ void Draw_v2::spriteOperation(int16 operation) { // Some handle, but always assigned to -1 in Game::loadTotFile() int16 word_2F2D2 = -1; - deltaVeto = (bool) (operation & 0x10); + deltaVeto = (operation & 0x10) != 0; operation &= 0x0F; if (_sourceSurface >= 100) diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index f146cded6d..43eac76928 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -77,6 +77,8 @@ Game::Game(GobEngine *vm) : _vm(vm) { _handleMouse = 0; _forceHandleMouse = 0; _menuLevel = 0; + _noScroll = true; + _scrollHandleMouse = false; _tempStr[0] = 0; _curImaFile[0] = 0; @@ -133,7 +135,7 @@ byte *Game::loadExtData(int16 itemId, int16 *pResWidth, offset = item->offset; size = item->size; - isPacked = (bool) (item->width & 0x8000); + isPacked = (item->width & 0x8000) != 0; if (pResWidth != 0) { *pResWidth = item->width & 0x7FFF; @@ -196,7 +198,7 @@ byte *Game::loadExtData(int16 itemId, int16 *pResWidth, void Game::freeCollision(int16 id) { for (int i = 0; i < 250; i++) { if (_collisionAreas[i].id == id) - _collisionAreas[i].left = -1; + _collisionAreas[i].left = 0xFFFF; } } @@ -289,10 +291,10 @@ void Game::freeSoundSlot(int16 slot) { } void Game::evaluateScroll(int16 x, int16 y) { - if ((_handleMouse == 0) || (_menuLevel > 0)) + if (!_scrollHandleMouse || (_menuLevel > 0)) return; - if (_vm->_global->_videoMode != 0x14) + if (_noScroll || (_vm->_global->_videoMode != 0x14)) return; if ((x == 0) && (_vm->_draw->_scrollOffsetX > 0)) { @@ -301,10 +303,18 @@ void Game::evaluateScroll(int16 x, int16 y) { off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX); off = MAX(off / 2, 1); _vm->_draw->_scrollOffsetX -= off; + } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) { + uint16 off; + + off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY); + off = MAX(off / 2, 1); + _vm->_draw->_scrollOffsetY -= off; } int16 cursorRight = x + _vm->_draw->_cursorWidth; int16 screenRight = _vm->_draw->_scrollOffsetX + 320; + int16 cursorBottom = y + _vm->_draw->_cursorHeight; + int16 screenBottom = _vm->_draw->_scrollOffsetY + 200; if ((cursorRight >= 320) && (screenRight < _vm->_video->_surfWidth)) { uint16 off; @@ -316,6 +326,18 @@ void Game::evaluateScroll(int16 x, int16 y) { _vm->_draw->_scrollOffsetX += off; _vm->_util->setMousePos(320 - _vm->_draw->_cursorWidth, y); + } else if ((cursorBottom >= (200 - _vm->_video->_splitHeight2)) && + (screenBottom < _vm->_video->_surfHeight)) { + uint16 off; + + off = MIN(_vm->_draw->_cursorHeight, + (int16) (_vm->_video->_surfHeight - screenBottom)); + off = MAX(off / 2, 1); + + _vm->_draw->_scrollOffsetY += off; + + _vm->_util->setMousePos(x, 200 - _vm->_video->_splitHeight2 - + _vm->_draw->_cursorHeight); } _vm->_util->setScrollOffset(); @@ -653,13 +675,13 @@ byte *Game::loadLocTexts(void) { void Game::setCollisions(void) { byte *savedIP; - int16 left; - int16 top; - int16 width; - int16 height; + uint16 left; + uint16 top; + uint16 width; + uint16 height; Collision *collArea; - for (collArea = _collisionAreas; collArea->left != -1; collArea++) { + for (collArea = _collisionAreas; collArea->left != 0xFFFF; collArea++) { if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0)) continue; @@ -669,7 +691,8 @@ void Game::setCollisions(void) { top = _vm->_parse->parseValExpr(); width = _vm->_parse->parseValExpr(); height = _vm->_parse->parseValExpr(); - if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) { + if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && + (left != 0xFFFF)) { left += _vm->_draw->_backDeltaX; top += _vm->_draw->_backDeltaY; } diff --git a/engines/gob/game.h b/engines/gob/game.h index f509e0d6a0..66fa0179fd 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -37,10 +37,10 @@ public: struct Collision { int16 id; - int16 left; - int16 top; - int16 right; - int16 bottom; + uint16 left; + uint16 top; + uint16 right; + uint16 bottom; int16 flags; int16 key; uint16 funcEnter; @@ -128,6 +128,9 @@ public: int32 _startTimeKey; int16 _mouseButtons; + bool _noScroll; + bool _scrollHandleMouse; + Game(GobEngine *vm); virtual ~Game(); @@ -149,9 +152,9 @@ public: virtual void playTot(int16 skipPlay) = 0; virtual void clearCollisions(void) = 0; - virtual int16 addNewCollision(int16 id, int16 left, int16 top, int16 right, - int16 bottom, int16 flags, int16 key, uint16 funcEnter, - uint16 funcLeave) = 0; + virtual int16 addNewCollision(int16 id, uint16 left, uint16 top, + uint16 right, uint16 bottom, int16 flags, int16 key, + uint16 funcEnter, uint16 funcLeave) = 0; virtual void collisionsBlock(void) = 0; virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc *inpDesc, int16 *collResId, int16 *collIndex) = 0; @@ -230,9 +233,9 @@ public: virtual void playTot(int16 skipPlay); virtual void clearCollisions(void); - virtual int16 addNewCollision(int16 id, int16 left, int16 top, int16 right, - int16 bottom, int16 flags, int16 key, uint16 funcEnter, - uint16 funcLeave); + virtual int16 addNewCollision(int16 id, uint16 left, uint16 top, + uint16 right, uint16 bottom, int16 flags, int16 key, + uint16 funcEnter, uint16 funcLeave); virtual void collisionsBlock(void); virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc *inpDesc, int16 *collResId, int16 *collIndex); @@ -245,7 +248,7 @@ public: virtual void prepareStart(void); Game_v1(GobEngine *vm); - virtual ~Game_v1() {}; + virtual ~Game_v1() {} protected: virtual void pushCollisions(char all); @@ -258,9 +261,9 @@ public: virtual void playTot(int16 skipPlay); virtual void clearCollisions(void); - virtual int16 addNewCollision(int16 id, int16 left, int16 top, int16 right, - int16 bottom, int16 flags, int16 key, uint16 funcEnter, - uint16 funcLeave); + virtual int16 addNewCollision(int16 id, uint16 left, uint16 top, + uint16 right, uint16 bottom, int16 flags, int16 key, + uint16 funcEnter, uint16 funcLeave); virtual void collisionsBlock(void); virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc *inpDesc, int16 *collResId, int16 *collIndex); @@ -273,7 +276,7 @@ public: virtual void prepareStart(void); Game_v2(GobEngine *vm); - virtual ~Game_v2() {}; + virtual ~Game_v2() {} protected: struct CollLast { diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index ddc34f176c..6de1165470 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -257,12 +257,12 @@ void Game_v1::playTot(int16 skipPlay) { void Game_v1::clearCollisions() { for (int i = 0; i < 250; i++) { _collisionAreas[i].id = 0; - _collisionAreas[i].left = -1; + _collisionAreas[i].left = 0xFFFF; } } -int16 Game_v1::addNewCollision(int16 id, int16 left, int16 top, - int16 right, int16 bottom, int16 flags, int16 key, +int16 Game_v1::addNewCollision(int16 id, uint16 left, uint16 top, + uint16 right, uint16 bottom, int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave) { Collision *ptr; @@ -275,7 +275,7 @@ int16 Game_v1::addNewCollision(int16 id, int16 left, int16 top, funcEnter, funcLeave); for (int i = 0; i < 250; i++) { - if (_collisionAreas[i].left != -1) + if (_collisionAreas[i].left != 0xFFFF) continue; ptr = &_collisionAreas[i]; @@ -300,7 +300,7 @@ void Game_v1::pushCollisions(char all) { int16 size; debugC(1, kDebugCollisions, "pushCollisions"); - for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { + for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) { if (all || (srcPtr->id & 0x8000)) size++; } @@ -310,10 +310,10 @@ void Game_v1::pushCollisions(char all) { _collStackElemSizes[_collStackSize] = size; _collStackSize++; - for (srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { + for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) { if (all || (srcPtr->id & 0x8000)) { memcpy(destPtr, srcPtr, sizeof(Collision)); - srcPtr->left = -1; + srcPtr->left = 0xFFFF; destPtr++; } } @@ -326,7 +326,7 @@ void Game_v1::popCollisions(void) { debugC(1, kDebugCollisions, "popCollision"); _collStackSize--; - for (destPtr = _collisionAreas; destPtr->left != -1; destPtr++); + for (destPtr = _collisionAreas; destPtr->left != 0xFFFF; destPtr++); srcPtr = _collStack[_collStackSize]; memcpy(destPtr, srcPtr, @@ -595,10 +595,10 @@ void Game_v1::collisionsBlock(void) { int16 cmdHigh; int16 key; int16 flags; - int16 left; - int16 top; - int16 width; - int16 height; + uint16 left; + uint16 top; + uint16 width; + uint16 height; int16 var_22; int16 index; int16 curEditIndex; @@ -693,7 +693,7 @@ void Game_v1::collisionsBlock(void) { _vm->_global->_inter_execPtr += _vm->_inter->load16(); } - if (left == -1) + if (left == 0xFFFF) break; if ((cmd & 1) == 0) { @@ -802,7 +802,7 @@ void Game_v1::collisionsBlock(void) { if (key == 0x1C0D) { for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -833,7 +833,7 @@ void Game_v1::collisionsBlock(void) { if (_activeCollResId == 0) { if (key != 0) { for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -850,7 +850,7 @@ void Game_v1::collisionsBlock(void) { if (_activeCollResId == 0) { for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -878,7 +878,7 @@ void Game_v1::collisionsBlock(void) { collPtr = _collisionAreas; for (i = 0, collPtr = _collisionAreas; - collPtr->left != -1; i++, collPtr++) { + collPtr->left != 0xFFFF; i++, collPtr++) { if ((collPtr->id & 0x8000) == 0) continue; @@ -923,7 +923,7 @@ void Game_v1::collisionsBlock(void) { if (descIndex != 0) { counter = 0; for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -939,7 +939,7 @@ void Game_v1::collisionsBlock(void) { } } else { for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -955,7 +955,7 @@ void Game_v1::collisionsBlock(void) { if (descIndex2 != 0) { counter = 0; for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -1010,7 +1010,7 @@ void Game_v1::collisionsBlock(void) { var_24 = 0; var_26 = 1; for (i = 0; i < 250; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0x8000) == 0) @@ -1102,7 +1102,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, for (i = 0; i < 250; i++) { collArea = &_collisionAreas[i]; - if (collArea->left == -1) + if (collArea->left == 0xFFFF) continue; if ((collArea->id & 0x8000) == 0) @@ -1145,7 +1145,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, for (i = 0; i < 250; i++) { collArea = &_collisionAreas[i]; - if (collArea->left == -1) + if (collArea->left == 0xFFFF) continue; if ((collArea->id & 0x8000) == 0) @@ -1194,7 +1194,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, for (i = 0; i < 250; i++) { collArea = &_collisionAreas[i]; - if (collArea->left == -1) + if (collArea->left == 0xFFFF) continue; if ((collArea->id & 0x8000) == 0) @@ -1487,7 +1487,7 @@ int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { *resIndex = 0; ptr = _collisionAreas; - for (i = 0; ptr->left != -1; ptr++, i++) { + for (i = 0; ptr->left != 0xFFFF; ptr++, i++) { if (all) { if ((ptr->flags & 0xF) > 1) continue; diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 3113d81349..d10c599ddd 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -298,11 +298,12 @@ void Game_v2::clearCollisions() { _lastCollKey = 0; for (int i = 0; i < 150; i++) - _collisionAreas[i].left = -1; + _collisionAreas[i].left = 0xFFFF; } -int16 Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int16 bottom, - int16 flags, int16 key, uint16 funcEnter, uint16 funcLeave) { +int16 Game_v2::addNewCollision(int16 id, uint16 left, uint16 top, + uint16 right, uint16 bottom, int16 flags, int16 key, + uint16 funcEnter, uint16 funcLeave) { Collision *ptr; debugC(5, kDebugCollisions, "addNewCollision"); @@ -314,7 +315,7 @@ int16 Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int funcEnter, funcLeave); for (int i = 0; i < 150; i++) { - if ((_collisionAreas[i].left != -1) && (_collisionAreas[i].id != id)) + if ((_collisionAreas[i].left != 0xFFFF) && (_collisionAreas[i].id != id)) continue; ptr = &_collisionAreas[i]; @@ -341,7 +342,7 @@ void Game_v2::pushCollisions(char all) { int16 size; debugC(1, kDebugCollisions, "pushCollisions"); - for (size = 0, srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) + for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) if (all || (((uint16) srcPtr->id) >= 20)) size++; @@ -365,10 +366,10 @@ void Game_v2::pushCollisions(char all) { _lastCollAreaIndex = 0; _collStackSize++; - for (srcPtr = _collisionAreas; srcPtr->left != -1; srcPtr++) { + for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) { if (all || (((uint16) srcPtr->id) >= 20)) { memcpy(destPtr, srcPtr, sizeof(Collision)); - srcPtr->left = -1; + srcPtr->left = 0xFFFF; destPtr++; } } @@ -389,7 +390,7 @@ void Game_v2::popCollisions(void) { _lastCollId = _collLasts[_collStackSize].id; _lastCollAreaIndex = _collLasts[_collStackSize].areaIndex; - for (destPtr = _collisionAreas; destPtr->left != -1; destPtr++); + for (destPtr = _collisionAreas; destPtr->left != 0xFFFF; destPtr++); srcPtr = _collStack[_collStackSize]; memcpy(destPtr, srcPtr, @@ -407,7 +408,7 @@ int16 Game_v2::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId, int16 newkey; uint32 timeKey; - _handleMouse = handleMouse; + _scrollHandleMouse = handleMouse != 0; if (deltaTime >= -1) { _lastCollKey = 0; @@ -599,10 +600,10 @@ void Game_v2::collisionsBlock(void) { int16 cmdHigh; int16 key; int16 flags; - int16 left; - int16 top; - int16 width; - int16 height; + uint16 left; + uint16 top; + uint16 width; + uint16 height; int16 var_1C; int16 index; int16 curEditIndex; @@ -627,7 +628,7 @@ void Game_v2::collisionsBlock(void) { pushCollisions(0); collArea = _collisionAreas; - while (collArea->left != -1) + while (collArea->left != 0xFFFF) collArea++; _shouldPushColls = 0; @@ -680,12 +681,12 @@ void Game_v2::collisionsBlock(void) { height = _vm->_inter->load16(); } - if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) { + if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) { left += _vm->_draw->_backDeltaX; top += _vm->_draw->_backDeltaY; } - if (left != -1) { + if (left != 0xFFFF) { _vm->_draw->adjustCoords(0, &left, &top); if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) { if (_vm->_draw->_needAdjust != 2) @@ -766,7 +767,7 @@ void Game_v2::collisionsBlock(void) { } else descArray[index].ptr = 0; - if (left == -1) { + if (left == 0xFFFF) { if ((cmd & 1) == 0) { _vm->_global->_inter_execPtr += 2; _vm->_global->_inter_execPtr += @@ -875,7 +876,7 @@ void Game_v2::collisionsBlock(void) { WRITE_VAR(55, curEditIndex); if (key == 0x1C0D) { for (i = 0; i < 150; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) break; if ((_collisionAreas[i].id & 0xC000) != 0x8000) @@ -905,7 +906,7 @@ void Game_v2::collisionsBlock(void) { if (_activeCollResId == 0) { if (key != 0) { for (i = 0; i < 150; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) break; if ((_collisionAreas[i].id & 0xC000) != 0x8000) @@ -921,7 +922,7 @@ void Game_v2::collisionsBlock(void) { if (_activeCollResId == 0) { for (i = 0; i < 150; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) break; if ((_collisionAreas[i].id & 0xC000) != 0x8000) @@ -945,7 +946,7 @@ void Game_v2::collisionsBlock(void) { if (stackPos2 != 0) { collStackPos = 0; - for (i = 0, collPtr = collArea; collPtr->left != -1; i++, collPtr++) { + for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) { if ((collPtr->id & 0xF000) != 0x8000) continue; @@ -992,7 +993,7 @@ void Game_v2::collisionsBlock(void) { if (descIndex != 0) { counter = 0; - for (i = 0, collPtr = collArea; collPtr->left != -1; i++, collPtr++) { + for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) { if ((collPtr->id & 0xF000) == 0x8000) if (++counter == descIndex) { _activeCollResId = collPtr->id; @@ -1003,7 +1004,7 @@ void Game_v2::collisionsBlock(void) { } else { - for (i = 0, collPtr = _collisionAreas; collPtr->left != -1; i++, collPtr++) { + for (i = 0, collPtr = _collisionAreas; collPtr->left != 0xFFFF; i++, collPtr++) { if ((collPtr->id & 0xF000) == 0x8000) { _activeCollResId = collPtr->id; _activeCollIndex = i; @@ -1043,7 +1044,7 @@ void Game_v2::collisionsBlock(void) { var_24 = 0; var_26 = 1; for (i = 0; i < 150; i++) { - if (_collisionAreas[i].left == -1) + if (_collisionAreas[i].left == 0xFFFF) continue; if ((_collisionAreas[i].id & 0xC000) == 0x8000) @@ -1148,7 +1149,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, for (i = 0; i < 150; i++) { collArea = &_collisionAreas[i]; - if (collArea->left == -1) + if (collArea->left == 0xFFFF) continue; if ((collArea->id & 0xC000) != 0x8000) @@ -1200,7 +1201,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, for (i = 0; i < 150; i++) { collArea = &_collisionAreas[i]; - if (collArea->left == -1) + if (collArea->left == 0xFFFF) continue; if ((collArea->id & 0xC000) != 0x8000) @@ -1241,7 +1242,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, if (_mouseButtons != 0) { for (collArea = _collisionAreas, i = 0; - collArea->left != -1; collArea++, i++) { + collArea->left != 0xFFFF; collArea++, i++) { if ((collArea->flags & 0xF00)) continue; @@ -1277,7 +1278,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, for (i = 0; i < 150; i++) { collArea = &_collisionAreas[i]; - if (collArea->left == -1) + if (collArea->left == 0xFFFF) continue; if ((collArea->id & 0xC000) != 0x8000) @@ -1586,7 +1587,7 @@ int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) { *resIndex = 0; ptr = _collisionAreas; - for (i = 0; ptr->left != -1; ptr++, i++) { + for (i = 0; ptr->left != 0xFFFF; ptr++, i++) { if (ptr->id & 0x4000) continue; diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index e7ff850da1..6452ae279f 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -25,7 +25,7 @@ #include "base/plugins.h" #include "common/config-manager.h" -#include "common/fs.h" +//#include "common/fs.h" #include "common/md5.h" #include "sound/mididrv.h" @@ -191,7 +191,7 @@ int GobEngine::init() { _scenery = new Scenery_v2(this); _saveLoad = new SaveLoad_v2(this, _targetName.c_str()); } else if (_features & Gob::GF_GOB3) { - _init = new Init_v2(this); + _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v3(this); _parse = new Parse_v2(this); diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp index 61dfbaff31..4620afabaa 100644 --- a/engines/gob/goblin.cpp +++ b/engines/gob/goblin.cpp @@ -977,39 +977,48 @@ void Goblin::moveFindItem(int16 posX, int16 posY) { break; } - _pressedMapX = posX / 12; - _pressedMapY = posY / 6; + _pressedMapX = CLIP(posX / 12, 0, _vm->_map->_mapWidth - 1); + _pressedMapY = CLIP(posY / 6, 0, _vm->_map->_mapHeight - 1); if ((_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0) && (i < 20)) { - if (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX] != 0) { + if ((_pressedMapY < (_vm->_map->_mapHeight - 1)) && + (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX] != 0)) { _pressedMapY++; - } else if (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX + 1] != 0) { + } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) && + (_pressedMapY < (_vm->_map->_mapHeight - 1)) && + (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX + 1] != 0)) { _pressedMapX++; _pressedMapY++; - } else if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] != 0) { + } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) && + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] != 0)) { _pressedMapX++; - } else if (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX + 1] != 0) { + } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) && + (_pressedMapY > 0) && + (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX + 1] != 0)) { _pressedMapX++; _pressedMapY--; - } else if (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] != 0) { + } else if ((_pressedMapY > 0) && + (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] != 0)) { _pressedMapY--; - } else if (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX - 1] != 0) { + } else if ((_pressedMapY > 0) && (_pressedMapX > 0) && + (_vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX - 1] != 0)) { _pressedMapY--; _pressedMapX--; - } else if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX - 1] != 0) { + } else if ((_pressedMapX > 0) && + (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX - 1] != 0)) { _pressedMapX--; - } else if (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX - 1] != 0) { + } else if ((_pressedMapX > 0) && + (_pressedMapY < (_vm->_map->_mapHeight - 1)) && + (_vm->_map->_itemsMap[_pressedMapY + 1][_pressedMapX - 1] != 0)) { _pressedMapX--; _pressedMapY++; } } } else { - _pressedMapX = posX / 12; - _pressedMapY = posY / 6; + _pressedMapX = CLIP(posX / 12, 0, _vm->_map->_mapWidth - 1); + _pressedMapY = CLIP(posY / 6, 0, _vm->_map->_mapHeight - 1); } - _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1); - _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1); } void Goblin::moveCheckSelect(int16 framesCount, Gob_Object *gobDesc, diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h index f8bddff332..a18213fcf7 100644 --- a/engines/gob/goblin.h +++ b/engines/gob/goblin.h @@ -271,7 +271,7 @@ public: int16 nextAct, int16 framesCount); Goblin_v1(GobEngine *vm); - virtual ~Goblin_v1() {}; + virtual ~Goblin_v1() {} protected: virtual bool isMovement(int8 state) { return false; } @@ -291,7 +291,7 @@ public: int16 nextAct, int16 framesCount); Goblin_v2(GobEngine *vm); - virtual ~Goblin_v2() {}; + virtual ~Goblin_v2() {} protected: virtual bool isMovement(int8 state); @@ -306,7 +306,7 @@ public: int16 index, int16 x, int16 y, int16 state); Goblin_v3(GobEngine *vm); - virtual ~Goblin_v3() {}; + virtual ~Goblin_v3() {} protected: virtual bool isMovement(int8 state); diff --git a/engines/gob/imd.cpp b/engines/gob/imd.cpp index d9faba5b61..d2fa69e067 100644 --- a/engines/gob/imd.cpp +++ b/engines/gob/imd.cpp @@ -961,7 +961,7 @@ uint16 ImdPlayer::checkFrameType(Imd *imdPtr, int16 frame) { } void ImdPlayer::seekFrame(Imd *imdPtr, int16 frame, int16 from, bool restart) { - uint32 framePos; + uint32 framePos = 0; if (!imdPtr) return; @@ -1011,6 +1011,8 @@ uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { _top = yBak = imdPtr->y; _bottom = heightBak= imdPtr->height; _right = widthBak = imdPtr->width; + _right += _left - 1; + _bottom += _top - 1; if ((frame == 0) && (imdPtr->verMin & 0x800)) _vm->_video->setPalette(imdPtr->palette); @@ -1106,7 +1108,7 @@ uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { cmd = _vm->_dataIO->readUint16(imdPtr->handle); - // Clear sound slice + // Empty sound slice } else if (!hasNextCmd && (!_noSound)) { soundBuf = new byte[_soundSliceSize]; assert(soundBuf); diff --git a/engines/gob/init.h b/engines/gob/init.h index 3ca935c6b4..6d8d71ae59 100644 --- a/engines/gob/init.h +++ b/engines/gob/init.h @@ -35,7 +35,7 @@ public: virtual void initVideo() = 0; Init(GobEngine *vm); - virtual ~Init() {}; + virtual ~Init() {} protected: Video::PalDesc *_palDesc; @@ -50,7 +50,7 @@ public: virtual void initVideo(); Init_v1(GobEngine *vm); - virtual ~Init_v1() {}; + virtual ~Init_v1() {} }; class Init_v2 : public Init_v1 { @@ -58,7 +58,15 @@ public: virtual void initVideo(); Init_v2(GobEngine *vm); - virtual ~Init_v2() {}; + virtual ~Init_v2() {} +}; + +class Init_v3 : public Init_v2 { +public: + virtual void initVideo(); + + Init_v3(GobEngine *vm); + virtual ~Init_v3() {} }; } // End of namespace Gob diff --git a/engines/gob/init_v3.cpp b/engines/gob/init_v3.cpp new file mode 100644 index 0000000000..5e10240257 --- /dev/null +++ b/engines/gob/init_v3.cpp @@ -0,0 +1,42 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/init.h" +#include "gob/game.h" + +namespace Gob { + +Init_v3::Init_v3(GobEngine *vm) : Init_v2(vm) { +} + +void Init_v3::initVideo() { + Init_v2::initVideo(); + + _vm->_game->_noScroll = false; +} + +} // End of namespace Gob diff --git a/engines/gob/inter.h b/engines/gob/inter.h index cd685bd27e..90d0f7158e 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -61,7 +61,7 @@ public: virtual void animPalette() = 0; Inter(GobEngine *vm); - virtual ~Inter() {}; + virtual ~Inter() {} protected: struct OpFuncParams { @@ -108,7 +108,7 @@ protected: class Inter_v1 : public Inter { public: Inter_v1(GobEngine *vm); - virtual ~Inter_v1() {}; + virtual ~Inter_v1() {} virtual int16 loadSound(int16 slot); virtual void animPalette(); @@ -303,7 +303,7 @@ protected: class Inter_v2 : public Inter_v1 { public: Inter_v2(GobEngine *vm); - virtual ~Inter_v2() {}; + virtual ~Inter_v2() {} virtual int16 loadSound(int16 search); virtual void animPalette(); @@ -394,7 +394,7 @@ protected: class Inter_Bargon : public Inter_v2 { public: Inter_Bargon(GobEngine *vm); - virtual ~Inter_Bargon() {}; + virtual ~Inter_Bargon() {} protected: typedef void (Inter_Bargon::*OpcodeDrawProcBargon)(); @@ -440,7 +440,7 @@ protected: class Inter_v3 : public Inter_v2 { public: Inter_v3(GobEngine *vm); - virtual ~Inter_v3() {}; + virtual ~Inter_v3() {} protected: typedef void (Inter_v3::*OpcodeDrawProcV3)(); diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 052aef0e25..822c96d749 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1656,58 +1656,15 @@ bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { break; case 1: + _vm->_util->forceMouseUp(true); key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0); storeKey(key); break; case 2: - key = 0; - - if (_vm->_global->_pressedKeys[0x48]) - key |= 1; - - if (_vm->_global->_pressedKeys[0x50]) - key |= 2; - - if (_vm->_global->_pressedKeys[0x4D]) - key |= 4; - - if (_vm->_global->_pressedKeys[0x4B]) - key |= 8; - - if (_vm->_global->_pressedKeys[0x1C]) - key |= 0x10; - - if (_vm->_global->_pressedKeys[0x39]) - key |= 0x20; - - if (_vm->_global->_pressedKeys[1]) - key |= 0x40; - - if (_vm->_global->_pressedKeys[0x1D]) - key |= 0x80; - - if (_vm->_global->_pressedKeys[0x2A]) - key |= 0x100; - - if (_vm->_global->_pressedKeys[0x36]) - key |= 0x200; - - if (_vm->_global->_pressedKeys[0x38]) - key |= 0x400; - - if (_vm->_global->_pressedKeys[0x3B]) - key |= 0x800; - - if (_vm->_global->_pressedKeys[0x3C]) - key |= 0x1000; - - if (_vm->_global->_pressedKeys[0x3D]) - key |= 0x2000; - - if (_vm->_global->_pressedKeys[0x3E]) - key |= 0x4000; + _vm->_util->processInput(true); + key = _vm->_util->checkKey(); WRITE_VAR(0, key); _vm->_util->clearKeyBuf(); @@ -2227,6 +2184,7 @@ bool Inter_v1::o1_readData(OpFuncParams ¶ms) { dataVar = _vm->_parse->parseVarIndex(); size = _vm->_parse->parseValExpr(); offset = _vm->_parse->parseValExpr(); + retSize = 0; if (_vm->_game->_extHandle >= 0) _vm->_dataIO->closeData(_vm->_game->_extHandle); diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 3f76be5498..78ea9cab7a 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -975,7 +975,7 @@ void Inter_v2::o2_loadMultObject() { _vm->_global->_inter_execPtr++; } - if (_vm->_goblin->_gobsCount < 0) + if (_vm->_goblin->_gobsCount <= objIndex) return; Mult::Mult_Object &obj = _vm->_mult->_objects[objIndex]; @@ -1376,7 +1376,9 @@ void Inter_v2::o2_initScreen() { if (height > 0) _vm->_video->_surfHeight = height; - _vm->_video->_splitHeight = _vm->_video->_surfHeight - offY; + _vm->_video->_splitHeight1 = MIN(200, _vm->_video->_surfHeight - offY); + _vm->_video->_splitHeight2 = offY; + _vm->_video->_splitStart = _vm->_video->_surfHeight - offY; _vm->_draw->closeScreen(); _vm->_util->clearPalette(); @@ -1827,6 +1829,7 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { size = _vm->_parse->parseValExpr(); evalExpr(0); offset = _vm->_global->_inter_resVal; + retSize = 0; debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)", _vm->_global->_inter_resStr, dataVar, size, offset); @@ -2003,12 +2006,12 @@ void Inter_v2::o2_stopInfogrames(OpGobParams ¶ms) { } void Inter_v2::o2_handleGoblins(OpGobParams ¶ms) { - _vm->_goblin->_gob1NoTurn = (bool) VAR(load16()); - _vm->_goblin->_gob2NoTurn = (bool) VAR(load16()); + _vm->_goblin->_gob1NoTurn = VAR(load16()) != 0; + _vm->_goblin->_gob2NoTurn = VAR(load16()) != 0; _vm->_goblin->_gob1RelaxTimeVar = load16(); _vm->_goblin->_gob2RelaxTimeVar = load16(); - _vm->_goblin->_gob1Busy = (bool) VAR(load16()); - _vm->_goblin->_gob2Busy = (bool) VAR(load16()); + _vm->_goblin->_gob1Busy = VAR(load16()) != 0; + _vm->_goblin->_gob2Busy = VAR(load16()) != 0; _vm->_goblin->handleGoblins(); } @@ -2023,6 +2026,7 @@ int16 Inter_v2::loadSound(int16 search) { type = SOUND_SND; slotIdMask = 0; + dataSize = 0; if (!search) { slot = _vm->_parse->parseValExpr(); diff --git a/engines/gob/inter_v3.cpp b/engines/gob/inter_v3.cpp index 0fb270891b..f34953b40f 100644 --- a/engines/gob/inter_v3.cpp +++ b/engines/gob/inter_v3.cpp @@ -715,7 +715,7 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { int16 totTextItem; int16 part, curPart = 0; int16 offX = 0, offY = 0; - int16 collId, collCmd; + int16 collId = 0, collCmd; uint32 stringStartVar, stringVar; bool end; diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 63aea49a29..db0660fa5c 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -22,6 +22,7 @@ MODULE_OBJS := \ init.o \ init_v1.o \ init_v2.o \ + init_v3.o \ inter.o \ inter_v1.o \ inter_v2.o \ diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index d0b2a6589c..d407c41292 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -104,6 +104,8 @@ void Mult::initAll(void) { _objects = 0; _animSurf = 0; _renderData = 0; + + _vm->_scenery->init(); } void Mult::freeAll(void) { @@ -113,7 +115,6 @@ void Mult::freeAll(void) { _vm->_scenery->freeAnim(i); _vm->_scenery->freeStatic(i); } - _vm->_scenery->init(); } void Mult::freeMult() { diff --git a/engines/gob/mult.h b/engines/gob/mult.h index 7f318e8a7f..4be1290a87 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -293,7 +293,7 @@ protected: class Mult_v1 : public Mult { public: Mult_v1(GobEngine *vm); - virtual ~Mult_v1() {}; + virtual ~Mult_v1() {} virtual void loadMult(int16 resId); virtual void freeMultKeys(); diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index d973ea4c22..8b158ab314 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -227,6 +227,13 @@ void Mult_v2::loadMult(int16 resId) { case 3: _vm->_global->_inter_execPtr += 4; break; + + case -1: + break; + + default: + warning("Mult_v2::loadMult(): Unknown sound key command (%d)", + _multData->sndKeys[i].cmd); } } @@ -1185,6 +1192,8 @@ void Mult_v2::advanceObjects(int16 index) { } void Mult_v2::advanceAllObjects() { + Mult_Data *multData = _multData; + for (int i = 0; i < 8; i++) { if (_multDatas[i]) { _multData = _multDatas[i]; @@ -1192,6 +1201,8 @@ void Mult_v2::advanceAllObjects() { advanceObjects(j); } } + + _multData = multData; } } // End of namespace Gob diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index 93af23c82b..a603fd164e 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -196,17 +196,17 @@ void Parse::printExpr_internal(char stopToken) { debugN(5, "var8_%d", _vm->_inter->load16()); break; - case 19: // uint32 immediate + case 19: // int32/uint32 immediate debugN(5, "%d", READ_LE_UINT32(_vm->_global->_inter_execPtr)); _vm->_global->_inter_execPtr += 4; break; - case 20: // uint16 immediate + case 20: // int16 immediate debugN(5, "%d", _vm->_inter->load16()); break; - case 21: // uint8 immediate - debugN(5, "%d", *_vm->_global->_inter_execPtr++); + case 21: // int8 immediate + debugN(5, "%d", (int8) *_vm->_global->_inter_execPtr++); break; case 22: // string immediate diff --git a/engines/gob/parse.h b/engines/gob/parse.h index 27a6f50b1c..22853e24f0 100644 --- a/engines/gob/parse.h +++ b/engines/gob/parse.h @@ -36,7 +36,7 @@ public: virtual int16 parseExpr(byte stopToken, byte *resultPtr) = 0; Parse(GobEngine *vm); - virtual ~Parse() {}; + virtual ~Parse() {} protected: enum PointerType { @@ -56,7 +56,7 @@ protected: class Parse_v1 : public Parse { public: Parse_v1(GobEngine *vm); - virtual ~Parse_v1() {}; + virtual ~Parse_v1() {} virtual int16 parseVarIndex(void); virtual int16 parseValExpr(byte stopToken = 99); @@ -66,7 +66,7 @@ public: class Parse_v2 : public Parse_v1 { public: Parse_v2(GobEngine *vm); - virtual ~Parse_v2() {}; + virtual ~Parse_v2() {} virtual int16 parseVarIndex(void); virtual int16 parseValExpr(byte stopToken = 99); diff --git a/engines/gob/saveload.h b/engines/gob/saveload.h index 905ec6965d..6f867e30ec 100644 --- a/engines/gob/saveload.h +++ b/engines/gob/saveload.h @@ -114,7 +114,7 @@ public: virtual SaveType getSaveType(const char *fileName); SaveLoad_v2(GobEngine *vm, const char *targetName); - virtual ~SaveLoad_v2() {}; + virtual ~SaveLoad_v2() {} protected: virtual uint32 getSaveGameSize(); @@ -135,7 +135,7 @@ public: virtual SaveType getSaveType(const char *fileName); SaveLoad_v3(GobEngine *vm, const char *targetName); - virtual ~SaveLoad_v3() {}; + virtual ~SaveLoad_v3() {} protected: bool _useScreenshots; diff --git a/engines/gob/scenery.h b/engines/gob/scenery.h index 864b74f18d..365bbd326c 100644 --- a/engines/gob/scenery.h +++ b/engines/gob/scenery.h @@ -156,7 +156,7 @@ public: virtual int16 loadAnim(char search); Scenery_v1(GobEngine *vm); - virtual ~Scenery_v1() {}; + virtual ~Scenery_v1() {} }; class Scenery_v2 : public Scenery_v1 { @@ -164,7 +164,7 @@ public: virtual int16 loadAnim(char search); Scenery_v2(GobEngine *vm); - virtual ~Scenery_v2() {}; + virtual ~Scenery_v2() {} }; } // End of namespace Gob diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp index c2e48adac1..baee878f4d 100644 --- a/engines/gob/sound.cpp +++ b/engines/gob/sound.cpp @@ -33,6 +33,8 @@ namespace Gob { +#define FRAC_BITS 16 + void SoundDesc::set(SoundType type, SoundSource src, byte *data, uint32 dSize) { @@ -168,15 +170,18 @@ Snd::Snd(GobEngine *vm) : _vm(vm) { _length = 0; _freq = 0; _repCount = 0; - _offset = 0.0; - _frac = 0.0; + _offset = 0; + _offsetFrac = 0; + _offsetInc = 0; + _offsetIncFrac = 0; + _cur = 0; _last = 0; _fade = false; - _fadeVol = 255.0; - _fadeVolStep = 0.0; + _fadeVol = 65536; + _fadeVolStep = 0; _fadeSamples = 0; _curFadeSamples = 0; @@ -228,9 +233,9 @@ void Snd::stopSound(int16 fadeLength, SoundDesc *sndDesc) { } _fade = true; - _fadeVol = 255.0; + _fadeVol = 65536; _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); - _fadeVolStep = 255.0 / ((double) _fadeSamples); + _fadeVolStep = MAX((int32) 1, (int32) (65536 / _fadeSamples)); _curFadeSamples = 0; } @@ -312,29 +317,31 @@ void Snd::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency, _length = sndDesc.size(); _freq = frequency; - if ((frequency % 100) == 0) - _freq--; - - _ratio = ((double) _freq) / _rate; - _offset = 0.0; - _frac = 0; - _last = _cur; - _cur = _data[0]; _repCount = repCount; _end = false; _playingSound = 1; + _offset = 0; + _offsetFrac = 0; + + uint32 incr = (_freq << FRAC_BITS) / _rate; + _offsetInc = incr >> FRAC_BITS; + _offsetIncFrac = incr & ((1UL << FRAC_BITS) - 1); + + _last = _cur; + _cur = _data[0]; + _curFadeSamples = 0; if (fadeLength == 0) { _fade = false; - _fadeVol = 255.0; + _fadeVol = 65536; _fadeSamples = 0; - _fadeVolStep = 0.0; + _fadeVolStep = 0; } else { _fade = true; - _fadeVol = 0.0; + _fadeVol = 0; _fadeSamples = (int) (fadeLength * (((double) _rate) / 10.0)); - _fadeVolStep = -(255.0 / ((double) _fadeSamples)); + _fadeVolStep = - MAX((int32) 1, (int32) (65536 / _fadeSamples)); } } @@ -371,8 +378,8 @@ void Snd::checkEndSample() { if (_compositionPos != -1) nextCompositionPos(); else if ((_repCount == -1) || (--_repCount > 0)) { - _offset = 0.0; - _frac = 0.0; + _offset = 0; + _offsetFrac = 0; _end = false; _playingSound = 1; } else { @@ -384,6 +391,9 @@ void Snd::checkEndSample() { int Snd::readBuffer(int16 *buffer, const int numSamples) { Common::StackLock slock(_mutex); + int16 val; + uint32 tmp, oldOffset; + for (int i = 0; i < numSamples; i++) { if (!_data) return i; @@ -392,16 +402,25 @@ int Snd::readBuffer(int16 *buffer, const int numSamples) { if (_end) return i; - *buffer++ = (int16) ((_last + (_cur - _last) * _frac) * _fadeVol); - _frac += _ratio; - _offset += _ratio; - while ((_frac > 1) && (_offset < _length)) { - _frac -= 1; + // Linear interpolation. See sound/rate.cpp + + val = (_last + (((_cur - _last) * _offsetFrac + + (1UL << (FRAC_BITS - 1))) >> FRAC_BITS)) << 8; + *buffer++ = (((int32) val) * _fadeVol) >> 16; + + oldOffset = _offset; + + tmp = _offsetFrac + _offsetIncFrac; + _offset += _offsetInc + (tmp >> FRAC_BITS); + _offsetFrac = tmp & ((1UL << FRAC_BITS) - 1); + + if (oldOffset < _offset) { _last = _cur; - _cur = _data[(int) _offset]; + _cur = _data[oldOffset]; } if (_fade) { + if (++_curFadeSamples >= _fadeSamples) { if (_fadeVolStep > 0) { _data = 0; @@ -410,11 +429,15 @@ int Snd::readBuffer(int16 *buffer, const int numSamples) { _compositionPos = -1; _curSoundDesc = 0; } else { - _fadeVol = 255.0; + _fadeVol = 65536; _fade = false; } } else _fadeVol -= _fadeVolStep; + + if (_fadeVol < 0) + _fadeVol = 0; + } } return numSamples; diff --git a/engines/gob/sound.h b/engines/gob/sound.h index ffdaf2a3d6..8f05fcf2e1 100644 --- a/engines/gob/sound.h +++ b/engines/gob/sound.h @@ -51,7 +51,7 @@ public: byte *getData() { return _dataPtr; } uint32 size() { return _size; } bool empty() { return !_dataPtr; } - bool isId(int16 id) { return _dataPtr && _id == id; }; + bool isId(int16 id) { return _dataPtr && _id == id; } SoundType getType() { return _type; } void set(SoundType type, SoundSource src, byte *data, uint32 dSize); @@ -171,16 +171,18 @@ protected: uint32 _rate; int32 _freq; int32 _repCount; - double _offset; - double _ratio; - double _frac; + uint32 _offset; + uint32 _offsetFrac; + uint32 _offsetInc; + uint32 _offsetIncFrac; + int16 _cur; int16 _last; bool _fade; - double _fadeVol; - double _fadeVolStep; + int32 _fadeVol; + int32 _fadeVolStep; uint8 _fadeLength; uint32 _fadeSamples; uint32 _curFadeSamples; diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index e2ef60d5e2..ad10381dac 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -82,7 +82,7 @@ void Util::initInput(void) { void Util::processInput(bool scroll) { Common::Event event; Common::EventManager *eventMan = g_system->getEventManager(); - int16 x, y; + int16 x = 0, y = 0; bool hasMove = false; while (eventMan->pollEvent(event)) { @@ -112,7 +112,7 @@ void Util::processInput(bool scroll) { _fastMode ^= 2; break; } - addKeyToBuffer(event.kbd.keycode); + addKeyToBuffer(event.kbd.ascii); break; case Common::EVENT_KEYUP: break; @@ -125,8 +125,13 @@ void Util::processInput(bool scroll) { } _vm->_global->_speedFactor = MIN(_fastMode + 1, 3); - if (scroll && hasMove) + if (scroll && hasMove) { + if (y >= (200 - _vm->_video->_splitHeight2)) { + y = 200 - _vm->_video->_splitHeight2 - 1; + _vm->_util->setMousePos(x, y); + } _vm->_game->evaluateScroll(x, y); + } } void Util::clearKeyBuf(void) { @@ -171,16 +176,16 @@ int16 Util::translateKey(int16 key) { {274, 0x5000}, // Down arrow {275, 0x4D00}, // Right arrow {276, 0x4B00}, // Left arrow - {282, 0x3B00}, // F1 - {283, 0x3C00}, // F2 - {284, 0x3D00}, // F3 - {285, 0x3E00}, // F4 - {286, 0x011B}, // F5 - {287, 0x4000}, // F6 - {288, 0x4100}, // F7 - {289, 0x4200}, // F8 - {290, 0x4300}, // F9 - {291, 0x4400} // F10 + {315, 0x3B00}, // F1 + {316, 0x3C00}, // F2 + {317, 0x3D00}, // F3 + {318, 0x3E00}, // F4 + {319, 0x011B}, // F5 + {320, 0x4000}, // F6 + {321, 0x4100}, // F7 + {322, 0x4200}, // F8 + {323, 0x4300}, // F9 + {324, 0x4400} // F10 }; for (int i = 0; i < ARRAYSIZE(keys); i++) @@ -261,7 +266,10 @@ void Util::waitMouseRelease(char drawMouse) { } while (buttons != 0); } -void Util::forceMouseUp(void) { +void Util::forceMouseUp(bool onlyWhenSynced) { + if (onlyWhenSynced && (_vm->_game->_mouseButtons != _mouseButtons)) + return; + _vm->_game->_mouseButtons = 0; _mouseButtons = 0; } @@ -385,6 +393,11 @@ void Util::cutFromStr(char *str, int16 from, int16 cutlen) { } while (str[i] != 0); } +void Util::replaceChar(char *str, char c1, char c2) { + while ((str = strchr(str, c1))) + *str = c2; +} + static const char trStr1[] = " ' + - :0123456789: <=> abcdefghijklmnopqrstuvwxyz " "abcdefghijklmnopqrstuvwxyz "; diff --git a/engines/gob/util.h b/engines/gob/util.h index ca9042598c..3adc26385a 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -64,7 +64,7 @@ public: void waitMouseUp(void); void waitMouseDown(void); void waitMouseRelease(char drawMouse); - void forceMouseUp(void); + void forceMouseUp(bool onlyWhenSynced = false); void clearPalette(void); void setFrameRate(int16 rate); @@ -77,6 +77,7 @@ public: static void insertStr(const char *str1, char *str2, int16 pos); static void cutFromStr(char *str, int16 from, int16 cutlen); static void prepareStr(char *str); + static void replaceChar(char *str, char c1, char c2); static void listInsertFront(List *list, void *data); static void listInsertBack(List *list, void *data); diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 4af5ece7c5..93b9f9b470 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -89,7 +89,9 @@ Video::Video(GobEngine *vm) : _vm(vm) { _surfHeight = 200; _scrollOffsetX = 0; _scrollOffsetY = 0; - _splitHeight = 200; + _splitHeight1 = 200; + _splitHeight2 = 0; + _splitStart = 0; _curSparse = 0; _lastSparse = 0xFFFFFFFF; @@ -162,11 +164,11 @@ void Video::retrace(bool mouse) { if (_vm->_global->_primarySurfDesc) { g_system->copyRectToScreen(_vm->_global->_primarySurfDesc->getVidMem() + _scrollOffsetY * _surfWidth + _scrollOffsetX, _surfWidth, - 0, 0, 320, _splitHeight); - if (_splitHeight < _surfHeight) + 0, 0, 320, _splitHeight1); + if (_splitHeight2 > 0) g_system->copyRectToScreen(_vm->_global->_primarySurfDesc->getVidMem() + - _splitHeight * _surfWidth, _surfWidth, 0, _splitHeight, 320, - _surfHeight - _splitHeight); + _splitStart * _surfWidth, _surfWidth, 0, + 200 - _splitHeight2, 320, _splitHeight2); g_system->updateScreen(); } } diff --git a/engines/gob/video.h b/engines/gob/video.h index d3d297d8cb..21c3e7d0f2 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -99,7 +99,9 @@ public: int16 _surfHeight; int16 _scrollOffsetX; int16 _scrollOffsetY; - int16 _splitHeight; + int16 _splitHeight1; + int16 _splitHeight2; + int16 _splitStart; void freeDriver(); void initPrimary(int16 mode); @@ -147,7 +149,7 @@ public: SurfaceDesc *destDesc) = 0; Video(class GobEngine *vm); - virtual ~Video() {}; + virtual ~Video() {} protected: class VideoDriver *_videoDriver; @@ -166,7 +168,7 @@ public: int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); Video_v1(GobEngine *vm); - virtual ~Video_v1() {}; + virtual ~Video_v1() {} }; class Video_v2 : public Video_v1 { @@ -175,7 +177,7 @@ public: int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); Video_v2(GobEngine *vm); - virtual ~Video_v2() {}; + virtual ~Video_v2() {} }; class VideoDriver { diff --git a/engines/kyra/animator.cpp b/engines/kyra/animator.cpp index 322009bc8c..ba6ded002c 100644 --- a/engines/kyra/animator.cpp +++ b/engines/kyra/animator.cpp @@ -39,10 +39,17 @@ ScreenAnimator::ScreenAnimator(KyraEngine *vm, OSystem *system) { _system = system; _screenObjects = _actors = _items = _sprites = _objectQueue = 0; _noDrawShapesFlag = 0; + + _actorBkgBackUp[0] = new uint8[_screen->getRectSize(8, 69)]; + memset(_actorBkgBackUp[0], 0, _screen->getRectSize(8, 69)); + _actorBkgBackUp[1] = new uint8[_screen->getRectSize(8, 69)]; + memset(_actorBkgBackUp[1], 0, _screen->getRectSize(8, 69)); } ScreenAnimator::~ScreenAnimator() { close(); + delete [] _actorBkgBackUp[0]; + delete [] _actorBkgBackUp[1]; } void ScreenAnimator::init(int actors_, int items_, int sprites_) { @@ -72,7 +79,7 @@ void ScreenAnimator::initAnimStateList() { animStates[0].index = 0; animStates[0].active = 1; animStates[0].flags = 0x800; - animStates[0].background = _vm->_shapes[2]; + animStates[0].background = _actorBkgBackUp[0]; animStates[0].rectSize = _screen->getRectSize(4, 48); animStates[0].width = 4; animStates[0].height = 48; @@ -83,7 +90,7 @@ void ScreenAnimator::initAnimStateList() { animStates[i].index = i; animStates[i].active = 0; animStates[i].flags = 0x800; - animStates[i].background = _vm->_shapes[3]; + animStates[i].background = _actorBkgBackUp[1]; animStates[i].rectSize = _screen->getRectSize(4, 64); animStates[i].width = 4; animStates[i].height = 48; @@ -100,7 +107,7 @@ void ScreenAnimator::initAnimStateList() { for (int i = 16; i < 28; ++i) { animStates[i].index = i; animStates[i].flags = 0; - animStates[i].background = _vm->_shapes[349+i]; + animStates[i].background = _vm->_shapes[345+i]; animStates[i].rectSize = _screen->getRectSize(3, 24); animStates[i].width = 3; animStates[i].height = 16; @@ -196,19 +203,16 @@ void ScreenAnimator::preserveOrRestoreBackground(AnimObject *obj, bool restore) int temp; temp = x + width; - if (temp >= 39) { + if (temp >= 39) x = 39 - width; - } temp = y + height; - if (temp >= 136) { + if (temp >= 136) y = 136 - height; - } - if (restore) { + if (restore) _screen->copyBlockToPage(_screen->_curPage, x << 3, y, width << 3, height, obj->background); - } else { + else _screen->copyRegionToBuffer(_screen->_curPage, x << 3, y, width << 3, height, obj->background); - } } void ScreenAnimator::prepDrawAllObjects() { @@ -229,13 +233,12 @@ void ScreenAnimator::prepDrawAllObjects() { int ypos = curObject->y1; int drawLayer = 0; - if (!(curObject->flags & 0x800)) { + if (!(curObject->flags & 0x800)) drawLayer = 7; - } else if (curObject->disable) { + else if (curObject->disable) drawLayer = 0; - } else { + else drawLayer = _vm->_sprites->getDrawLayer(curObject->drawY); - } // talking head functionallity if (_vm->_talkingCharNum != -1 && (_vm->_currentCharacter->currentAnimFrame != 88 || curObject->index != 0)) { @@ -253,18 +256,16 @@ void ScreenAnimator::prepDrawAllObjects() { shapesIndex = baseAnimFrameTable2[curObject->index]; int temp2 = 0; if (curObject->index == 2) { - if (_vm->_characterList[2].sceneId == 77 || _vm->_characterList[2].sceneId == 86) { + if (_vm->_characterList[2].sceneId == 77 || _vm->_characterList[2].sceneId == 86) temp2 = 1; - } else { + else temp2 = 0; - } } else { temp2 = 1; } - if (!temp2) { + if (!temp2) shapesIndex = -1; - } } xpos = curObject->x1; @@ -282,16 +283,14 @@ void ScreenAnimator::prepDrawAllObjects() { xpos += tempX; ypos += tempY; - if (_vm->_scaleMode && _brandonScaleX != 256) { + if (_vm->_scaleMode && _brandonScaleX != 256) ++xpos; - } if (curObject->index == 0 && shapesIndex != -1) { if (!(_vm->_brandonStatusBit & 2)) { flagUnk3 = 0x100; - if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000)) { + if ((flagUnk1 & 0x200) || (flagUnk2 & 0x4000)) flagUnk3 = 0; - } int tempFlags = 0; if (flagUnk3 & 0x100) { @@ -302,23 +301,22 @@ void ScreenAnimator::prepDrawAllObjects() { if (!(flagUnk3 & 0x100) && (flagUnk2 & 0x4000)) { tempFlags = curObject->flags & 1; tempFlags |= 0x900 | flagUnk1 | 0x4000; - _screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); + _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); } else { if (!(flagUnk2 & 0x4000)) { tempFlags = curObject->flags & 1; tempFlags |= 0x900 | flagUnk1; } - _screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); + _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 4, _vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); } } } else { if (shapesIndex != -1) { int tempFlags = 0; - if (curObject->flags & 1) { + if (curObject->flags & 1) tempFlags = 1; - } - _screen->drawShape(drawPage, _vm->_shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer); + _screen->drawShape(drawPage, _vm->_shapes[shapesIndex], xpos, ypos, 2, tempFlags | 0x800, drawLayer); } } } @@ -331,37 +329,32 @@ void ScreenAnimator::prepDrawAllObjects() { if (curObject->index == 0) { flagUnk3 = 0x100; - if (flagUnk1 & 0x200 || flagUnk2 & 0x4000) { + if (flagUnk1 & 0x200 || flagUnk2 & 0x4000) flagUnk3 = 0; - } - if (_vm->_brandonStatusBit & 2) { + if (_vm->_brandonStatusBit & 2) curObject->flags &= 0xFFFFFFFE; - } if (!_vm->_scaleMode) { - if (flagUnk3 & 0x100) { + if (flagUnk3 & 0x100) _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer); - } else if (flagUnk2 & 0x4000) { + else if (flagUnk2 & 0x4000) _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4000, int(_vm->_brandonInvFlag), drawLayer); - } else { + else _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1, drawLayer); - } } else { - if (flagUnk3 & 0x100) { + if (flagUnk3 & 0x100) _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_vm->_brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY); - } else if (flagUnk2 & 0x4000) { + else if (flagUnk2 & 0x4000) _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4004, int(_vm->_brandonInvFlag), drawLayer, _brandonScaleX, _brandonScaleY); - } else { + else _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x4, drawLayer, _brandonScaleX, _brandonScaleY); - } } } else { - if (curObject->index >= 16 && curObject->index <= 27) { + if (curObject->index >= 16 && curObject->index <= 27) _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | 4, drawLayer, (int)_vm->_scaleTable[curObject->drawY], (int)_vm->_scaleTable[curObject->drawY]); - } else { + else _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags, drawLayer); - } } } curObject = curObject->nextAnimObject; @@ -380,25 +373,21 @@ void ScreenAnimator::copyChangedObjectsForward(int refreshFlag) { width = curObject->width + (curObject->width2>>3) + 2; height = curObject->height + curObject->height2*2; - if (xpos < 1) { + if (xpos < 1) xpos = 1; - } else if (xpos > 39) { + else if (xpos > 39) continue; - } - if (xpos + width > 39) { + if (xpos + width > 39) width = 39 - xpos; - } - if (ypos < 8) { + if (ypos < 8) ypos = 8; - } else if (ypos > 136) { + else if (ypos > 136) continue; - } - if (ypos + height > 136) { + if (ypos + height > 136) height = 136 - ypos; - } _screen->copyRegion(xpos << 3, ypos, xpos << 3, ypos, width << 3, height, 2, 0, Screen::CR_CLIPPED); curObject->refreshFlag = 0; @@ -446,7 +435,7 @@ void ScreenAnimator::animAddGameItem(int index, uint16 sceneId) { animObj->refreshFlag = 1; animObj->bkgdChangeFlag = 1; animObj->drawY = currentRoom->itemsYPos[index]; - animObj->sceneAnimPtr = _vm->_shapes[220+currentRoom->itemsTable[index]]; + animObj->sceneAnimPtr = _vm->_shapes[216+currentRoom->itemsTable[index]]; animObj->animFrameNumber = -1; animObj->x1 = currentRoom->itemsXPos[index]; animObj->y1 = currentRoom->itemsYPos[index]; @@ -472,14 +461,15 @@ void ScreenAnimator::animAddNPC(int character) { animObj->refreshFlag = 1; animObj->bkgdChangeFlag = 1; animObj->drawY = ch->y1; - animObj->sceneAnimPtr = _vm->_shapes[4+ch->currentAnimFrame]; + animObj->sceneAnimPtr = _vm->_shapes[ch->currentAnimFrame]; animObj->x1 = animObj->x2 = ch->x1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].xOffset; animObj->y1 = animObj->y2 = ch->y1 + _vm->_defaultShapeTable[ch->currentAnimFrame-7].yOffset; - if (ch->facing >= 1 && ch->facing <= 3) { + + if (ch->facing >= 1 && ch->facing <= 3) animObj->flags |= 1; - } else if (ch->facing >= 5 && ch->facing <= 7) { + else if (ch->facing >= 5 && ch->facing <= 7) animObj->flags &= 0xFFFFFFFE; - } + _objectQueue = objectQueue(_objectQueue, animObj); preserveAnyChangedBackgrounds(); animObj->refreshFlag = 1; @@ -507,16 +497,14 @@ AnimObject *ScreenAnimator::objectRemoveQueue(AnimObject *queue, AnimObject *rem if (!cur->nextAnimObject) { if (cur == rem) { - if (!prev) { + if (!prev) return 0; - } else { + else prev->nextAnimObject = 0; - } } } else { - if (cur == rem) { + if (cur == rem) prev->nextAnimObject = rem->nextAnimObject; - } } return queue; @@ -556,31 +544,28 @@ AnimObject *ScreenAnimator::objectQueue(AnimObject *queue, AnimObject *add) { void ScreenAnimator::addObjectToQueue(AnimObject *object) { debugC(9, kDebugLevelAnimator, "ScreenAnimator::addObjectToQueue(%p)", (const void *)object); - if (!_objectQueue) { + if (!_objectQueue) _objectQueue = objectAddHead(0, object); - } else { + else _objectQueue = objectQueue(_objectQueue, object); - } } void ScreenAnimator::refreshObject(AnimObject *object) { debugC(9, kDebugLevelAnimator, "ScreenAnimator::refreshObject(%p)", (const void *)object); _objectQueue = objectRemoveQueue(_objectQueue, object); - if (_objectQueue) { + if (_objectQueue) _objectQueue = objectQueue(_objectQueue, object); - } else { + else _objectQueue = objectAddHead(0, object); - } } void ScreenAnimator::makeBrandonFaceMouse() { debugC(9, kDebugLevelAnimator, "ScreenAnimator::makeBrandonFaceMouse()"); Common::Point mouse = _vm->getMousePos(); - if (mouse.x >= _vm->_currentCharacter->x1) { + if (mouse.x >= _vm->_currentCharacter->x1) _vm->_currentCharacter->facing = 3; - } else { + else _vm->_currentCharacter->facing = 5; - } animRefreshNPC(0); updateAllObjectShapes(); } @@ -625,14 +610,13 @@ void ScreenAnimator::animRefreshNPC(int character) { animObj->refreshFlag = 1; animObj->bkgdChangeFlag = 1; int facing = ch->facing; - if (facing >= 1 && facing <= 3) { + if (facing >= 1 && facing <= 3) animObj->flags |= 1; - } else if (facing >= 5 && facing <= 7) { + else if (facing >= 5 && facing <= 7) animObj->flags &= 0xFFFFFFFE; - } animObj->drawY = ch->y1; - animObj->sceneAnimPtr = _vm->shapes()[4+ch->currentAnimFrame]; + animObj->sceneAnimPtr = _vm->shapes()[ch->currentAnimFrame]; animObj->animFrameNumber = ch->currentAnimFrame; if (character == 0) { if (_vm->brandonStatus() & 10) { @@ -642,12 +626,14 @@ void ScreenAnimator::animRefreshNPC(int character) { if (_vm->brandonStatus() & 2) { animObj->animFrameNumber = _brandonDrawFrame; ch->currentAnimFrame = _brandonDrawFrame; - animObj->sceneAnimPtr = _vm->shapes()[4+_brandonDrawFrame]; + animObj->sceneAnimPtr = _vm->shapes()[_brandonDrawFrame]; if (_vm->_brandonStatusBit0x02Flag) { ++_brandonDrawFrame; - if (_brandonDrawFrame >= 122) + // TODO: check this + if (_brandonDrawFrame >= 122) { _brandonDrawFrame = 113; _vm->_brandonStatusBit0x02Flag = 0; + } } } } @@ -695,9 +681,9 @@ void ScreenAnimator::setCharactersHeight() { 44, 42, 47, 38, 35, 40 }; - for (int i = 0; i < 11; ++i) { + for (int i = 0; i < 11; ++i) _vm->characterList()[i].height = initHeightTable[i]; - } } } // end of namespace Kyra + diff --git a/engines/kyra/animator.h b/engines/kyra/animator.h index 2473cc6636..e21a2b52fd 100644 --- a/engines/kyra/animator.h +++ b/engines/kyra/animator.h @@ -109,6 +109,8 @@ protected: AnimObject *_items; AnimObject *_sprites; + uint8 *_actorBkgBackUp[2]; + AnimObject *objectRemoveQueue(AnimObject *queue, AnimObject *rem); AnimObject *objectAddHead(AnimObject *queue, AnimObject *head); AnimObject *objectQueue(AnimObject *queue, AnimObject *add); @@ -124,3 +126,4 @@ protected: } // end of namespace Kyra #endif + diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index 30ec201f27..48f1787ceb 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -119,8 +119,9 @@ bool Debugger::cmd_toggleFlag(int argc, const char **argv) { else _vm->setGameFlag(flag); DebugPrintf("Flag %i is now %i\n", flag, _vm->queryGameFlag(flag)); - } else + } else { DebugPrintf("Syntax: toggleflag <flag>\n"); + } return true; } @@ -129,8 +130,9 @@ bool Debugger::cmd_queryFlag(int argc, const char **argv) { if (argc > 1) { uint flag = atoi(argv[1]); DebugPrintf("Flag %i is %i\n", flag, _vm->queryGameFlag(flag)); - } else + } else { DebugPrintf("Syntax: queryflag <flag>\n"); + } return true; } @@ -148,8 +150,9 @@ bool Debugger::cmd_setTimerCountdown(int argc, const char **argv) { uint countdown = atoi(argv[2]); _vm->setTimerCountdown(timer, countdown); DebugPrintf("Timer %i now has countdown %i\n", timer, _vm->_timers[timer].countdown); - } else + } else { DebugPrintf("Syntax: settimercountdown <timer> <countdown>\n"); + } return true; } @@ -166,9 +169,11 @@ bool Debugger::cmd_giveItem(int argc, const char **argv) { _vm->setMouseItem(item); _vm->_itemInHand = item; - } else + } else { DebugPrintf("Syntax: give <itemid>\n"); + } return true; } } // End of namespace Kyra + diff --git a/engines/kyra/debugger.h b/engines/kyra/debugger.h index 91f90ee3ef..7e1e613433 100644 --- a/engines/kyra/debugger.h +++ b/engines/kyra/debugger.h @@ -53,3 +53,4 @@ protected: } // End of namespace Kyra #endif + diff --git a/engines/kyra/plugin.cpp b/engines/kyra/detection.cpp index 0cd959a51a..3bd1021e5d 100644 --- a/engines/kyra/plugin.cpp +++ b/engines/kyra/detection.cpp @@ -20,8 +20,9 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra2.h" -#include "kyra/kyra3.h" +#include "kyra/kyra_v1.h" +#include "kyra/kyra_v2.h" +#include "kyra/kyra_v3.h" #include "common/config-manager.h" #include "common/advancedDetector.h" @@ -71,9 +72,11 @@ const KYRAGameDescription adGameDescs[] = { { { "kyra1", "Demo", AD_ENTRY1("DEMO1.WSA", "fb722947d94897512b13b50cc84fd648"), Common::EN_ANY, Common::kPlatformPC, Common::ADGF_DEMO }, KYRA1_DEMO_FLAGS }, - { { "kyra2", 0, AD_ENTRY1("FATE.PAK", "28cbad1c5bf06b2d3825ae57d760d032"), Common::UNK_LANG, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA2_CD_FLAGS }, // CD version + { { "kyra2", 0, AD_ENTRY1("FATE.PAK", "28cbad1c5bf06b2d3825ae57d760d032"), Common::EN_ANY, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA2_CD_FLAGS }, // CD version + { { "kyra2", 0, AD_ENTRY1("FATE.PAK", "28cbad1c5bf06b2d3825ae57d760d032"), Common::DE_DEU, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA2_CD_FLAGS }, // CD version + { { "kyra2", 0, AD_ENTRY1("FATE.PAK", "28cbad1c5bf06b2d3825ae57d760d032"), Common::FR_FRA, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA2_CD_FLAGS }, // CD version - { { "kyra2", "Demo", AD_ENTRY1("GENERAL.PAK", "35825783e5b60755fd520360079f9c15"), Common::UNK_LANG, Common::kPlatformPC, Common::ADGF_DEMO }, KYRA2_DEMO_FLAGS }, + { { "kyra2", "Demo", AD_ENTRY1("GENERAL.PAK", "35825783e5b60755fd520360079f9c15"), Common::EN_ANY, Common::kPlatformPC, Common::ADGF_DEMO }, KYRA2_DEMO_FLAGS }, { { "kyra3", 0, AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), Common::EN_ANY, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA3_CD_FLAGS }, { { "kyra3", 0, AD_ENTRY1("ONETIME.PAK", "3833ff312757b8e6147f464cca0a6587"), Common::DE_DEU, Common::kPlatformPC, Common::ADGF_NO_FLAGS }, KYRA3_CD_FLAGS }, @@ -139,17 +142,15 @@ PluginError Engine_KYRA_create(OSystem *syst, Engine **engine) { flags.platform = gd->desc.platform; Common::Platform platform = Common::parsePlatform(ConfMan.get("platform")); - if (platform != Common::kPlatformUnknown) { + if (platform != Common::kPlatformUnknown) flags.platform = platform; - } if (flags.lang == Common::UNK_LANG) { Common::Language lang = Common::parseLanguage(ConfMan.get("language")); - if (lang != Common::UNK_LANG) { + if (lang != Common::UNK_LANG) flags.lang = lang; - } else { + else flags.lang = Common::EN_ANY; - } } if (!scumm_stricmp("kyra1", gameid)) { @@ -165,3 +166,4 @@ PluginError Engine_KYRA_create(OSystem *syst, Engine **engine) { } REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine", "The Legend of Kyrandia (C) Westwood Studios"); + diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index c9b8b045c2..7d6a881ba0 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -130,9 +130,8 @@ void KyraEngine::writeSettings() { void KyraEngine::initMainButtonList() { _haveScrollButtons = false; _buttonList = &_buttonData[0]; - for (int i = 0; _buttonDataListPtr[i]; ++i) { + for (int i = 0; _buttonDataListPtr[i]; ++i) _buttonList = initButton(_buttonList, _buttonDataListPtr[i]); - } } Button *KyraEngine::initButton(Button *list, Button *newButton) { @@ -141,12 +140,13 @@ Button *KyraEngine::initButton(Button *list, Button *newButton) { if (!list) return newButton; Button *cur = list; + while (true) { - if (!cur->nextButton) { + if (!cur->nextButton) break; - } cur = cur->nextButton; } + cur->nextButton = newButton; return list; } @@ -173,7 +173,7 @@ int KyraEngine::buttonInventoryCallback(Button *caller) { snd_playSoundEffect(0x35); _screen->hideMouse(); _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12); - _screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); + _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); setMouseItem(inventoryItem); updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179); _screen->showMouse(); @@ -182,8 +182,8 @@ int KyraEngine::buttonInventoryCallback(Button *caller) { } else { snd_playSoundEffect(0x32); _screen->hideMouse(); - _screen->drawShape(0, _shapes[220+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0); + _screen->setMouseCursor(1, 1, _shapes[0]); updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179); _screen->showMouse(); _currentCharacter->inventoryItems[itemOffset] = _itemInHand; @@ -231,9 +231,8 @@ int KyraEngine::buttonAmuletCallback(Button *caller) { _scriptClick->variables[6] = jewel; _scriptInterpreter->startScript(_scriptClick, 4); - while (_scriptInterpreter->validScript(_scriptClick)) { + while (_scriptInterpreter->validScript(_scriptClick)) _scriptInterpreter->runScript(_scriptClick); - } if (_scriptClick->variables[3]) return 1; @@ -376,43 +375,37 @@ void KyraEngine::processButton(Button *button) { int flags = (button->flags2 & 5); if (flags == 1) { processType = button->process2; - if (processType == 1) { + if (processType == 1) shape = button->process2PtrShape; - } else if (processType == 4) { + else if (processType == 4) callback = button->process2PtrCallback; - } } else if (flags == 4 || flags == 5) { processType = button->process1; - if (processType == 1) { + if (processType == 1) shape = button->process1PtrShape; - } else if (processType == 4) { + else if (processType == 4) callback = button->process1PtrCallback; - } } else { processType = button->process0; - if (processType == 1) { + if (processType == 1) shape = button->process0PtrShape; - } else if (processType == 4) { + else if (processType == 4) callback = button->process0PtrCallback; - } } int x = button->x; int y = button->y; assert(button->dimTableIndex < _screen->_screenDimTableCount); - if (x < 0) { + if (x < 0) x += _screen->_screenDimTable[button->dimTableIndex].w << 3; - } - if (y < 0) { + if (y < 0) y += _screen->_screenDimTable[button->dimTableIndex].h; - } - if (processType == 1 && shape) { + if (processType == 1 && shape) _screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10); - } else if (processType == 4 && callback) { + else if (processType == 4 && callback) (this->*callback)(button); - } } void KyraEngine::processAllMenuButtons() { @@ -421,9 +414,8 @@ void KyraEngine::processAllMenuButtons() { Button *cur = _menuButtonList; while (true) { - if (!cur->nextButton) { + if (!cur->nextButton) break; - } processMenuButton(cur); cur = cur->nextButton; } @@ -434,7 +426,7 @@ void KyraEngine::processMenuButton(Button *button) { if (!_displayMenu) return; - if ( !button || (button->flags & 8)) + if (!button || (button->flags & 8)) return; if (button->flags2 & 1) @@ -466,7 +458,6 @@ int KyraEngine::drawBoxCallback(Button *button) { } int KyraEngine::drawShadedBoxCallback(Button *button) { - if (!_displayMenu) return 0; @@ -487,13 +478,12 @@ void KyraEngine::setGUILabels() { int menuLabelGarbageOffset = 0; if (_flags.isTalkie) { - if (_flags.lang == Common::EN_ANY) { + if (_flags.lang == Common::EN_ANY) offset = 52; - } else if (_flags.lang == Common::DE_DEU) { + else if (_flags.lang == Common::DE_DEU) offset = 30; - } else if (_flags.lang == Common::FR_FRA) { + else if (_flags.lang == Common::FR_FRA) offset = 6; - } offsetOn = offsetMainMenu = offsetOptions = offset; walkspeedGarbageOffset = 48; } else if (_flags.lang == Common::ES_ESP) { @@ -558,10 +548,10 @@ void KyraEngine::setGUILabels() { // Main Menu _menu[5].item[5].itemString = &_guiStrings[19 + offsetMainMenu][menuLabelGarbageOffset]; - if (_flags.isTalkie) { + if (_flags.isTalkie) // Text & Voice _voiceTextString = _guiStrings[28 + offset]; - } + _textSpeedString = _guiStrings[25 + offsetOptions]; _onString = _guiStrings[20 + offsetOn]; _offString = _guiStrings[21 + offset]; @@ -607,9 +597,9 @@ int KyraEngine::buttonMenuCallback(Button *caller) { _mousePressFlag = false; _toplevelMenu = 0; - if (_menuDirectlyToLoad) + if (_menuDirectlyToLoad) { gui_loadGameMenu(0); - else { + } else { if (!caller) _toplevelMenu = 4; @@ -627,9 +617,9 @@ int KyraEngine::buttonMenuCallback(Button *caller) { gui_restorePalette(); _screen->loadPageFromDisk("SEENPAGE.TMP", 0); _animator->_updateScreen = true; - } - else + } else { _screen->deletePageFromDisk(0); + } return 0; } @@ -663,7 +653,6 @@ void KyraEngine::initMenu(Menu &menu) { if (!menu.item[i].enabled) continue; - x1 = menu.x + menu.item[i].x; y1 = menu.y + menu.item[i].y; @@ -726,8 +715,9 @@ void KyraEngine::initMenu(Menu &menu) { _scrollDownButton.nextButton = 0; _menuButtonList = initButton(_menuButtonList, &_scrollDownButton); processMenuButton(&_scrollDownButton); - } else + } else { _haveScrollButtons = false; + } _screen->showMouse(); _screen->updateScreen(); @@ -867,11 +857,10 @@ int KyraEngine::getNextSavegameSlot() { Common::InSaveFile *in; for (int i = 1; i < 1000; i++) { - if ((in = _saveFileMan->openForLoading(getSavegameFilename(i)))) { + if ((in = _saveFileMan->openForLoading(getSavegameFilename(i)))) delete in; - } else { + else return i; - } } warning("Didn't save: Ran out of savegame filenames"); return 0; @@ -888,8 +877,9 @@ void KyraEngine::setupSavegames(Menu &menu, int num) { menu.item[0].enabled = 1; menu.item[0].field_1b = 0; startSlot = 1; - } else + } else { startSlot = 0; + } for (int i = startSlot; i < num; i++) { if ((in = _saveFileMan->openForLoading(getSavegameFilename(i + _savegameOffset)))) { @@ -949,9 +939,9 @@ int KyraEngine::gui_saveGameMenu(Button *button) { int KyraEngine::gui_loadGameMenu(Button *button) { debugC(9, kDebugLevelGUI, "KyraEngine::gui_loadGameMenu()"); - if (_menuDirectlyToLoad) + if (_menuDirectlyToLoad) { _menu[2].item[5].enabled = false; - else { + } else { processMenuButton(button); _menu[2].item[5].enabled = true; } @@ -1109,9 +1099,9 @@ int KyraEngine::gui_quitPlaying(Button *button) { debugC(9, kDebugLevelGUI, "KyraEngine::gui_quitPlaying()"); processMenuButton(button); - if (gui_quitConfirm(_guiStrings[14])) // Are you sure you want to quit playing? + if (gui_quitConfirm(_guiStrings[14])) { // Are you sure you want to quit playing? quitGame(); - else { + } else { initMenu(_menu[_toplevelMenu]); processAllMenuButtons(); } @@ -1455,9 +1445,8 @@ void KyraEngine::gui_fadePalette() { memcpy(_screen->getPalette(2), _screen->_currentPalette, 768); - for (int i = 0; i < 768; i++) { - _screen->_currentPalette[i] /= 2; - } + for (int i = 0; i < 768; i++) + _screen->_currentPalette[i] >>= 1; while (menuPalIndexes[index] != -1) { memcpy(&_screen->_currentPalette[menuPalIndexes[index]*3], &_screen->getPalette(2)[menuPalIndexes[index]*3], 3); @@ -1600,9 +1589,8 @@ void KyraEngine::gui_drawMainBox(int x, int y, int w, int h, int fill) { --w; --h; - if (fill) { + if (fill) _screen->fillRect(x, y, x+w, y+h, colorTable[0]); - } _screen->drawClippedLine(x, y+h, x+w, y+h, colorTable[1]); _screen->drawClippedLine(x+w, y, x+w, y+h, colorTable[1]); @@ -1624,13 +1612,11 @@ void KyraEngine::gui_printString(const char *format, int x, int y, int col1, int vsprintf(string, format, vaList); va_end(vaList); - if (flags & 1) { + if (flags & 1) x -= _screen->getTextWidth(string) >> 1; - } - if (flags & 2) { + if (flags & 2) x -= _screen->getTextWidth(string); - } if (flags & 4) { _screen->printText(string, x - 1, y, 240, col2); diff --git a/engines/kyra/items.cpp b/engines/kyra/items.cpp index 21d263446c..9e0330583d 100644 --- a/engines/kyra/items.cpp +++ b/engines/kyra/items.cpp @@ -148,9 +148,8 @@ void KyraEngine::placeItemInGenericMapScene(int item, int index) { break; case 51: - if (room != 46) { + if (room != 46) placeItem = true; - } break; default: @@ -159,11 +158,10 @@ void KyraEngine::placeItemInGenericMapScene(int item, int index) { if (placeItem) { Room *roomPtr = &_roomTable[room]; - if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) { + if (roomPtr->northExit == 0xFFFF && roomPtr->eastExit == 0xFFFF && roomPtr->southExit == 0xFFFF && roomPtr->westExit == 0xFFFF) placeItem = false; - } else if (_currentCharacter->sceneId == room) { + else if (_currentCharacter->sceneId == room) placeItem = false; - } } if (placeItem) { @@ -185,18 +183,17 @@ void KyraEngine::createMouseItem(int item) { void KyraEngine::destroyMouseItem() { debugC(9, kDebugLevelMain, "KyraEngine::destroyMouseItem()"); _screen->hideMouse(); - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->setMouseCursor(1, 1, _shapes[0]); _itemInHand = -1; _screen->showMouse(); } void KyraEngine::setMouseItem(int item) { debugC(9, kDebugLevelMain, "KyraEngine::setMouseItem(%d)", item); - if (item == -1) { - _screen->setMouseCursor(1, 1, _shapes[10]); - } else { - _screen->setMouseCursor(8, 15, _shapes[220+item]); - } + if (item == -1) + _screen->setMouseCursor(1, 1, _shapes[6]); + else + _screen->setMouseCursor(8, 15, _shapes[216+item]); } void KyraEngine::wipeDownMouseItem(int xpos, int ypos) { @@ -206,22 +203,22 @@ void KyraEngine::wipeDownMouseItem(int xpos, int ypos) { xpos -= 8; ypos -= 15; _screen->hideMouse(); - _screen->backUpRect1(xpos, ypos); + backUpItemRect1(xpos, ypos); int y = ypos; int height = 16; while (height >= 0) { - _screen->restoreRect1(xpos, ypos); - _screen->setNewShapeHeight(_shapes[220+_itemInHand], height); + restoreItemRect1(xpos, ypos); + _screen->setNewShapeHeight(_shapes[216+_itemInHand], height); uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, _shapes[220+_itemInHand], xpos, y, 0, 0); + _screen->drawShape(0, _shapes[216+_itemInHand], xpos, y, 0, 0); _screen->updateScreen(); y += 2; height -= 2; delayUntil(nextTime); } - _screen->restoreRect1(xpos, ypos); - _screen->resetShapeHeight(_shapes[220+_itemInHand]); + restoreItemRect1(xpos, ypos); + _screen->resetShapeHeight(_shapes[216+_itemInHand]); destroyMouseItem(); _screen->showMouse(); } @@ -233,9 +230,8 @@ void KyraEngine::setupSceneItems() { Room *currentRoom = &_roomTable[sceneId]; for (int i = 0; i < 12; ++i) { uint8 item = currentRoom->itemsTable[i]; - if (item == 0xFF || !currentRoom->needInit[i]) { + if (item == 0xFF || !currentRoom->needInit[i]) continue; - } int xpos = 0; int ypos = 0; @@ -256,9 +252,8 @@ void KyraEngine::setupSceneItems() { if (!stop) { xpos = currentRoom->itemsXPos[i] = _rnd.getRandomNumberRng(24, 296); ypos = currentRoom->itemsYPos[i] = _rnd.getRandomNumberRng(_northExitHeight & 0xFF, 130); - if (countItemsInScene(sceneId) >= 12) { + if (countItemsInScene(sceneId) >= 12) break; - } } else { currentRoom->needInit[i] = 0; } @@ -274,9 +269,8 @@ int KyraEngine::countItemsInScene(uint16 sceneId) { int items = 0; for (int i = 0; i < 12; ++i) { - if (currentRoom->itemsTable[i] != 0xFF) { + if (currentRoom->itemsTable[i] != 0xFF) ++items; - } } return items; @@ -286,9 +280,8 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un debugC(9, kDebugLevelMain, "KyraEngine::processItemDrop(%d, %d, %d, %d, %d, %d)", sceneId, item, x, y, unk1, unk2); int freeItem = -1; uint8 itemIndex = findItemAtPos(x, y); - if (unk1) { + if (unk1) itemIndex = 0xFF; - } if (itemIndex != 0xFF) { exchangeItemWithMouseItem(sceneId, itemIndex); @@ -309,9 +302,8 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un freeItem = _lastProcessedItem; } - if (freeItem == -1) { + if (freeItem == -1) return 0; - } if (sceneId != _currentCharacter->sceneId) { addItemToRoom(sceneId, item, freeItem, x, y); @@ -337,21 +329,18 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un bool running2 = true; if (_screen->getDrawLayer(xpos, ypos) > 1) { - if (((_northExitHeight >> 8) & 0xFF) != ypos) { + if (((_northExitHeight >> 8) & 0xFF) != ypos) running2 = false; - } } if (_screen->getDrawLayer2(xpos, ypos, itemHeight) > 1) { - if (((_northExitHeight >> 8) & 0xFF) != ypos) { + if (((_northExitHeight >> 8) & 0xFF) != ypos) running2 = false; - } } if (!isDropable(xpos, ypos)) { - if (((_northExitHeight >> 8) & 0xFF) != ypos) { + if (((_northExitHeight >> 8) & 0xFF) != ypos) running2 = false; - } } int xpos2 = xpos; @@ -384,14 +373,12 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un continue; xpos2 -= 2; - if (xpos2 < 16) { + if (xpos2 < 16) xpos2 = 16; - } xpos3 += 2; - if (xpos3 > 304) { + if (xpos3 > 304) xpos3 = 304; - } if (xpos2 > 16) continue; @@ -405,23 +392,20 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un running = 0; destY -= _rnd.getRandomNumberRng(0, 3); - if ((_northExitHeight & 0xFF) < destY) { + if ((_northExitHeight & 0xFF) < destY) continue; - } destY = (_northExitHeight & 0xFF) + 1; continue; } ypos += 2; - if (((_northExitHeight >> 8) & 0xFF) >= ypos) { + if (((_northExitHeight >> 8) & 0xFF) >= ypos) continue; - } ypos = (_northExitHeight >> 8) & 0xFF; } - if (destX == -1 || destY == -1) { + if (destX == -1 || destY == -1) return 0; - } if (unk1 == 3) { currentRoom->itemsXPos[freeItem] = destX; @@ -429,13 +413,11 @@ int KyraEngine::processItemDrop(uint16 sceneId, uint8 item, int x, int y, int un return 1; } - if (unk1 == 2) { + if (unk1 == 2) itemSpecialFX(x, y, item); - } - if (unk1 == 0) { + if (unk1 == 0) destroyMouseItem(); - } itemDropDown(x, y, destX, destY, freeItem, item); @@ -479,17 +461,14 @@ void KyraEngine::addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int KyraEngine::checkNoDropRects(int x, int y) { debugC(9, kDebugLevelMain, "KyraEngine::checkNoDropRects(%d, %d)", x, y); - if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) { + if (_lastProcessedItemHeight < 1 || _lastProcessedItemHeight > 16) _lastProcessedItemHeight = 16; - } - if (_noDropRects[0].x == -1) { + if (_noDropRects[0].x == -1) return 0; - } for (int i = 0; i < 11; ++i) { - if (_noDropRects[i].x == -1) { + if (_noDropRects[i].x == -1) break; - } int xpos = _noDropRects[i].x; int ypos = _noDropRects[i].y; @@ -515,14 +494,12 @@ int KyraEngine::isDropable(int x, int y) { x -= 8; y -= 1; - if (checkNoDropRects(x, y)) { + if (checkNoDropRects(x, y)) return 0; - } for (int xpos = x; xpos < x + 16; ++xpos) { - if (_screen->getShapeFlag1(xpos, y) == 0) { + if (_screen->getShapeFlag1(xpos, y) == 0) return 0; - } } return 1; } @@ -546,28 +523,26 @@ void KyraEngine::itemDropDown(int x, int y, int destX, int destY, byte freeItem, int drawX = x - 8; int drawY = 0; - _screen->backUpRect0(drawX, y - 16); + backUpItemRect0(drawX, y - 16); while (tempY < destY) { - _screen->restoreRect0(drawX, tempY - 16); + restoreItemRect0(drawX, tempY - 16); tempY += addY; - if (tempY > destY) { + if (tempY > destY) tempY = destY; - } ++addY; drawY = tempY - 16; - _screen->backUpRect0(drawX, drawY); + backUpItemRect0(drawX, drawY); uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, _shapes[220+item], drawX, drawY, 0, 0); + _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } bool skip = false; if (x == destX) { - if (destY - y <= 16) { + if (destY - y <= 16) skip = true; - } } if (!skip) { @@ -579,32 +554,30 @@ void KyraEngine::itemDropDown(int x, int y, int destX, int destY, byte freeItem, xDiff /= addY; int startAddY = addY; addY >>= 1; - if (destY - y <= 8) { + if (destY - y <= 8) addY >>= 1; - } addY = -addY; int unkX = x << 4; while (--startAddY) { drawX = (unkX >> 4) - 8; drawY = tempY - 16; - _screen->restoreRect0(drawX, drawY); + restoreItemRect0(drawX, drawY); tempY += addY; unkX += xDiff; - if (tempY > destY) { + if (tempY > destY) tempY = destY; - } ++addY; drawX = (unkX >> 4) - 8; drawY = tempY - 16; - _screen->backUpRect0(drawX, drawY); + backUpItemRect0(drawX, drawY); uint32 nextTime = _system->getMillis() + 1 * _tickLength; - _screen->drawShape(0, _shapes[220+item], drawX, drawY, 0, 0); + _screen->drawShape(0, _shapes[216+item], drawX, drawY, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } - _screen->restoreRect0(drawX, drawY); + restoreItemRect0(drawX, drawY); } else { - _screen->restoreRect0(drawX, tempY - 16); + restoreItemRect0(drawX, tempY - 16); } } currentRoom->itemsXPos[freeItem] = destX; @@ -620,42 +593,39 @@ void KyraEngine::dropItem(int unk1, int item, int x, int y, int unk2) { if (processItemDrop(_currentCharacter->sceneId, item, x, y, unk1, unk2)) return; snd_playSoundEffect(54); - if (12 == countItemsInScene(_currentCharacter->sceneId)) { - assert(_noDropList); + assert(_noDropList); + if (12 == countItemsInScene(_currentCharacter->sceneId)) drawSentenceCommand(_noDropList[0], 6); - } else { - assert(_noDropList); + else drawSentenceCommand(_noDropList[1], 6); - } } void KyraEngine::itemSpecialFX(int x, int y, int item) { debugC(9, kDebugLevelMain, "KyraEngine::itemSpecialFX(%d, %d, %d)", x, y, item); - if (item == 41) { + if (item == 41) itemSpecialFX1(x, y, item); - } else { + else itemSpecialFX2(x, y, item); - } } void KyraEngine::itemSpecialFX1(int x, int y, int item) { debugC(9, kDebugLevelMain, "KyraEngine::itemSpecialFX1(%d, %d, %d)", x, y, item); - uint8 *shape = _shapes[220+item]; + uint8 *shape = _shapes[216+item]; x -= 8; int startY = y; y -= 15; _screen->hideMouse(); - _screen->backUpRect0(x, y); + backUpItemRect0(x, y); for (int i = 1; i <= 16; ++i) { _screen->setNewShapeHeight(shape, i); --startY; - _screen->restoreRect0(x, y); + restoreItemRect0(x, y); uint32 nextTime = _system->getMillis() + 1 * _tickLength; _screen->drawShape(0, shape, x, startY, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } - _screen->restoreRect0(x, y); + restoreItemRect0(x, y); _screen->showMouse(); } @@ -664,28 +634,27 @@ void KyraEngine::itemSpecialFX2(int x, int y, int item) { x -= 8; y -= 15; int yAdd = (int8)(((16 - _itemTable[item].height) >> 1) & 0xFF); - _screen->backUpRect0(x, y); - if (item >= 80 && item <= 89) { + backUpItemRect0(x, y); + if (item >= 80 && item <= 89) snd_playSoundEffect(55); - } for (int i = 201; i <= 205; ++i) { - _screen->restoreRect0(x, y); + restoreItemRect0(x, y); uint32 nextTime = _system->getMillis() + 3 * _tickLength; - _screen->drawShape(0, _shapes[4+i], x, y + yAdd, 0, 0); + _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } for (int i = 204; i >= 201; --i) { - _screen->restoreRect0(x, y); + restoreItemRect0(x, y); uint32 nextTime = _system->getMillis() + 3 * _tickLength; - _screen->drawShape(0, _shapes[220+item], x, y, 0, 0); - _screen->drawShape(0, _shapes[4+i], x, y + yAdd, 0, 0); + _screen->drawShape(0, _shapes[216+item], x, y, 0, 0); + _screen->drawShape(0, _shapes[i], x, y + yAdd, 0, 0); _screen->updateScreen(); delayUntil(nextTime); } - _screen->restoreRect0(x, y); + restoreItemRect0(x, y); } void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) { @@ -702,9 +671,8 @@ void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) { y = _itemPosY[itemPos] - 3; } - if (_itemInHand == -1 && itemPos == -1) { + if (_itemInHand == -1 && itemPos == -1) return; - } int tableIndex = 0, loopStart = 0, maxLoops = 0; if (animIndex == 0) { @@ -723,48 +691,45 @@ void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) { tableIndex = -1; } - if (animIndex == 2) { + if (animIndex == 2) snd_playSoundEffect(0x5E); - } else { + else snd_playSoundEffect(0x37); - } _screen->hideMouse(); - _screen->backUpRect1(x, y); + backUpItemRect1(x, y); for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; - _screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0); - if (tableIndex == -1) { - _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0); - } else { + _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - } _screen->updateScreen(); delayUntil(nextTime); } if (itemPos != -1) { - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0); - _screen->backUpRect1(x, y); + backUpItemRect1(x, y); } for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; - _screen->drawShape(0, _shapes[220+_itemInHand], x + 4, y + 3, 0, 0); - if (tableIndex == -1) { - _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0); - } else { + _screen->drawShape(0, _shapes[216+_itemInHand], x + 4, y + 3, 0, 0); + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - } _screen->updateScreen(); delayUntil(nextTime); } - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); if (itemPos == -1) { - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->setMouseCursor(1, 1, _shapes[0]); _itemInHand = -1; } else { _characterList[0].inventoryItems[itemPos] = 0xFF; @@ -808,44 +773,41 @@ void KyraEngine::magicInMouseItem(int animIndex, int item, int itemPos) { } _screen->hideMouse(); - _screen->backUpRect1(x, y); - if (animIndex == 2) { + backUpItemRect1(x, y); + if (animIndex == 2) snd_playSoundEffect(0x5E); - } else { + else snd_playSoundEffect(0x37); - } for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) { - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; - if (tableIndex == -1) { - _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0); - } else { + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - } _screen->updateScreen(); delayUntil(nextTime); } for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) { - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); uint32 nextTime = _system->getMillis() + 4 * _tickLength; - if (tableIndex == -1) { - _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0); - } else { + if (tableIndex == -1) + _screen->drawShape(0, _shapes[shape], x, y, 0, 0); + else specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops); - } _screen->updateScreen(); delayUntil(nextTime); } - _screen->restoreRect1(x, y); + restoreItemRect1(x, y); if (itemPos == -1) { - _screen->setMouseCursor(8, 15, _shapes[220+item]); + _screen->setMouseCursor(8, 15, _shapes[216+item]); _itemInHand = item; } else { _characterList[0].inventoryItems[itemPos] = item; _screen->hideMouse(); - _screen->drawShape(0, _shapes[220+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0); + _screen->drawShape(0, _shapes[216+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0); _screen->showMouse(); } _screen->showMouse(); @@ -864,35 +826,34 @@ void KyraEngine::specialMouseItemFX(int shape, int x, int y, int animIndex, int 0x7C, 0xD0, 0x74, 0x84, 0x87, 0x00, 0x00, 0x00 }; int tableValue = 0; - if (animIndex == 0) { + if (animIndex == 0) tableValue = table1[tableIndex]; - } else if (animIndex == 1) { + else if (animIndex == 1) tableValue = table2[tableIndex]; - } else if (animIndex == 2) { + else if (animIndex == 2) tableValue = table3[tableIndex]; - } else { + else return; - } processSpecialMouseItemFX(shape, x, y, tableValue, loopStart, maxLoops); } void KyraEngine::processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops) { debugC(9, kDebugLevelMain, "KyraEngine::processSpecialMouseItemFX(%d, %d, %d, %d, %d, %d)", shape, x, y, tableValue, loopStart, maxLoops); uint8 shapeColorTable[16]; - uint8 *shapePtr = _shapes[4+shape] + 10; + uint8 *shapePtr = _shapes[shape] + 10; if (_flags.useAltShapeHeader) shapePtr += 2; - for (int i = 0; i < 16; ++i) { + + for (int i = 0; i < 16; ++i) shapeColorTable[i] = shapePtr[i]; - } + for (int i = loopStart; i < loopStart + maxLoops; ++i) { for (int i2 = 0; i2 < 16; ++i2) { - if (shapePtr[i2] == i) { + if (shapePtr[i2] == i) shapeColorTable[i2] = (i + tableValue) - loopStart; - } } } - _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0x8000, shapeColorTable); + _screen->drawShape(0, _shapes[shape], x, y, 0, 0x8000, shapeColorTable); } void KyraEngine::updatePlayerItemsForScene() { @@ -902,7 +863,7 @@ void KyraEngine::updatePlayerItemsForScene() { if (_itemInHand > 33) _itemInHand = 33; _screen->hideMouse(); - _screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]); + _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); _screen->showMouse(); } @@ -924,16 +885,14 @@ void KyraEngine::updatePlayerItemsForScene() { _screen->showMouse(); } - if (_itemInHand == 33) { + if (_itemInHand == 33) magicOutMouseItem(2, -1); - } _screen->hideMouse(); for (int i = 0; i < 10; ++i) { uint8 item = _currentCharacter->inventoryItems[i]; - if (item == 33) { + if (item == 33) magicOutMouseItem(2, i); - } } _screen->showMouse(); } @@ -946,7 +905,7 @@ void KyraEngine::redrawInventory(int page) { _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page); if (_currentCharacter->inventoryItems[i] != 0xFF) { uint8 item = _currentCharacter->inventoryItems[i]; - _screen->drawShape(page, _shapes[220+item], _itemPosX[i], _itemPosY[i], 0, 0); + _screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0); } } _screen->showMouse(); @@ -954,4 +913,29 @@ void KyraEngine::redrawInventory(int page) { _screen->updateScreen(); } +void KyraEngine::backUpItemRect0(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine::backUpItemRect0(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 3<<3, 24); + _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); +} + +void KyraEngine::restoreItemRect0(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine::restoreItemRect0(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 3<<3, 24); + _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 3<<3, 24, _itemBkgBackUp[0]); +} + +void KyraEngine::backUpItemRect1(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine::backUpItemRect1(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 4<<3, 32); + _screen->copyRegionToBuffer(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); +} + +void KyraEngine::restoreItemRect1(int xpos, int ypos) { + debugC(9, kDebugLevelMain, "KyraEngine::restoreItemRect1(%d, %d)", xpos, ypos); + _screen->rectClip(xpos, ypos, 4<<3, 32); + _screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]); +} + } // end of namespace Kyra + diff --git a/engines/kyra/kyra.cpp b/engines/kyra/kyra.cpp index aba461a231..fd3b32c2f8 100644 --- a/engines/kyra/kyra.cpp +++ b/engines/kyra/kyra.cpp @@ -49,10 +49,6 @@ namespace Kyra { KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags) : Engine(system) { - setupOpcodeTable(); - setupButtonData(); - setupMenu(); - _flags = flags; _seq_Forest = _seq_KallakWriting = _seq_KyrandiaLogo = _seq_KallakMalcolm = @@ -124,15 +120,10 @@ KyraEngine::KyraEngine(OSystem *system, const GameFlags &flags) Common::addSpecialDebugLevel(kDebugLevelMovie, "Movie", "Movie debug level"); } -KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) - : KyraEngine(system, flags) { -} - int KyraEngine::init() { // Setup mixer - if (!_mixer->isReady()) { + if (!_mixer->isReady()) warning("Sound initialization failed."); - } _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); @@ -161,9 +152,8 @@ int KyraEngine::init() { MidiDriver *driver = MidiDriver::createMidi(midiDriver); assert(driver); - if (native_mt32) { + if (native_mt32) driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE); - } SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver); _sound = soundMidiPc; @@ -217,14 +207,19 @@ int KyraEngine::init() { _sound->setVolume(255); _sound->loadSoundFile(0); + setupOpcodeTable(); + setupButtonData(); + setupMenu(); + _paletteChanged = 1; _currentCharacter = 0; _characterList = new Character[11]; assert(_characterList); - for (int i = 0; i < 11; ++i) { - memset(&_characterList[i], 0, sizeof(Character)); + memset(_characterList, 0, sizeof(Character)*11); + + for (int i = 0; i < 11; ++i) memset(_characterList[i].inventoryItems, 0xFF, sizeof(_characterList[i].inventoryItems)); - } + _characterList[0].sceneId = 5; _characterList[0].height = 48; _characterList[0].facing = 3; @@ -255,9 +250,8 @@ int KyraEngine::init() { assert(_debugger); memset(_shapes, 0, sizeof(_shapes)); - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) _movieObjects[i] = createWSAMovie(); - } memset(_flagsTable, 0, sizeof(_flagsTable)); @@ -405,7 +399,10 @@ KyraEngine::~KyraEngine() { delete [] _scrollDownButton.process0PtrShape; delete [] _scrollDownButton.process1PtrShape; delete [] _scrollDownButton.process2PtrShape; - + + delete [] _itemBkgBackUp[0]; + delete [] _itemBkgBackUp[1]; + for (int i = 0; i < ARRAYSIZE(_shapes); ++i) { if (_shapes[i] != 0) { delete [] _shapes[i]; @@ -417,20 +414,14 @@ KyraEngine::~KyraEngine() { _shapes[i] = 0; } } - for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) { - delete [] _sceneAnimTable[i]; - } -} - -KyraEngine_v1::~KyraEngine_v1() { + for (int i = 0; i < ARRAYSIZE(_sceneAnimTable); ++i) + delete [] _sceneAnimTable[i]; } int KyraEngine::go() { - - if (_res->getFileSize("6.FNT")) { + if (_res->getFileSize("6.FNT")) _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); - } _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); _screen->setScreenDim(0); @@ -472,18 +463,16 @@ void KyraEngine::startup() { resetBrandonPoisonFlags(); _screen->_curPage = 0; // XXX - for (int i = 0; i < 0x0C; ++i) { + for (int i = 0; i < 12; ++i) { int size = _screen->getRectSize(3, 24); - _shapes[365+i] = new byte[size]; + _shapes[361+i] = new byte[size]; } - _shapes[0] = new uint8[_screen->getRectSize(3, 24)]; - memset(_shapes[0], 0, _screen->getRectSize(3, 24)); - _shapes[1] = new uint8[_screen->getRectSize(4, 32)]; - memset(_shapes[1], 0, _screen->getRectSize(4, 32)); - _shapes[2] = new uint8[_screen->getRectSize(8, 69)]; - memset(_shapes[2], 0, _screen->getRectSize(8, 69)); - _shapes[3] = new uint8[_screen->getRectSize(8, 69)]; - memset(_shapes[3], 0, _screen->getRectSize(8, 69)); + + _itemBkgBackUp[0] = new uint8[_screen->getRectSize(3, 24)]; + memset(_itemBkgBackUp[0], 0, _screen->getRectSize(3, 24)); + _itemBkgBackUp[1] = new uint8[_screen->getRectSize(4, 32)]; + memset(_itemBkgBackUp[1], 0, _screen->getRectSize(4, 32)); + for (int i = 0; i < _roomTableSize; ++i) { for (int item = 0; item < 12; ++item) { _roomTable[i].itemsTable[item] = 0xFF; @@ -492,6 +481,7 @@ void KyraEngine::startup() { _roomTable[i].needInit[item] = 0; } } + loadCharacterShapes(); loadSpecialEffectShapes(); loadItems(); @@ -505,28 +495,27 @@ void KyraEngine::startup() { _animator->initAnimStateList(); setCharactersInDefaultScene(); - if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, 0)) { + if (!_scriptInterpreter->loadScript("_STARTUP.EMC", _npcScriptData, &_opcodes)) error("Could not load \"_STARTUP.EMC\" script"); - } _scriptInterpreter->initScript(_scriptMain, _npcScriptData); - if (!_scriptInterpreter->startScript(_scriptMain, 0)) { + + if (!_scriptInterpreter->startScript(_scriptMain, 0)) error("Could not start script function 0 of script \"_STARTUP.EMC\""); - } - while (_scriptInterpreter->validScript(_scriptMain)) { + + while (_scriptInterpreter->validScript(_scriptMain)) _scriptInterpreter->runScript(_scriptMain); - } _scriptInterpreter->unloadScript(_npcScriptData); - if (!_scriptInterpreter->loadScript("_NPC.EMC", _npcScriptData, 0)) { + + if (!_scriptInterpreter->loadScript("_NPC.EMC", _npcScriptData, &_opcodes)) error("Could not load \"_NPC.EMC\" script"); - } snd_playTheme(1); enterNewScene(_currentCharacter->sceneId, _currentCharacter->facing, 0, 0, 1); if (_abortIntroFlag && _skipIntroFlag) { _menuDirectlyToLoad = true; - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->setMouseCursor(1, 1, _shapes[0]); _screen->showMouse(); buttonMenuCallback(0); _menuDirectlyToLoad = false; @@ -543,32 +532,27 @@ void KyraEngine::mainLoop() { if (_currentCharacter->sceneId == 210) { updateKyragemFading(); - if (seq_playEnd()) { - if (_deathHandler != 8) - break; - } + if (seq_playEnd() && _deathHandler != 8) + break; } if (_deathHandler != 0xFF) { snd_playWanderScoreViaMap(0, 1); snd_playSoundEffect(49); _screen->hideMouse(); - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->setMouseCursor(1, 1, _shapes[0]); destroyMouseItem(); _screen->showMouse(); buttonMenuCallback(0); _deathHandler = 0xFF; } - if (_brandonStatusBit & 2) { - if (_brandonStatusBit0x02Flag) - _animator->animRefreshNPC(0); - } - if (_brandonStatusBit & 0x20) { - if (_brandonStatusBit0x20Flag) { - _animator->animRefreshNPC(0); - _brandonStatusBit0x20Flag = 0; - } + if ((_brandonStatusBit & 2) && _brandonStatusBit0x02Flag) + _animator->animRefreshNPC(0); + + if ((_brandonStatusBit & 0x20) && _brandonStatusBit0x20Flag) { + _animator->animRefreshNPC(0); + _brandonStatusBit0x20Flag = 0; } _screen->showMouse(); @@ -596,6 +580,7 @@ void KyraEngine::delayUntil(uint32 timestamp, bool updateTimers, bool update, bo while (_system->getMillis() < timestamp && !_quitFlag) { if (updateTimers) updateGameTimers(); + if (timestamp - _system->getMillis() >= 10) delay(10, update, isMainLoop); } @@ -660,6 +645,7 @@ void KyraEngine::delay(uint32 amount, bool update, bool isMainLoop) { break; } } + if (_debugger->isAttached()) _debugger->onFrame(); @@ -670,22 +656,18 @@ void KyraEngine::delay(uint32 amount, bool update, bool isMainLoop) { updateMousePointer(); } - if (_currentCharacter && _currentCharacter->sceneId == 210 && update) { + if (_currentCharacter && _currentCharacter->sceneId == 210 && update) updateKyragemFading(); - } if (_skipFlag && !_abortIntroFlag && !queryGameFlag(0xFE)) _skipFlag = false; - if (amount > 0 && !_skipFlag && !_quitFlag) { + if (amount > 0 && !_skipFlag && !_quitFlag) _system->delayMillis(10); - } - if (_skipFlag) { + if (_skipFlag) _sound->voiceStop(); - } } while (!_skipFlag && _system->getMillis() < start + amount && !_quitFlag); - } Common::Point KyraEngine::getMousePos() const { @@ -700,6 +682,7 @@ Common::Point KyraEngine::getMousePos() const { void KyraEngine::waitForEvent() { bool finished = false; Common::Event event; + while (!finished && !_quitFlag) { while (_eventMan->pollEvent(event)) { switch (event.type) { @@ -727,15 +710,19 @@ void KyraEngine::waitForEvent() { void KyraEngine::delayWithTicks(int ticks) { uint32 nextTime = _system->getMillis() + ticks * _tickLength; + while (_system->getMillis() < nextTime) { _sprites->updateSceneAnims(); _animator->updateAllObjectShapes(); + if (_currentCharacter->sceneId == 210) { updateKyragemFading(); seq_playEnd(); } + if (_skipFlag) break; + if (nextTime - _system->getMillis() >= 10) delay(10); } @@ -747,9 +734,10 @@ void KyraEngine::delayWithTicks(int ticks) { void KyraEngine::setupShapes123(const Shape *shapeTable, int endShape, int flags) { debugC(9, kDebugLevelMain, "KyraEngine::setupShapes123(%p, %d, %d)", (const void *)shapeTable, endShape, flags); - for (int i = 123; i <= 172; ++i) { - _shapes[4+i] = NULL; - } + + for (int i = 123; i <= 172; ++i) + _shapes[i] = 0; + uint8 curImage = 0xFF; int curPageBackUp = _screen->_curPage; _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff @@ -763,7 +751,7 @@ void KyraEngine::setupShapes123(const Shape *shapeTable, int endShape, int flags _screen->loadBitmap(_characterImageTable[newImage], 8, 8, 0); curImage = newImage; } - _shapes[4+i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); + _shapes[i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, shapeFlags); assert(i-7 < _defaultShapeTableSize); _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset; _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset; @@ -775,9 +763,10 @@ void KyraEngine::setupShapes123(const Shape *shapeTable, int endShape, int flags void KyraEngine::freeShapes123() { debugC(9, kDebugLevelMain, "KyraEngine::freeShapes123()"); + for (int i = 123; i <= 172; ++i) { - delete [] _shapes[4+i]; - _shapes[4+i] = NULL; + delete [] _shapes[i]; + _shapes[i] = 0; } } @@ -788,6 +777,7 @@ void KyraEngine::freeShapes123() { Movie *KyraEngine::createWSAMovie() { if (_flags.platform == Common::kPlatformAmiga) return new WSAMovieAmiga(this); + return new WSAMovieV1(this); } @@ -808,11 +798,13 @@ int KyraEngine::resetGameFlag(int flag) { void KyraEngine::setBrandonPoisonFlags(int reset) { debugC(9, kDebugLevelMain, "KyraEngine::setBrandonPoisonFlags(%d)", reset); _brandonStatusBit |= 1; + if (reset) _poisonDeathCounter = 0; - for (int i = 0; i < 0x100; ++i) { + + for (int i = 0; i < 0x100; ++i) _brandonPoisonFlagsGFX[i] = i; - } + _brandonPoisonFlagsGFX[0x99] = 0x34; _brandonPoisonFlagsGFX[0x9A] = 0x35; _brandonPoisonFlagsGFX[0x9B] = 0x37; @@ -823,9 +815,9 @@ void KyraEngine::setBrandonPoisonFlags(int reset) { void KyraEngine::resetBrandonPoisonFlags() { debugC(9, kDebugLevelMain, "KyraEngine::resetBrandonPoisonFlags()"); _brandonStatusBit = 0; - for (int i = 0; i < 0x100; ++i) { + + for (int i = 0; i < 0x100; ++i) _brandonPoisonFlagsGFX[i] = i; - } } #pragma mark - @@ -840,9 +832,9 @@ void KyraEngine::processInput() { debugC(9, kDebugLevelMain, "KyraEngine::processInput(%d, %d)", xpos, ypos); _abortWalkFlag2 = false; - if (processInputHelper(xpos, ypos)) { + if (processInputHelper(xpos, ypos)) return; - } + uint8 item = findItemAtPos(xpos, ypos); if (item == 0xFF) { _changedScene = false; @@ -932,9 +924,8 @@ int KyraEngine::clickEventHandler(int xpos, int ypos) { _scriptClick->variables[4] = _itemInHand; _scriptInterpreter->startScript(_scriptClick, 1); - while (_scriptInterpreter->validScript(_scriptClick)) { + while (_scriptInterpreter->validScript(_scriptClick)) _scriptInterpreter->runScript(_scriptClick); - } return _scriptClick->variables[3]; } @@ -1032,7 +1023,7 @@ void KyraEngine::updateMousePointer(bool forceUpdate) { if ((newMouseState && _mouseState != newMouseState) || (newMouseState && forceUpdate)) { _mouseState = newMouseState; _screen->hideMouse(); - _screen->setMouseCursor(newX, newY, _shapes[4+shape]); + _screen->setMouseCursor(newX, newY, _shapes[shape]); _screen->showMouse(); } @@ -1042,9 +1033,9 @@ void KyraEngine::updateMousePointer(bool forceUpdate) { _mouseState = _itemInHand; _screen->hideMouse(); if (_itemInHand == -1) { - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->setMouseCursor(1, 1, _shapes[0]); } else { - _screen->setMouseCursor(8, 15, _shapes[220+_itemInHand]); + _screen->setMouseCursor(8, 15, _shapes[216+_itemInHand]); } _screen->showMouse(); } @@ -1054,14 +1045,15 @@ void KyraEngine::updateMousePointer(bool forceUpdate) { bool KyraEngine::hasClickedOnExit(int xpos, int ypos) { debugC(9, kDebugLevelMain, "KyraEngine::hasClickedOnExit(%d, %d)", xpos, ypos); - if (xpos < 16 || xpos >= 304) { + if (xpos < 16 || xpos >= 304) return true; - } + if (ypos < 8) return true; - if (ypos < 136 || ypos > 155) { + + if (ypos < 136 || ypos > 155) return false; - } + return true; } @@ -1077,9 +1069,8 @@ void KyraEngine::clickEventHandler2() { _scriptClick->variables[4] = _itemInHand; _scriptInterpreter->startScript(_scriptClick, 6); - while (_scriptInterpreter->validScript(_scriptClick)) { + while (_scriptInterpreter->validScript(_scriptClick)) _scriptInterpreter->runScript(_scriptClick); - } } int KyraEngine::checkForNPCScriptRun(int xpos, int ypos) { @@ -1097,13 +1088,11 @@ int KyraEngine::checkForNPCScriptRun(int xpos, int ypos) { charTop = currentChar->y1 - addY; charBottom = currentChar->y1; - if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) { + if (xpos >= charLeft && charRight >= xpos && charTop <= ypos && charBottom >= ypos) return 0; - } - if (xpos > 304 || xpos < 16) { + if (xpos > 304 || xpos < 16) return -1; - } for (int i = 1; i < 5; ++i) { currentChar = &_characterList[i]; @@ -1120,14 +1109,12 @@ int KyraEngine::checkForNPCScriptRun(int xpos, int ypos) { charBottom = currentChar->y1; // } - if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) { + if (xpos < charLeft || xpos > charRight || ypos < charTop || charBottom < ypos) continue; - } if (returnValue != -1) { - if (currentChar->y1 >= _characterList[returnValue].y1) { + if (currentChar->y1 >= _characterList[returnValue].y1) returnValue = i; - } } else { returnValue = i; } @@ -1144,19 +1131,9 @@ void KyraEngine::runNpcScript(int func) { _npcScript->variables[4] = _itemInHand; _npcScript->variables[5] = func; - while (_scriptInterpreter->validScript(_npcScript)) { + while (_scriptInterpreter->validScript(_npcScript)) _scriptInterpreter->runScript(_npcScript); - } -} - -int KyraEngine::runOpcode(ScriptState *script, uint8 opcode) { - debugC(9, kDebugLevelMain | kDebugLevelScript, "KyraEngine::runOpcode(%p, %d)", (void *)script, opcode); - assert(opcode < _opcodeTableSize); - if (_opcodeTable[opcode] == &KyraEngine::o1_dummy) - warning("calling unimplemented opcode(0x%.02X)", opcode); - int val = (this->*_opcodeTable[opcode])(script); - assert(script); - return val; } } // End of namespace Kyra + diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index d5fb11e44d..fe0067a5b4 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -20,11 +20,12 @@ * */ -#ifndef KYRA_H -#define KYRA_H +#ifndef KYRA_KYRA_H +#define KYRA_KYRA_H #include "engines/engine.h" #include "common/rect.h" +#include "common/array.h" namespace Kyra { @@ -43,6 +44,7 @@ class TextDisplayer; class KyraEngine; class StaticResource; +struct Opcode; struct ScriptState; struct ScriptData; @@ -262,8 +264,8 @@ public: int16 _northExitHeight; typedef void (KyraEngine::*IntroProc)(); - typedef int (KyraEngine::*OpcodeProc)(ScriptState *script); + // static data access const char * const*seqWSATable() { return _seq_WSATable; } const char * const*seqCPSTable() { return _seq_CPSTable; } const char * const*seqCOLTable() { return _seq_COLTable; } @@ -272,9 +274,60 @@ public: const uint8 * const*palTable1() { return &_specialPalettes[0]; } const uint8 * const*palTable2() { return &_specialPalettes[29]; } + // sequences + // -> misc bool seq_skipSequence() const; + +protected: + // -> demo + void seq_demo(); + + // -> intro + void seq_intro(); + void seq_introLogos(); + void seq_introStory(); + void seq_introMalcolmTree(); + void seq_introKallakWriting(); + void seq_introKallakMalcolm(); + + // -> ingame animations + void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); + void seq_brandonHealing(); + void seq_brandonHealing2(); + void seq_poisonDeathNow(int now); + void seq_poisonDeathNowAnim(); + void seq_playFluteAnimation(); + void seq_winterScroll1(); + void seq_winterScroll2(); + void seq_makeBrandonInv(); + void seq_makeBrandonNormal(); + void seq_makeBrandonNormal2(); + void seq_makeBrandonWisp(); + void seq_dispelMagicAnimation(); + void seq_fillFlaskWithWater(int item, int type); + void seq_playDrinkPotionAnim(int item, int unk2, int flags); + void seq_brandonToStone(); + + // -> end fight + int seq_playEnd(); + void seq_playEnding(); + + int handleMalcolmFlag(); + int handleBeadState(); + void initBeadState(int x, int y, int x2, int y2, int unk1, BeadState *ptr); + int processBead(int x, int y, int &x2, int &y2, BeadState *ptr); + + // -> credits + void seq_playCredits(); + +public: + // delay void delayUntil(uint32 timestamp, bool updateGameTimers = false, bool update = false, bool isMainLoop = false); void delay(uint32 millis, bool update = false, bool isMainLoop = false); + void delayWithTicks(int ticks); + void waitForEvent(); + + // TODO void quitGame(); void registerDefaultSettings(); @@ -292,10 +345,6 @@ public: bool speechEnabled(); bool textEnabled(); - void drawSentenceCommand(const char *sentence, int unk1); - void updateSentenceCommand(const char *str1, const char *str2, int unk1); - void updateTextFade(); - void updateGameTimers(); void clearNextEventTickCount(); void setTimerCountdown(uint8 timer, int32 countdown); @@ -304,8 +353,6 @@ public: void enableTimer(uint8 timer); void disableTimer(uint8 timer); - void delayWithTicks(int ticks); - void saveGame(const char *fileName, const char *saveName); void loadGame(const char *fileName); @@ -314,239 +361,87 @@ public: int setGameFlag(int flag); int queryGameFlag(int flag); int resetGameFlag(int flag); - - virtual int runOpcode(ScriptState *script, uint8 opcode); protected: - int o1_magicInMouseItem(ScriptState *script); - int o1_characterSays(ScriptState *script); - int o1_pauseTicks(ScriptState *script); - int o1_drawSceneAnimShape(ScriptState *script); - int o1_queryGameFlag(ScriptState *script); - int o1_setGameFlag(ScriptState *script); - int o1_resetGameFlag(ScriptState *script); - int o1_runNPCScript(ScriptState *script); - int o1_setSpecialExitList(ScriptState *script); - int o1_blockInWalkableRegion(ScriptState *script); - int o1_blockOutWalkableRegion(ScriptState *script); - int o1_walkPlayerToPoint(ScriptState *script); - int o1_dropItemInScene(ScriptState *script); - int o1_drawAnimShapeIntoScene(ScriptState *script); - int o1_createMouseItem(ScriptState *script); - int o1_savePageToDisk(ScriptState *script); - int o1_sceneAnimOn(ScriptState *script); - int o1_sceneAnimOff(ScriptState *script); - int o1_getElapsedSeconds(ScriptState *script); - int o1_mouseIsPointer(ScriptState *script); - int o1_destroyMouseItem(ScriptState *script); - int o1_runSceneAnimUntilDone(ScriptState *script); - int o1_fadeSpecialPalette(ScriptState *script); - int o1_playAdlibSound(ScriptState *script); - int o1_playAdlibScore(ScriptState *script); - int o1_phaseInSameScene(ScriptState *script); - int o1_setScenePhasingFlag(ScriptState *script); - int o1_resetScenePhasingFlag(ScriptState *script); - int o1_queryScenePhasingFlag(ScriptState *script); - int o1_sceneToDirection(ScriptState *script); - int o1_setBirthstoneGem(ScriptState *script); - int o1_placeItemInGenericMapScene(ScriptState *script); - int o1_setBrandonStatusBit(ScriptState *script); - int o1_pauseSeconds(ScriptState *script); - int o1_getCharactersLocation(ScriptState *script); - int o1_runNPCSubscript(ScriptState *script); - int o1_magicOutMouseItem(ScriptState *script); - int o1_internalAnimOn(ScriptState *script); - int o1_forceBrandonToNormal(ScriptState *script); - int o1_poisonDeathNow(ScriptState *script); - int o1_setScaleMode(ScriptState *script); - int o1_openWSAFile(ScriptState *script); - int o1_closeWSAFile(ScriptState *script); - int o1_runWSAFromBeginningToEnd(ScriptState *script); - int o1_displayWSAFrame(ScriptState *script); - int o1_enterNewScene(ScriptState *script); - int o1_setSpecialEnterXAndY(ScriptState *script); - int o1_runWSAFrames(ScriptState *script); - int o1_popBrandonIntoScene(ScriptState *script); - int o1_restoreAllObjectBackgrounds(ScriptState *script); - int o1_setCustomPaletteRange(ScriptState *script); - int o1_loadPageFromDisk(ScriptState *script); - int o1_customPrintTalkString(ScriptState *script); - int o1_restoreCustomPrintBackground(ScriptState *script); - int o1_hideMouse(ScriptState *script); - int o1_showMouse(ScriptState *script); - int o1_getCharacterX(ScriptState *script); - int o1_getCharacterY(ScriptState *script); - int o1_changeCharactersFacing(ScriptState *script); - int o1_copyWSARegion(ScriptState *script); - int o1_printText(ScriptState *script); - int o1_random(ScriptState *script); - int o1_loadSoundFile(ScriptState *script); - int o1_displayWSAFrameOnHidPage(ScriptState *script); - int o1_displayWSASequentialFrames(ScriptState *script); - int o1_drawCharacterStanding(ScriptState *script); - int o1_internalAnimOff(ScriptState *script); - int o1_changeCharactersXAndY(ScriptState *script); - int o1_clearSceneAnimatorBeacon(ScriptState *script); - int o1_querySceneAnimatorBeacon(ScriptState *script); - int o1_refreshSceneAnimator(ScriptState *script); - int o1_placeItemInOffScene(ScriptState *script); - int o1_wipeDownMouseItem(ScriptState *script); - int o1_placeCharacterInOtherScene(ScriptState *script); - int o1_getKey(ScriptState *script); - int o1_specificItemInInventory(ScriptState *script); - int o1_popMobileNPCIntoScene(ScriptState *script); - int o1_mobileCharacterInScene(ScriptState *script); - int o1_hideMobileCharacter(ScriptState *script); - int o1_unhideMobileCharacter(ScriptState *script); - int o1_setCharactersLocation(ScriptState *script); - int o1_walkCharacterToPoint(ScriptState *script); - int o1_specialEventDisplayBrynnsNote(ScriptState *script); - int o1_specialEventRemoveBrynnsNote(ScriptState *script); - int o1_setLogicPage(ScriptState *script); - int o1_fatPrint(ScriptState *script); - int o1_preserveAllObjectBackgrounds(ScriptState *script); - int o1_updateSceneAnimations(ScriptState *script); - int o1_sceneAnimationActive(ScriptState *script); - int o1_setCharactersMovementDelay(ScriptState *script); - int o1_getCharactersFacing(ScriptState *script); - int o1_bkgdScrollSceneAndMasksRight(ScriptState *script); - int o1_dispelMagicAnimation(ScriptState *script); - int o1_findBrightestFireberry(ScriptState *script); - int o1_setFireberryGlowPalette(ScriptState *script); - int o1_setDeathHandlerFlag(ScriptState *script); - int o1_drinkPotionAnimation(ScriptState *script); - int o1_makeAmuletAppear(ScriptState *script); - int o1_drawItemShapeIntoScene(ScriptState *script); - int o1_setCharactersCurrentFrame(ScriptState *script); - int o1_waitForConfirmationMouseClick(ScriptState *script); - int o1_pageFlip(ScriptState *script); - int o1_setSceneFile(ScriptState *script); - int o1_getItemInMarbleVase(ScriptState *script); - int o1_setItemInMarbleVase(ScriptState *script); - int o1_addItemToInventory(ScriptState *script); - int o1_intPrint(ScriptState *script); - int o1_shakeScreen(ScriptState *script); - int o1_createAmuletJewel(ScriptState *script); - int o1_setSceneAnimCurrXY(ScriptState *script); - int o1_poisonBrandonAndRemaps(ScriptState *script); - int o1_fillFlaskWithWater(ScriptState *script); - int o1_getCharactersMovementDelay(ScriptState *script); - int o1_getBirthstoneGem(ScriptState *script); - int o1_queryBrandonStatusBit(ScriptState *script); - int o1_playFluteAnimation(ScriptState *script); - int o1_playWinterScrollSequence(ScriptState *script); - int o1_getIdolGem(ScriptState *script); - int o1_setIdolGem(ScriptState *script); - int o1_totalItemsInScene(ScriptState *script); - int o1_restoreBrandonsMovementDelay(ScriptState *script); - int o1_setMousePos(ScriptState *script); - int o1_getMouseState(ScriptState *script); - int o1_setEntranceMouseCursorTrack(ScriptState *script); - int o1_itemAppearsOnGround(ScriptState *script); - int o1_setNoDrawShapesFlag(ScriptState *script); - int o1_fadeEntirePalette(ScriptState *script); - int o1_itemOnGroundHere(ScriptState *script); - int o1_queryCauldronState(ScriptState *script); - int o1_setCauldronState(ScriptState *script); - int o1_queryCrystalState(ScriptState *script); - int o1_setCrystalState(ScriptState *script); - int o1_setPaletteRange(ScriptState *script); - int o1_shrinkBrandonDown(ScriptState *script); - int o1_growBrandonUp(ScriptState *script); - int o1_setBrandonScaleXAndY(ScriptState *script); - int o1_resetScaleMode(ScriptState *script); - int o1_getScaleDepthTableValue(ScriptState *script); - int o1_setScaleDepthTableValue(ScriptState *script); - int o1_message(ScriptState *script); - int o1_checkClickOnNPC(ScriptState *script); - int o1_getFoyerItem(ScriptState *script); - int o1_setFoyerItem(ScriptState *script); - int o1_setNoItemDropRegion(ScriptState *script); - int o1_walkMalcolmOn(ScriptState *script); - int o1_passiveProtection(ScriptState *script); - int o1_setPlayingLoop(ScriptState *script); - int o1_brandonToStoneSequence(ScriptState *script); - int o1_brandonHealingSequence(ScriptState *script); - int o1_protectCommandLine(ScriptState *script); - int o1_pauseMusicSeconds(ScriptState *script); - int o1_resetMaskRegion(ScriptState *script); - int o1_setPaletteChangeFlag(ScriptState *script); - int o1_fillRect(ScriptState *script); - int o1_dummy(ScriptState *script); - int o1_vocUnload(ScriptState *script); - int o1_vocLoad(ScriptState *script); - -protected: - virtual int go(); virtual int init(); - void startup(); - void mainLoop(); - int initCharacterChat(int8 charNum); - int8 getChatPartnerNum(); - void backupChatPartnerAnimFrame(int8 charNum); - void restoreChatPartnerAnimFrame(int8 charNum); - void endCharacterChat(int8 charNum, int16 arg_4); - void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); - void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); + // input + void processInput(); + int processInputHelper(int xpos, int ypos); + int clickEventHandler(int xpos, int ypos); + void clickEventHandler2(); + void updateMousePointer(bool forceUpdate = false); + bool hasClickedOnExit(int xpos, int ypos); - void setCharactersPositions(int character); - - void setupSceneResource(int sceneId); - - void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive); - void transcendScenes(int roomIndex, int roomName); - void setSceneFile(int roomIndex, int roomName); - void moveCharacterToPos(int character, int facing, int xpos, int ypos); - void setCharacterPositionWithUpdate(int character); - int setCharacterPosition(int character, int *facingTable); - void setCharacterPositionHelper(int character, int *facingTable); - int getOppositeFacingDirection(int dir); + // scene + // -> init void loadSceneMsc(); void startSceneScript(int brandonAlive); void setupSceneItems(); void initSceneData(int facing, int unk1, int brandonAlive); - void clearNoDropRects(); - void addToNoDropRects(int x, int y, int w, int h); - byte findFreeItemInScene(int scene); - byte findItemAtPos(int x, int y); - void placeItemInGenericMapScene(int item, int index); void initSceneObjectList(int brandonAlive); void initSceneScreen(int brandonAlive); - int findDuplicateItemShape(int shape); + void setupSceneResource(int sceneId); + + // -> process + void enterNewScene(int sceneId, int facing, int unk1, int unk2, int brandonAlive); + int handleSceneChange(int xpos, int ypos, int unk1, int frameReset); + int processSceneChange(int *table, int unk1, int frameReset); + int changeScene(int facing); + + // -> modification + void transcendScenes(int roomIndex, int roomName); + void setSceneFile(int roomIndex, int roomName); + + // -> pathfinder int findWay(int x, int y, int toX, int toY, int *moveTable, int moveTableSize); int findSubPath(int x, int y, int toX, int toY, int *moveTable, int start, int end); int getFacingFromPointToPoint(int x, int y, int toX, int toY); void changePosTowardsFacing(int &x, int &y, int facing); bool lineIsPassable(int x, int y); int getMoveTableSize(int *moveTable); - int handleSceneChange(int xpos, int ypos, int unk1, int frameReset); - int processSceneChange(int *table, int unk1, int frameReset); - int changeScene(int facing); - void createMouseItem(int item); - void destroyMouseItem(); - void setMouseItem(int item); - void wipeDownMouseItem(int xpos, int ypos); - void setBrandonPoisonFlags(int reset); - void resetBrandonPoisonFlags(); - void processInput(); - int processInputHelper(int xpos, int ypos); - int clickEventHandler(int xpos, int ypos); - void clickEventHandler2(); - void updateMousePointer(bool forceUpdate = false); - bool hasClickedOnExit(int xpos, int ypos); - int checkForNPCScriptRun(int xpos, int ypos); - void runNpcScript(int func); - - int countItemsInScene(uint16 sceneId); - int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2); - void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex); + // -> item handling + // --> misc void addItemToRoom(uint16 sceneId, uint8 item, int itemIndex, int x, int y); - int checkNoDropRects(int x, int y); - int isDropable(int x, int y); + + // --> drop handling void itemDropDown(int x, int y, int destX, int destY, byte freeItem, int item); + int processItemDrop(uint16 sceneId, uint8 item, int x, int y, int unk1, int unk2); void dropItem(int unk1, int item, int x, int y, int unk2); + + // --> dropped item handling + int countItemsInScene(uint16 sceneId); + void exchangeItemWithMouseItem(uint16 sceneId, int itemIndex); + byte findFreeItemInScene(int scene); + byte findItemAtPos(int x, int y); + + // --> drop area handling + void addToNoDropRects(int x, int y, int w, int h); + void clearNoDropRects(); + int isDropable(int x, int y); + int checkNoDropRects(int x, int y); + + // --> player items handling + void updatePlayerItemsForScene(); + + // --> item GFX handling + void backUpItemRect0(int xpos, int ypos); + void restoreItemRect0(int xpos, int ypos); + void backUpItemRect1(int xpos, int ypos); + void restoreItemRect1(int xpos, int ypos); + + // items + // -> misc + void placeItemInGenericMapScene(int item, int index); + + // -> mouse item + void createMouseItem(int item); + void destroyMouseItem(); + void setMouseItem(int item); + + // -> graphics effects + void wipeDownMouseItem(int xpos, int ypos); void itemSpecialFX(int x, int y, int item); void itemSpecialFX1(int x, int y, int item); void itemSpecialFX2(int x, int y, int item); @@ -554,63 +449,77 @@ protected: void magicInMouseItem(int animIndex, int item, int itemPos); void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops); void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops); - void updatePlayerItemsForScene(); + + // character + // -> movement + void moveCharacterToPos(int character, int facing, int xpos, int ypos); + void setCharacterPositionWithUpdate(int character); + int setCharacterPosition(int character, int *facingTable); + void setCharacterPositionHelper(int character, int *facingTable); + int getOppositeFacingDirection(int dir); + void setCharactersPositions(int character); + + // -> brandon + void setBrandonPoisonFlags(int reset); + void resetBrandonPoisonFlags(); + + // chat + // -> process + void characterSays(int vocFile, const char *chatStr, int8 charNum, int8 chatDuration); + void waitForChatToFinish(int vocFile, int16 chatDuration, const char *str, uint8 charNum); + + // -> initialization + int initCharacterChat(int8 charNum); + void backupChatPartnerAnimFrame(int8 charNum); + void restoreChatPartnerAnimFrame(int8 charNum); + int8 getChatPartnerNum(); + + // -> deinitialization + void endCharacterChat(int8 charNum, int16 arg_4); + + // graphics + // -> misc + int findDuplicateItemShape(int shape); + void updateKyragemFading(); + + // -> interface + void loadMainScreen(int page = 3); void redrawInventory(int page); - +public: + void drawSentenceCommand(const char *sentence, int unk1); + void updateSentenceCommand(const char *str1, const char *str2, int unk1); + void updateTextFade(); + +protected: + // -> amulet void drawJewelPress(int jewel, int drawSpecial); void drawJewelsFadeOutStart(); void drawJewelsFadeOutEnd(int jewel); + + // -> shape handling void setupShapes123(const Shape *shapeTable, int endShape, int flags); void freeShapes123(); - void seq_demo(); - void seq_intro(); - void seq_introLogos(); - void seq_introStory(); - void seq_introMalcolmTree(); - void seq_introKallakWriting(); - void seq_introKallakMalcolm(); - void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly); - void seq_brandonHealing(); - void seq_brandonHealing2(); - void seq_poisonDeathNow(int now); - void seq_poisonDeathNowAnim(); - void seq_playFluteAnimation(); - void seq_winterScroll1(); - void seq_winterScroll2(); - void seq_makeBrandonInv(); - void seq_makeBrandonNormal(); - void seq_makeBrandonNormal2(); - void seq_makeBrandonWisp(); - void seq_dispelMagicAnimation(); - void seq_fillFlaskWithWater(int item, int type); - void seq_playDrinkPotionAnim(int item, int unk2, int flags); - int seq_playEnd(); - void seq_brandonToStone(); - void seq_playEnding(); - void seq_playCredits(); - void updateKyragemFading(); + // misc (TODO) + void startup(); + void mainLoop(); - void setupOpcodeTable(); - const OpcodeProc *_opcodeTable; - int _opcodeTableSize; + int checkForNPCScriptRun(int xpos, int ypos); + void runNpcScript(int func); + + virtual void setupOpcodeTable() = 0; + Common::Array<const Opcode*> _opcodes; - void waitForEvent(); void loadMouseShapes(); void loadCharacterShapes(); void loadSpecialEffectShapes(); void loadItems(); void loadButtonShapes(); void initMainButtonList(); - void loadMainScreen(int page = 3); void setCharactersInDefaultScene(); void setupPanPages(); void freePanPages(); void closeFinalWsa(); - int handleMalcolmFlag(); - int handleBeadState(); - void initBeadState(int x, int y, int x2, int y2, int unk1, BeadState *ptr); - int processBead(int x, int y, int &x2, int &y2, BeadState *ptr); void setTimer19(); void setupTimers(); @@ -682,7 +591,7 @@ protected: // Kyra 2 and 3 main menu static const char *_mainMenuStrings[]; - virtual void gui_initMainMenu() {}; + virtual void gui_initMainMenu() {} int gui_handleMainMenu(); virtual void gui_updateMainMenuAnimation(); void gui_drawMainMenu(const char * const *strings, int select); @@ -702,7 +611,8 @@ protected: bool _mousePressFlag; int8 _mouseWheel; uint8 _flagsTable[69]; - uint8 *_shapes[377]; + uint8 *_itemBkgBackUp[2]; + uint8 *_shapes[373]; uint16 _gameSpeed; uint16 _tickLength; int _lang; @@ -1004,12 +914,7 @@ protected: static const uint16 _amuletY2[]; }; -class KyraEngine_v1 : public KyraEngine { -public: - KyraEngine_v1(OSystem *system, const GameFlags &flags); - ~KyraEngine_v1(); -}; - } // End of namespace Kyra #endif + diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp new file mode 100644 index 0000000000..f0c0c1200d --- /dev/null +++ b/engines/kyra/kyra_v1.cpp @@ -0,0 +1,241 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/kyra_v1.h" + +namespace Kyra { + +KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags) + : KyraEngine(system, flags) { +} + +KyraEngine_v1::~KyraEngine_v1() { +} + +#define Opcode(x) OpcodeV1(this, &KyraEngine_v1::x) +void KyraEngine_v1::setupOpcodeTable() { + static const OpcodeV1 opcodeTable[] = { + // 0x00 + Opcode(o1_magicInMouseItem), + Opcode(o1_characterSays), + Opcode(o1_pauseTicks), + Opcode(o1_drawSceneAnimShape), + // 0x04 + Opcode(o1_queryGameFlag), + Opcode(o1_setGameFlag), + Opcode(o1_resetGameFlag), + Opcode(o1_runNPCScript), + // 0x08 + Opcode(o1_setSpecialExitList), + Opcode(o1_blockInWalkableRegion), + Opcode(o1_blockOutWalkableRegion), + Opcode(o1_walkPlayerToPoint), + // 0x0c + Opcode(o1_dropItemInScene), + Opcode(o1_drawAnimShapeIntoScene), + Opcode(o1_createMouseItem), + Opcode(o1_savePageToDisk), + // 0x10 + Opcode(o1_sceneAnimOn), + Opcode(o1_sceneAnimOff), + Opcode(o1_getElapsedSeconds), + Opcode(o1_mouseIsPointer), + // 0x14 + Opcode(o1_destroyMouseItem), + Opcode(o1_runSceneAnimUntilDone), + Opcode(o1_fadeSpecialPalette), + Opcode(o1_playAdlibSound), + // 0x18 + Opcode(o1_playAdlibScore), + Opcode(o1_phaseInSameScene), + Opcode(o1_setScenePhasingFlag), + Opcode(o1_resetScenePhasingFlag), + // 0x1c + Opcode(o1_queryScenePhasingFlag), + Opcode(o1_sceneToDirection), + Opcode(o1_setBirthstoneGem), + Opcode(o1_placeItemInGenericMapScene), + // 0x20 + Opcode(o1_setBrandonStatusBit), + Opcode(o1_pauseSeconds), + Opcode(o1_getCharactersLocation), + Opcode(o1_runNPCSubscript), + // 0x24 + Opcode(o1_magicOutMouseItem), + Opcode(o1_internalAnimOn), + Opcode(o1_forceBrandonToNormal), + Opcode(o1_poisonDeathNow), + // 0x28 + Opcode(o1_setScaleMode), + Opcode(o1_openWSAFile), + Opcode(o1_closeWSAFile), + Opcode(o1_runWSAFromBeginningToEnd), + // 0x2c + Opcode(o1_displayWSAFrame), + Opcode(o1_enterNewScene), + Opcode(o1_setSpecialEnterXAndY), + Opcode(o1_runWSAFrames), + // 0x30 + Opcode(o1_popBrandonIntoScene), + Opcode(o1_restoreAllObjectBackgrounds), + Opcode(o1_setCustomPaletteRange), + Opcode(o1_loadPageFromDisk), + // 0x34 + Opcode(o1_customPrintTalkString), + Opcode(o1_restoreCustomPrintBackground), + Opcode(o1_hideMouse), + Opcode(o1_showMouse), + // 0x38 + Opcode(o1_getCharacterX), + Opcode(o1_getCharacterY), + Opcode(o1_changeCharactersFacing), + Opcode(o1_copyWSARegion), + // 0x3c + Opcode(o1_printText), + Opcode(o1_random), + Opcode(o1_loadSoundFile), + Opcode(o1_displayWSAFrameOnHidPage), + // 0x40 + Opcode(o1_displayWSASequentialFrames), + Opcode(o1_drawCharacterStanding), + Opcode(o1_internalAnimOff), + Opcode(o1_changeCharactersXAndY), + // 0x44 + Opcode(o1_clearSceneAnimatorBeacon), + Opcode(o1_querySceneAnimatorBeacon), + Opcode(o1_refreshSceneAnimator), + Opcode(o1_placeItemInOffScene), + // 0x48 + Opcode(o1_wipeDownMouseItem), + Opcode(o1_placeCharacterInOtherScene), + Opcode(o1_getKey), + Opcode(o1_specificItemInInventory), + // 0x4c + Opcode(o1_popMobileNPCIntoScene), + Opcode(o1_mobileCharacterInScene), + Opcode(o1_hideMobileCharacter), + Opcode(o1_unhideMobileCharacter), + // 0x50 + Opcode(o1_setCharactersLocation), + Opcode(o1_walkCharacterToPoint), + Opcode(o1_specialEventDisplayBrynnsNote), + Opcode(o1_specialEventRemoveBrynnsNote), + // 0x54 + Opcode(o1_setLogicPage), + Opcode(o1_fatPrint), + Opcode(o1_preserveAllObjectBackgrounds), + Opcode(o1_updateSceneAnimations), + // 0x58 + Opcode(o1_sceneAnimationActive), + Opcode(o1_setCharactersMovementDelay), + Opcode(o1_getCharactersFacing), + Opcode(o1_bkgdScrollSceneAndMasksRight), + // 0x5c + Opcode(o1_dispelMagicAnimation), + Opcode(o1_findBrightestFireberry), + Opcode(o1_setFireberryGlowPalette), + Opcode(o1_setDeathHandlerFlag), + // 0x60 + Opcode(o1_drinkPotionAnimation), + Opcode(o1_makeAmuletAppear), + Opcode(o1_drawItemShapeIntoScene), + Opcode(o1_setCharactersCurrentFrame), + // 0x64 + Opcode(o1_waitForConfirmationMouseClick), + Opcode(o1_pageFlip), + Opcode(o1_setSceneFile), + Opcode(o1_getItemInMarbleVase), + // 0x68 + Opcode(o1_setItemInMarbleVase), + Opcode(o1_addItemToInventory), + Opcode(o1_intPrint), + Opcode(o1_shakeScreen), + // 0x6c + Opcode(o1_createAmuletJewel), + Opcode(o1_setSceneAnimCurrXY), + Opcode(o1_poisonBrandonAndRemaps), + Opcode(o1_fillFlaskWithWater), + // 0x70 + Opcode(o1_getCharactersMovementDelay), + Opcode(o1_getBirthstoneGem), + Opcode(o1_queryBrandonStatusBit), + Opcode(o1_playFluteAnimation), + // 0x74 + Opcode(o1_playWinterScrollSequence), + Opcode(o1_getIdolGem), + Opcode(o1_setIdolGem), + Opcode(o1_totalItemsInScene), + // 0x78 + Opcode(o1_restoreBrandonsMovementDelay), + Opcode(o1_setMousePos), + Opcode(o1_getMouseState), + Opcode(o1_setEntranceMouseCursorTrack), + // 0x7c + Opcode(o1_itemAppearsOnGround), + Opcode(o1_setNoDrawShapesFlag), + Opcode(o1_fadeEntirePalette), + Opcode(o1_itemOnGroundHere), + // 0x80 + Opcode(o1_queryCauldronState), + Opcode(o1_setCauldronState), + Opcode(o1_queryCrystalState), + Opcode(o1_setCrystalState), + // 0x84 + Opcode(o1_setPaletteRange), + Opcode(o1_shrinkBrandonDown), + Opcode(o1_growBrandonUp), + Opcode(o1_setBrandonScaleXAndY), + // 0x88 + Opcode(o1_resetScaleMode), + Opcode(o1_getScaleDepthTableValue), + Opcode(o1_setScaleDepthTableValue), + Opcode(o1_message), + // 0x8c + Opcode(o1_checkClickOnNPC), + Opcode(o1_getFoyerItem), + Opcode(o1_setFoyerItem), + Opcode(o1_setNoItemDropRegion), + // 0x90 + Opcode(o1_walkMalcolmOn), + Opcode(o1_passiveProtection), + Opcode(o1_setPlayingLoop), + Opcode(o1_brandonToStoneSequence), + // 0x94 + Opcode(o1_brandonHealingSequence), + Opcode(o1_protectCommandLine), + Opcode(o1_pauseMusicSeconds), + Opcode(o1_resetMaskRegion), + // 0x98 + Opcode(o1_setPaletteChangeFlag), + Opcode(o1_fillRect), + Opcode(o1_vocUnload), + Opcode(o1_vocLoad), + Opcode(o1_dummy) + }; + + for (int i = 0; i < ARRAYSIZE(opcodeTable); ++i) + _opcodes.push_back(&opcodeTable[i]); +} +#undef Opcode + +} // end of namespace Kyra + diff --git a/engines/kyra/kyra_v1.h b/engines/kyra/kyra_v1.h new file mode 100644 index 0000000000..1bf18298e9 --- /dev/null +++ b/engines/kyra/kyra_v1.h @@ -0,0 +1,203 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_KYRA_V1_H +#define KYRA_KYRA_V1_H + +#include "kyra.h" +#include "script.h" + +namespace Kyra { + +class KyraEngine_v1 : public KyraEngine { +public: + KyraEngine_v1(OSystem *system, const GameFlags &flags); + ~KyraEngine_v1(); + +protected: + typedef OpcodeImpl<KyraEngine_v1> OpcodeV1; + void setupOpcodeTable(); + + // Opcodes + int o1_magicInMouseItem(ScriptState *script); + int o1_characterSays(ScriptState *script); + int o1_pauseTicks(ScriptState *script); + int o1_drawSceneAnimShape(ScriptState *script); + int o1_queryGameFlag(ScriptState *script); + int o1_setGameFlag(ScriptState *script); + int o1_resetGameFlag(ScriptState *script); + int o1_runNPCScript(ScriptState *script); + int o1_setSpecialExitList(ScriptState *script); + int o1_blockInWalkableRegion(ScriptState *script); + int o1_blockOutWalkableRegion(ScriptState *script); + int o1_walkPlayerToPoint(ScriptState *script); + int o1_dropItemInScene(ScriptState *script); + int o1_drawAnimShapeIntoScene(ScriptState *script); + int o1_createMouseItem(ScriptState *script); + int o1_savePageToDisk(ScriptState *script); + int o1_sceneAnimOn(ScriptState *script); + int o1_sceneAnimOff(ScriptState *script); + int o1_getElapsedSeconds(ScriptState *script); + int o1_mouseIsPointer(ScriptState *script); + int o1_destroyMouseItem(ScriptState *script); + int o1_runSceneAnimUntilDone(ScriptState *script); + int o1_fadeSpecialPalette(ScriptState *script); + int o1_playAdlibSound(ScriptState *script); + int o1_playAdlibScore(ScriptState *script); + int o1_phaseInSameScene(ScriptState *script); + int o1_setScenePhasingFlag(ScriptState *script); + int o1_resetScenePhasingFlag(ScriptState *script); + int o1_queryScenePhasingFlag(ScriptState *script); + int o1_sceneToDirection(ScriptState *script); + int o1_setBirthstoneGem(ScriptState *script); + int o1_placeItemInGenericMapScene(ScriptState *script); + int o1_setBrandonStatusBit(ScriptState *script); + int o1_pauseSeconds(ScriptState *script); + int o1_getCharactersLocation(ScriptState *script); + int o1_runNPCSubscript(ScriptState *script); + int o1_magicOutMouseItem(ScriptState *script); + int o1_internalAnimOn(ScriptState *script); + int o1_forceBrandonToNormal(ScriptState *script); + int o1_poisonDeathNow(ScriptState *script); + int o1_setScaleMode(ScriptState *script); + int o1_openWSAFile(ScriptState *script); + int o1_closeWSAFile(ScriptState *script); + int o1_runWSAFromBeginningToEnd(ScriptState *script); + int o1_displayWSAFrame(ScriptState *script); + int o1_enterNewScene(ScriptState *script); + int o1_setSpecialEnterXAndY(ScriptState *script); + int o1_runWSAFrames(ScriptState *script); + int o1_popBrandonIntoScene(ScriptState *script); + int o1_restoreAllObjectBackgrounds(ScriptState *script); + int o1_setCustomPaletteRange(ScriptState *script); + int o1_loadPageFromDisk(ScriptState *script); + int o1_customPrintTalkString(ScriptState *script); + int o1_restoreCustomPrintBackground(ScriptState *script); + int o1_hideMouse(ScriptState *script); + int o1_showMouse(ScriptState *script); + int o1_getCharacterX(ScriptState *script); + int o1_getCharacterY(ScriptState *script); + int o1_changeCharactersFacing(ScriptState *script); + int o1_copyWSARegion(ScriptState *script); + int o1_printText(ScriptState *script); + int o1_random(ScriptState *script); + int o1_loadSoundFile(ScriptState *script); + int o1_displayWSAFrameOnHidPage(ScriptState *script); + int o1_displayWSASequentialFrames(ScriptState *script); + int o1_drawCharacterStanding(ScriptState *script); + int o1_internalAnimOff(ScriptState *script); + int o1_changeCharactersXAndY(ScriptState *script); + int o1_clearSceneAnimatorBeacon(ScriptState *script); + int o1_querySceneAnimatorBeacon(ScriptState *script); + int o1_refreshSceneAnimator(ScriptState *script); + int o1_placeItemInOffScene(ScriptState *script); + int o1_wipeDownMouseItem(ScriptState *script); + int o1_placeCharacterInOtherScene(ScriptState *script); + int o1_getKey(ScriptState *script); + int o1_specificItemInInventory(ScriptState *script); + int o1_popMobileNPCIntoScene(ScriptState *script); + int o1_mobileCharacterInScene(ScriptState *script); + int o1_hideMobileCharacter(ScriptState *script); + int o1_unhideMobileCharacter(ScriptState *script); + int o1_setCharactersLocation(ScriptState *script); + int o1_walkCharacterToPoint(ScriptState *script); + int o1_specialEventDisplayBrynnsNote(ScriptState *script); + int o1_specialEventRemoveBrynnsNote(ScriptState *script); + int o1_setLogicPage(ScriptState *script); + int o1_fatPrint(ScriptState *script); + int o1_preserveAllObjectBackgrounds(ScriptState *script); + int o1_updateSceneAnimations(ScriptState *script); + int o1_sceneAnimationActive(ScriptState *script); + int o1_setCharactersMovementDelay(ScriptState *script); + int o1_getCharactersFacing(ScriptState *script); + int o1_bkgdScrollSceneAndMasksRight(ScriptState *script); + int o1_dispelMagicAnimation(ScriptState *script); + int o1_findBrightestFireberry(ScriptState *script); + int o1_setFireberryGlowPalette(ScriptState *script); + int o1_setDeathHandlerFlag(ScriptState *script); + int o1_drinkPotionAnimation(ScriptState *script); + int o1_makeAmuletAppear(ScriptState *script); + int o1_drawItemShapeIntoScene(ScriptState *script); + int o1_setCharactersCurrentFrame(ScriptState *script); + int o1_waitForConfirmationMouseClick(ScriptState *script); + int o1_pageFlip(ScriptState *script); + int o1_setSceneFile(ScriptState *script); + int o1_getItemInMarbleVase(ScriptState *script); + int o1_setItemInMarbleVase(ScriptState *script); + int o1_addItemToInventory(ScriptState *script); + int o1_intPrint(ScriptState *script); + int o1_shakeScreen(ScriptState *script); + int o1_createAmuletJewel(ScriptState *script); + int o1_setSceneAnimCurrXY(ScriptState *script); + int o1_poisonBrandonAndRemaps(ScriptState *script); + int o1_fillFlaskWithWater(ScriptState *script); + int o1_getCharactersMovementDelay(ScriptState *script); + int o1_getBirthstoneGem(ScriptState *script); + int o1_queryBrandonStatusBit(ScriptState *script); + int o1_playFluteAnimation(ScriptState *script); + int o1_playWinterScrollSequence(ScriptState *script); + int o1_getIdolGem(ScriptState *script); + int o1_setIdolGem(ScriptState *script); + int o1_totalItemsInScene(ScriptState *script); + int o1_restoreBrandonsMovementDelay(ScriptState *script); + int o1_setMousePos(ScriptState *script); + int o1_getMouseState(ScriptState *script); + int o1_setEntranceMouseCursorTrack(ScriptState *script); + int o1_itemAppearsOnGround(ScriptState *script); + int o1_setNoDrawShapesFlag(ScriptState *script); + int o1_fadeEntirePalette(ScriptState *script); + int o1_itemOnGroundHere(ScriptState *script); + int o1_queryCauldronState(ScriptState *script); + int o1_setCauldronState(ScriptState *script); + int o1_queryCrystalState(ScriptState *script); + int o1_setCrystalState(ScriptState *script); + int o1_setPaletteRange(ScriptState *script); + int o1_shrinkBrandonDown(ScriptState *script); + int o1_growBrandonUp(ScriptState *script); + int o1_setBrandonScaleXAndY(ScriptState *script); + int o1_resetScaleMode(ScriptState *script); + int o1_getScaleDepthTableValue(ScriptState *script); + int o1_setScaleDepthTableValue(ScriptState *script); + int o1_message(ScriptState *script); + int o1_checkClickOnNPC(ScriptState *script); + int o1_getFoyerItem(ScriptState *script); + int o1_setFoyerItem(ScriptState *script); + int o1_setNoItemDropRegion(ScriptState *script); + int o1_walkMalcolmOn(ScriptState *script); + int o1_passiveProtection(ScriptState *script); + int o1_setPlayingLoop(ScriptState *script); + int o1_brandonToStoneSequence(ScriptState *script); + int o1_brandonHealingSequence(ScriptState *script); + int o1_protectCommandLine(ScriptState *script); + int o1_pauseMusicSeconds(ScriptState *script); + int o1_resetMaskRegion(ScriptState *script); + int o1_setPaletteChangeFlag(ScriptState *script); + int o1_fillRect(ScriptState *script); + int o1_dummy(ScriptState *script); + int o1_vocUnload(ScriptState *script); + int o1_vocLoad(ScriptState *script); +}; + +} // end of namespace Kyra + +#endif + diff --git a/engines/kyra/kyra2.cpp b/engines/kyra/kyra_v2.cpp index 11b2e562c7..4f72b1378c 100644 --- a/engines/kyra/kyra2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -21,7 +21,7 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra2.h" +#include "kyra/kyra_v2.h" #include "kyra/screen.h" #include "kyra/resource.h" #include "kyra/wsamovie.h" @@ -43,20 +43,17 @@ KyraEngine_v2::~KyraEngine_v2() { int KyraEngine_v2::init() { KyraEngine::init(); - if (_res->getFileSize("6.FNT")) { + if (_res->getFileSize("6.FNT")) _screen->loadFont(Screen::FID_6_FNT, "6.FNT"); - } - if (_res->getFileSize("8FAT.FNT")) { + if (_res->getFileSize("8FAT.FNT")) _screen->loadFont(Screen::FID_8_FNT, "8FAT.FNT"); - } _screen->loadFont(Screen::FID_GOLDFONT_FNT, "GOLDFONT.FNT"); _screen->setAnimBlockPtr(3500); _screen->setScreenDim(0); assert(_introStringsSize == 21); - for (int i = 0; i < 21; i++) { + for (int i = 0; i < 21; i++) _introStringsDuration[i] = strlen(_introStrings[i]) * 8; - } // No mouse display in demo if (_flags.isDemo) @@ -127,3 +124,4 @@ void KyraEngine_v2::mainMenu() { } } // end of namespace Kyra + diff --git a/engines/kyra/kyra2.h b/engines/kyra/kyra_v2.h index ef07df41ed..65c9f32c1b 100644 --- a/engines/kyra/kyra2.h +++ b/engines/kyra/kyra_v2.h @@ -20,8 +20,8 @@ * */ -#ifndef KYRA2_H -#define KYRA2_H +#ifndef KYRA_KYRA_V2_H +#define KYRA_KYRA_V2_H namespace Kyra { @@ -81,6 +81,8 @@ public: int go(); private: + void setupOpcodeTable() {} + void seq_playSequences(int startSeq, int endSeq = -1); int seq_introWestwood(int seqNum); int seq_introTitle(int seqNum); @@ -115,9 +117,9 @@ private: static const int _introStringsSize; int _introStringsDuration[21]; - }; } // end of namespace Kyra #endif + diff --git a/engines/kyra/kyra3.cpp b/engines/kyra/kyra_v3.cpp index d17a2b72c3..2301697d61 100644 --- a/engines/kyra/kyra3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -21,7 +21,7 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra3.h" +#include "kyra/kyra_v3.h" #include "kyra/screen.h" #include "kyra/wsamovie.h" #include "kyra/sound.h" @@ -117,9 +117,8 @@ int KyraEngine_v3::init() { _mouseSHPBuf = _res->fileData("MOUSE.SHP", 0); assert(_mouseSHPBuf); - for (int i = 0; i <= 6; ++i) { + for (int i = 0; i <= 6; ++i) _gameShapes[i] = _screen->getPtrToShape(_mouseSHPBuf, i); - } initItems(); @@ -244,11 +243,10 @@ void KyraEngine_v3::playMenuAudioFile() { Common::File *handle = new Common::File(); uint32 temp = 0; _res->getFileHandle(_menuAudioFile, &temp, *handle); - if (handle->isOpen()) { + if (handle->isOpen()) _musicSoundChannel = _soundDigital->playSound(handle, true); - } else { + else delete handle; - } } void KyraEngine_v3::playMusicTrack(int track, int force) { @@ -256,11 +254,10 @@ void KyraEngine_v3::playMusicTrack(int track, int force) { // XXX byte_2C87C compare - if (_musicSoundChannel != -1 && !_soundDigital->isPlaying(_musicSoundChannel)) { + if (_musicSoundChannel != -1 && !_soundDigital->isPlaying(_musicSoundChannel)) force = 1; - } else if (_musicSoundChannel == -1) { + else if (_musicSoundChannel == -1) force = 1; - } if (track == _curMusicTrack && !force) return; @@ -273,11 +270,10 @@ void KyraEngine_v3::playMusicTrack(int track, int force) { Common::File *handle = new Common::File(); uint32 temp = 0; _res->getFileHandle(_soundList[track], &temp, *handle); - if (handle->isOpen()) { + if (handle->isOpen()) _musicSoundChannel = _soundDigital->playSound(handle); - } else { + else delete handle; - } } _musicSoundChannel = track; @@ -559,18 +555,16 @@ uint8 *KyraEngine_v3::allocTableSpace(uint8 *buf, int size, int id) { *(uint32*)(buf2 + 16) = unkValue1 + size; memcpy(_tableBuffer1 + entries * 14 + 12, _tableBuffer1 + unk1 * 14 + 12, 14); } else { - if (usedEntry > unk1) { + if (usedEntry > unk1) memcpy(buf2 + 12, _tableBuffer1 + unk1 * 14 + 12, 14); - } int temp = *(uint16*)(_tableBuffer1 + 2) - 1; *(uint16*)(_tableBuffer1 + 2) = temp; temp = *(uint16*)(_tableBuffer1 + 4) - 1; *(uint16*)(_tableBuffer1 + 4) = temp; } - for (int i = unk1; i > ok; --i) { + for (int i = unk1; i > ok; --i) memcpy(_tableBuffer1 + i * 14 + 12, _tableBuffer1 + (i-1) * 14 + 12, 14); - } buf2 = _tableBuffer1 + ok * 14; @@ -613,9 +607,8 @@ uint8 *KyraEngine_v3::findIdInTable(uint8 *buf, int id) { uint32 idVal = id; uint8 *ptr = (uint8*)bsearch(&idVal, _tableBuffer1 + 12, *(uint16*)(_tableBuffer1), 14, &tableIdCompare); - if (!ptr) { + if (!ptr) return 0; - } return _tableBuffer2 + *(uint32*)(ptr + 4); } @@ -633,15 +626,13 @@ void KyraEngine_v3::initItems() { _screen->loadBitmap("ITEMS.CSH", 3, 3, 0); - for (int i = 248; i <= 319; ++i) { + for (int i = 248; i <= 319; ++i) addShapeToTable(_screen->getCPagePtr(3), i, i-248); - } _screen->loadBitmap("ITEMS2.CSH", 3, 3, 0); - for (int i = 320; i <= 397; ++i) { + for (int i = 320; i <= 397; ++i) addShapeToTable(_screen->getCPagePtr(3), i, i-320); - } uint32 size = 0; uint8 *itemsDat = _res->fileData("_ITEMS.DAT", &size); @@ -703,3 +694,4 @@ bool KyraEngine_v3::loadLanguageFile(const char *file, uint8 *&buffer) { } } // end of namespace Kyra + diff --git a/engines/kyra/kyra3.h b/engines/kyra/kyra_v3.h index 17d69dcaae..009788a5f6 100644 --- a/engines/kyra/kyra3.h +++ b/engines/kyra/kyra_v3.h @@ -20,8 +20,8 @@ * */ -#ifndef KYRA3_H -#define KYRA3_H +#ifndef KYRA_KYRA_V3_H +#define KYRA_KYRA_V3_H #include "kyra/kyra.h" @@ -48,6 +48,8 @@ private: void preinit(); void realInit(); + void setupOpcodeTable() {} + SoundDigital *_soundDigital; // sound specific @@ -144,3 +146,4 @@ private: } // end of namespace Kyra #endif + diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index f8159dd78b..8303028b27 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -3,12 +3,13 @@ MODULE := engines/kyra MODULE_OBJS := \ animator.o \ debugger.o \ + detection.o \ gui.o \ items.o \ kyra.o \ - kyra2.o \ - kyra3.o \ - plugin.o \ + kyra_v1.o \ + kyra_v2.o \ + kyra_v3.o \ resource.o \ saveload.o \ scene.o \ diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 193ce839c1..ca56ed0f02 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -26,6 +26,8 @@ #include "common/file.h" #include "common/fs.h" #include "common/hash-str.h" +#include "common/func.h" +#include "common/algorithm.h" #include "gui/message.h" @@ -35,12 +37,24 @@ #include "kyra/screen.h" namespace Kyra { + +namespace { +struct ResFilenameEqual : public Common::BinaryFunction<ResourceFile*, uint, bool> { + uint _filename; + ResFilenameEqual(uint file) : _filename(file) {} + + bool operator()(ResourceFile *f) { + return f->filename() == _filename; + } +}; +} // end of anonymous namespace + Resource::Resource(KyraEngine *vm) { _vm = vm; if (_vm->game() == GI_KYRA1) { // we're loading KYRA.DAT here too (but just for Kyrandia 1) - if (!loadPakFile("KYRA.DAT", true) || !StaticResource::checkKyraDat()) { + if (!loadPakFile("KYRA.DAT") || !StaticResource::checkKyraDat()) { GUI::MessageDialog errorMsg("You're missing the 'KYRA.DAT' file or it got corrupted, (re)get it from the ScummVM website"); errorMsg.runModal(); error("You're missing the 'KYRA.DAT' file or it got corrupted, (re)get it from the ScummVM website"); @@ -58,7 +72,7 @@ Resource::Resource(KyraEngine *vm) { INSFile *insFile = new INSFile("WESTWOOD.001"); assert(insFile); if (!insFile->isValid()) - return; + error("'WESTWOOD.001' file not found or corrupt"); _pakfiles.push_back(insFile); } @@ -72,18 +86,11 @@ Resource::Resource(KyraEngine *vm) { static const char *list[] = { "ADL.PAK", "CHAPTER1.VRM", "COL.PAK", "FINALE.PAK", "INTRO1.PAK", "INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "MISC.PAK", "SND.PAK", "STARTUP.PAK", "XMI.PAK", - "CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK", 0 + "CAVE.APK", "DRAGON1.APK", "DRAGON2.APK", "LAGOON.APK" }; - for (int i = 0; list[i]; ++i) { - if (!loadPakFile(list[i])) - error("couldn't open pakfile '%s'", list[i]); - } - - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - for (;start != _pakfiles.end(); ++start) { - (*start)->protect(); - } + Common::for_each(list, list + ARRAYSIZE(list), Common::bind1st(Common::mem_fun(&Resource::loadPakFile), this)); + Common::for_each(_pakfiles.begin(), _pakfiles.end(), Common::bind2nd(Common::mem_fun(&ResourceFile::protect), true)); } else { for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { Common::String filename = file->name(); @@ -94,64 +101,54 @@ Resource::Resource(KyraEngine *vm) { continue; if (filename.hasSuffix("PAK") || filename.hasSuffix("APK")) { - if (!loadPakFile(file->name())) { + if (!loadPakFile(file->name())) error("couldn't open pakfile '%s'", file->name().c_str()); - } } } if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); uint unloadHash = (_vm->gameFlags().lang == Common::EN_ANY) ? Common::hashit_lower("JMC.PAK") : Common::hashit_lower("EMC.PAK"); - for (;start != _pakfiles.end(); ++start) { - if ((*start)->filename() == unloadHash) { - delete *start; - *start = 0; - _pakfiles.erase(start); - break; - } + ResIterator file = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(unloadHash)); + if (file != _pakfiles.end()) { + delete *file; + _pakfiles.erase(file); } } } } Resource::~Resource() { - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - - for (;start != _pakfiles.end(); ++start) { + for (ResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) { delete *start; *start = 0; } } -bool Resource::loadPakFile(const Common::String &filename, const bool forcePC) { - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - uint hash = Common::hashit_lower(filename.c_str()); - - for (;start != _pakfiles.end(); ++start) { - if ((*start)->filename() == hash) { - (*start)->open(); - return true; - } +bool Resource::loadPakFile(const Common::String &filename) { + ResIterator listFile = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))); + if (listFile != _pakfiles.end()) { + (*listFile)->open(); + return true; } + const bool isKyraDat = filename.equalsIgnoreCase("KYRA.DAT"); uint32 size = 0; Common::File handle; if (!getFileHandle(filename.c_str(), &size, handle)) { - warning("couldn't load file: '%s'", filename.c_str()); + (!isKyraDat ? error : warning)("couldn't load file: '%s'", filename.c_str()); return false; } - PAKFile *file = new PAKFile(filename.c_str(), handle.name(), handle, (_vm->gameFlags().platform == Common::kPlatformAmiga) && !forcePC); + PAKFile *file = new PAKFile(filename.c_str(), handle.name(), handle, (_vm->gameFlags().platform == Common::kPlatformAmiga) && !isKyraDat); handle.close(); if (!file) return false; if (!file->isValid()) { - warning("'%s' is no valid pak file", filename.c_str()); + error("'%s' is no valid pak file", filename.c_str()); delete file; return false; } @@ -161,28 +158,16 @@ bool Resource::loadPakFile(const Common::String &filename, const bool forcePC) { } void Resource::unloadPakFile(const Common::String &filename) { - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - uint hash = Common::hashit_lower(filename.c_str()); - for (;start != _pakfiles.end(); ++start) { - if ((*start)->filename() == hash) { - (*start)->close(); - break; - } - } - return; + ResIterator pak = Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))); + if (pak != _pakfiles.end()) + (*pak)->close(); } -bool Resource::isInPakList(const Common::String &filename) { - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - uint hash = Common::hashit_lower(filename.c_str()); - for (;start != _pakfiles.end(); ++start) { - if ((*start)->filename() == hash) - return true; - } - return false; +bool Resource::isInPakList(const Common::String &filename) const { + return (Common::find_if(_pakfiles.begin(), _pakfiles.end(), ResFilenameEqual(Common::hashit_lower(filename))) != _pakfiles.end()); } -uint8 *Resource::fileData(const char *file, uint32 *size) { +uint8 *Resource::fileData(const char *file, uint32 *size) const { Common::File fileHandle; if (size) @@ -201,15 +186,13 @@ uint8 *Resource::fileData(const char *file, uint32 *size) { return buffer; } else { - // opens the file in a PAK File - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - + // opens the file inside a PAK File uint fileHash = Common::hashit_lower(file); - for (;start != _pakfiles.end(); ++start) { - if (!(*start)->isOpen()) + for (ConstResIterator cur = _pakfiles.begin(); cur != _pakfiles.end(); ++cur) { + if (!(*cur)->isOpen()) continue; - uint32 fileSize = (*start)->getFileSize(fileHash); + uint32 fileSize = (*cur)->getFileSize(fileHash); if (!fileSize) continue; @@ -217,7 +200,7 @@ uint8 *Resource::fileData(const char *file, uint32 *size) { if (size) *size = fileSize; - return (*start)->getFile(fileHash); + return (*cur)->getFile(fileHash); } } @@ -230,10 +213,8 @@ bool Resource::getFileHandle(const char *file, uint32 *size, Common::File &fileh if (filehandle.open(file)) return true; - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - uint fileHash = Common::hashit_lower(file); - for (;start != _pakfiles.end(); ++start) { + for (ResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) { if (!(*start)->isOpen()) continue; @@ -249,15 +230,13 @@ bool Resource::getFileHandle(const char *file, uint32 *size, Common::File &fileh return false; } -uint32 Resource::getFileSize(const char *file) { - Common::List<ResourceFile*>::iterator start = _pakfiles.begin(); - +uint32 Resource::getFileSize(const char *file) const { Common::File temp; if (temp.open(file)) return temp.size(); uint fileHash = Common::hashit_lower(file); - for (;start != _pakfiles.end(); ++start) { + for (ConstResIterator start = _pakfiles.begin() ;start != _pakfiles.end(); ++start) { if (!(*start)->isOpen()) continue; @@ -288,7 +267,6 @@ bool Resource::loadFileToBuf(const char *file, void *buf, uint32 maxSize) { /////////////////////////////////////////// // Pak file manager -#define PAKFile_Iterate Common::List<PakChunk>::iterator start=_files.begin();start != _files.end(); ++start PAKFile::PAKFile(const char *file, const char *physfile, Common::File &pakfile, bool isAmiga) : ResourceFile() { _open = false; @@ -302,10 +280,10 @@ PAKFile::PAKFile(const char *file, const char *physfile, Common::File &pakfile, uint32 pos = 0, startoffset = 0, endoffset = 0; - if (!isAmiga) - startoffset = pakfile.readUint32LE(); - else + if (isAmiga) startoffset = pakfile.readUint32BE(); + else + startoffset = pakfile.readUint32LE(); if (startoffset > filesize) { warning("PAK file '%s' is corrupted", file); @@ -340,10 +318,10 @@ PAKFile::PAKFile(const char *file, const char *physfile, Common::File &pakfile, return; } - if (!isAmiga) - endoffset = READ_LE_UINT32(buffer + nameLength); - else + if (isAmiga) endoffset = READ_BE_UINT32(buffer + nameLength); + else + endoffset = READ_LE_UINT32(buffer + nameLength); if (!endoffset) { endoffset = filesize; @@ -380,47 +358,42 @@ PAKFile::~PAKFile() { _files.clear(); } -uint8 *PAKFile::getFile(uint hash) { - for (PAKFile_Iterate) { - if (start->_name == hash) { - Common::File pakfile; - if (!openFile(pakfile)) - return false; - - pakfile.seek(start->_start, SEEK_CUR); - uint8 *buffer = new uint8[start->_size]; - assert(buffer); - pakfile.read(buffer, start->_size); - return buffer; - } - } - return 0; +uint8 *PAKFile::getFile(uint hash) const { + ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); + if (file == _files.end()) + return 0; + + Common::File pakfile; + if (!openFile(pakfile)) + return false; + + pakfile.seek(file->_start, SEEK_CUR); + uint8 *buffer = new uint8[file->_size]; + assert(buffer); + pakfile.read(buffer, file->_size); + return buffer; } -bool PAKFile::getFileHandle(uint hash, Common::File &filehandle) { +bool PAKFile::getFileHandle(uint hash, Common::File &filehandle) const { filehandle.close(); - for (PAKFile_Iterate) { - if (start->_name == hash) { - if (!openFile(filehandle)) - return false; + ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); + if (file == _files.end()) + return false; - filehandle.seek(start->_start, SEEK_CUR); - return true; - } - } - return false; + if (!openFile(filehandle)) + return false; + + filehandle.seek(file->_start, SEEK_CUR); + return true; } -uint32 PAKFile::getFileSize(uint hash) { - for (PAKFile_Iterate) { - if (start->_name == hash) - return start->_size; - } - return 0; +uint32 PAKFile::getFileSize(uint hash) const { + ConstPakIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); + return (file != _files.end()) ? file->_size : 0; } -bool PAKFile::openFile(Common::File &filehandle) { +bool PAKFile::openFile(Common::File &filehandle) const { filehandle.close(); if (!filehandle.open(_physfile)) @@ -432,7 +405,6 @@ bool PAKFile::openFile(Common::File &filehandle) { /////////////////////////////////////////// // Ins file manager -#define INSFile_Iterate Common::List<FileEntry>::iterator start=_files.begin();start != _files.end(); ++start INSFile::INSFile(const char *file) : ResourceFile(), _files() { Common::File pakfile; _open = false; @@ -477,7 +449,7 @@ INSFile::INSFile(const char *file) : ResourceFile(), _files() { pakfile.seek(3); - for (INSFile_Iterate) { + for (FileIterator start = _files.begin(); start != _files.end(); ++start) { filesize = pakfile.readUint32LE(); start->_size = filesize; start->_start = pakfile.pos(); @@ -495,42 +467,39 @@ INSFile::~INSFile() { _files.clear(); } -uint8 *INSFile::getFile(uint hash) { - for (INSFile_Iterate) { - if (start->_name == hash) { - Common::File pakfile; - if (!pakfile.open(_physfile)) - return false; - - pakfile.seek(start->_start); - uint8 *buffer = new uint8[start->_size]; - assert(buffer); - pakfile.read(buffer, start->_size); - return buffer; - } - } - return 0; +uint8 *INSFile::getFile(uint hash) const { + ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); + if (file == _files.end()) + return 0; + + Common::File pakfile; + if (!pakfile.open(_physfile)) + return false; + + pakfile.seek(file->_start); + uint8 *buffer = new uint8[file->_size]; + assert(buffer); + pakfile.read(buffer, file->_size); + return buffer; } -bool INSFile::getFileHandle(uint hash, Common::File &filehandle) { - for (INSFile_Iterate) { - if (start->_name == hash) { - if (!filehandle.open(_physfile)) - return false; +bool INSFile::getFileHandle(uint hash, Common::File &filehandle) const { + ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); - filehandle.seek(start->_start, SEEK_CUR); - return true; - } - } - return false; + if (file == _files.end()) + return false; + + if (!filehandle.open(_physfile)) + return false; + + filehandle.seek(file->_start, SEEK_CUR); + return true; } -uint32 INSFile::getFileSize(uint hash) { - for (INSFile_Iterate) { - if (start->_name == hash) - return start->_size; - } - return 0; +uint32 INSFile::getFileSize(uint hash) const { + ConstFileIterator file = Common::find_if(_files.begin(), _files.end(), Common::bind2nd(Common::EqualTo<uint>(), hash)); + return (file != _files.end()) ? file->_size : 0; } } // end of namespace Kyra + diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 27e3917c3f..1e8eddcc4f 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -38,9 +38,9 @@ public: ResourceFile() : _open(false), _protected(false), _filename() {} virtual ~ResourceFile() {} - virtual uint8 *getFile(uint file) = 0; - virtual bool getFileHandle(uint file, Common::File &filehandle) = 0; - virtual uint32 getFileSize(uint file) = 0; + virtual uint8 *getFile(uint file) const = 0; + virtual bool getFileHandle(uint file, Common::File &filehandle) const = 0; + virtual uint32 getFileSize(uint file) const = 0; uint filename() const { return _filename; } @@ -62,21 +62,25 @@ class PAKFile : public ResourceFile { uint _name; uint32 _start; uint32 _size; + + operator uint() const { return _name; } }; public: PAKFile(const char *file, const char *physfile, Common::File &pakfile, bool isAmiga = false); ~PAKFile(); - uint8 *getFile(uint file); - bool getFileHandle(uint file, Common::File &filehandle); - uint32 getFileSize(uint file); + uint8 *getFile(uint file) const; + bool getFileHandle(uint file, Common::File &filehandle) const; + uint32 getFileSize(uint file) const; private: - bool openFile(Common::File &filehandle); + bool openFile(Common::File &filehandle) const; Common::String _physfile; uint32 _physOffset; + typedef Common::List<PakChunk>::iterator PakIterator; + typedef Common::List<PakChunk>::const_iterator ConstPakIterator; Common::List<PakChunk> _files; // the entries }; @@ -86,15 +90,19 @@ class INSFile : public ResourceFile { uint _name; uint32 _start; uint32 _size; + + operator uint() const { return _name; } }; public: INSFile(const char *file); ~INSFile(); - uint8 *getFile(uint file); - bool getFileHandle(uint file, Common::File &filehandle); - uint32 getFileSize(uint file); + uint8 *getFile(uint file) const; + bool getFileHandle(uint file, Common::File &filehandle) const; + uint32 getFileSize(uint file) const; protected: + typedef Common::List<FileEntry>::iterator FileIterator; + typedef Common::List<FileEntry>::const_iterator ConstFileIterator; Common::List<FileEntry> _files; // the entries Common::String _physfile; @@ -105,12 +113,12 @@ public: Resource(KyraEngine *vm); ~Resource(); - bool loadPakFile(const Common::String &filename, const bool forcePC = false); + bool loadPakFile(const Common::String &filename); void unloadPakFile(const Common::String &filename); - bool isInPakList(const Common::String &filename); + bool isInPakList(const Common::String &filename) const; - uint32 getFileSize(const char *file); - uint8* fileData(const char *file, uint32 *size); + uint32 getFileSize(const char *file) const; + uint8* fileData(const char *file, uint32 *size) const; // it gives back a file handle (used for the speech player) // it could be that the needed file is embedded in the returned // handle @@ -119,6 +127,9 @@ public: bool loadFileToBuf(const char *file, void *buf, uint32 maxSize); protected: + typedef Common::List<ResourceFile*>::iterator ResIterator; + typedef Common::List<ResourceFile*>::const_iterator ConstResIterator; + KyraEngine *_vm; Common::List<ResourceFile*> _pakfiles; }; @@ -303,3 +314,4 @@ private: } // end of namespace Kyra #endif + diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index f401148613..c857bcc765 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -126,19 +126,15 @@ void KyraEngine::loadGame(const char *fileName) { _marbleVaseItem = in->readSint16BE(); _itemInHand = in->readByte(); - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) _birthstoneGemTable[i] = in->readByte(); - } - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) _idolGemsTable[i] = in->readByte(); - } - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) _foyerItemTable[i] = in->readByte(); - } _cauldronState = in->readByte(); - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) _crystalState[i] = in->readByte(); - } _brandonStatusBit = in->readUint16BE(); _brandonStatusBit0x02Flag = in->readByte(); @@ -207,7 +203,6 @@ void KyraEngine::loadGame(const char *fileName) { if (version >= 7) { _curSfxFile = in->readByte(); - // In the first version there this entry was introduced, // it wasn't made sure that _curSfxFile was initialized // so if it's out of bounds we just set it to 0. @@ -225,9 +220,8 @@ void KyraEngine::loadGame(const char *fileName) { _screen->loadBitmap("AMULET3.CPS", 10, 10, 0); if (!queryGameFlag(0xF1)) { for (int i = 0x55; i <= 0x5A; ++i) { - if (queryGameFlag(i)) { + if (queryGameFlag(i)) seq_createAmuletJewel(i-0x55, 10, 1, 1); - } } } _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 8); @@ -308,19 +302,15 @@ void KyraEngine::saveGame(const char *fileName, const char *saveName) { out->writeSint16BE(_marbleVaseItem); out->writeByte(_itemInHand); - for (int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) out->writeByte(_birthstoneGemTable[i]); - } - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) out->writeByte(_idolGemsTable[i]); - } - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) out->writeByte(_foyerItemTable[i]); - } out->writeByte(_cauldronState); - for (int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) out->writeByte(_crystalState[i]); - } out->writeUint16BE(_brandonStatusBit); out->writeByte(_brandonStatusBit0x02Flag); @@ -333,11 +323,10 @@ void KyraEngine::saveGame(const char *fileName, const char *saveName) { for (int i = 0; i < 32; i++) { out->writeByte(_timers[i].active); out->writeSint32BE(_timers[i].countdown); - if (_system->getMillis() >= _timers[i].nextRun) { + if (_system->getMillis() >= _timers[i].nextRun) out->writeUint32BE(0); - } else { + else out->writeUint32BE(_timers[i].nextRun - _system->getMillis()); - } } out->writeUint32BE(sizeof(_flagsTable)); @@ -371,3 +360,4 @@ void KyraEngine::saveGame(const char *fileName, const char *saveName) { delete out; } } // end of namespace Kyra + diff --git a/engines/kyra/scene.cpp b/engines/kyra/scene.cpp index e2f3293753..1cba2e3e68 100644 --- a/engines/kyra/scene.cpp +++ b/engines/kyra/scene.cpp @@ -43,24 +43,23 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int _handleInput = false; _abortWalkFlag = false; _abortWalkFlag2 = false; - // just used for fm towns version, it should only load the sfx music file there + if (_flags.platform == Common::kPlatformFMTowns) { int newSfxFile = -1; - if (_currentCharacter->sceneId == 7 && sceneId == 24) { + if (_currentCharacter->sceneId == 7 && sceneId == 24) newSfxFile = 2; - } else if (_currentCharacter->sceneId == 25 && sceneId == 109) { + else if (_currentCharacter->sceneId == 25 && sceneId == 109) newSfxFile = 3; - } else if (_currentCharacter->sceneId == 120 && sceneId == 37) { + else if (_currentCharacter->sceneId == 120 && sceneId == 37) newSfxFile = 4; - } else if (_currentCharacter->sceneId == 52 && sceneId == 199) { + else if (_currentCharacter->sceneId == 52 && sceneId == 199) newSfxFile = 5; - } else if (_currentCharacter->sceneId == 37 && sceneId == 120) { + else if (_currentCharacter->sceneId == 37 && sceneId == 120) newSfxFile = 3; - } else if (_currentCharacter->sceneId == 109 && sceneId == 25) { + else if (_currentCharacter->sceneId == 109 && sceneId == 25) newSfxFile = 2; - } else if (_currentCharacter->sceneId == 24 && sceneId == 7) { + else if (_currentCharacter->sceneId == 24 && sceneId == 7) newSfxFile = 1; - } if (newSfxFile != -1) { _curSfxFile = newSfxFile; @@ -128,16 +127,14 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int moveCharacterToPos(0, facing, xpos, ypos); } - for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) { + for (int i = 0; i < ARRAYSIZE(_movieObjects); ++i) _movieObjects[i]->close(); - } if (!brandonAlive) { _scriptInterpreter->initScript(_scriptClick, _scriptClickData); _scriptInterpreter->startScript(_scriptClick, 5); - while (_scriptInterpreter->validScript(_scriptClick)) { + while (_scriptInterpreter->validScript(_scriptClick)) _scriptInterpreter->runScript(_scriptClick); - } } memset(_entranceMouseCursorTracks, 0xFFFF, sizeof(uint16)*4); @@ -166,22 +163,17 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int _walkBlockSouth = currentRoom->southExit; _walkBlockWest = currentRoom->westExit; - if (_walkBlockNorth == 0xFFFF) { + if (_walkBlockNorth == 0xFFFF) _screen->blockOutRegion(0, 0, 320, (_northExitHeight & 0xFF)+3); - } - if (_walkBlockEast == 0xFFFF) { + if (_walkBlockEast == 0xFFFF) _screen->blockOutRegion(312, 0, 8, 139); - } - if (_walkBlockSouth == 0xFFFF) { + if (_walkBlockSouth == 0xFFFF) _screen->blockOutRegion(0, 135, 320, 8); - } - if (_walkBlockWest == 0xFFFF) { + if (_walkBlockWest == 0xFFFF) _screen->blockOutRegion(0, 0, 8, 139); - } - if (!brandonAlive) { + if (!brandonAlive) updatePlayerItemsForScene(); - } startSceneScript(brandonAlive); setupSceneItems(); @@ -190,9 +182,8 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int _loopFlag2 = 0; _screen->showMouse(); - if (!brandonAlive) { + if (!brandonAlive) seq_poisonDeathNow(0); - } updateMousePointer(true); _changedScene = true; } @@ -200,6 +191,7 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int void KyraEngine::transcendScenes(int roomIndex, int roomName) { debugC(9, kDebugLevelMain, "KyraEngine::transcendScenes(%d, %d)", roomIndex, roomName); assert(roomIndex < _roomTableSize); + if (_flags.isTalkie) { char file[32]; assert(roomIndex < _roomTableSize); @@ -209,6 +201,7 @@ void KyraEngine::transcendScenes(int roomIndex, int roomName) { strcat(file, ".VRM"); _res->unloadPakFile(file); } + _roomTable[roomIndex].nameIndex = roomName; _unkScreenVar2 = 1; _unkScreenVar3 = 1; @@ -238,6 +231,7 @@ void KyraEngine::moveCharacterToPos(int character, int facing, int xpos, int ypo disableTimer(14); disableTimer(18); uint32 nextFrame = 0; + switch (facing) { case 0: while (ypos < ch->y1) { @@ -274,6 +268,7 @@ void KyraEngine::moveCharacterToPos(int character, int facing, int xpos, int ypo default: break; } + enableTimer(19); enableTimer(14); enableTimer(18); @@ -288,13 +283,13 @@ void KyraEngine::setCharacterPositionWithUpdate(int character) { _animator->updateAllObjectShapes(); updateTextFade(); - if (_currentCharacter->sceneId == 210) { + if (_currentCharacter->sceneId == 210) updateKyragemFading(); - } } int KyraEngine::setCharacterPosition(int character, int *facingTable) { debugC(9, kDebugLevelMain, "KyraEngine::setCharacterPosition(%d, %p)", character, (const void *)facingTable); + if (character == 0) { _currentCharacter->x1 += _charXPosTable[_currentCharacter->facing]; _currentCharacter->y1 += _charYPosTable[_currentCharacter->facing]; @@ -303,9 +298,8 @@ int KyraEngine::setCharacterPosition(int character, int *facingTable) { } else { _characterList[character].x1 += _charXPosTable[_characterList[character].facing]; _characterList[character].y1 += _charYPosTable[_characterList[character].facing]; - if (_characterList[character].sceneId == _currentCharacter->sceneId) { + if (_characterList[character].sceneId == _currentCharacter->sceneId) setCharacterPositionHelper(character, 0); - } } return 0; } @@ -335,24 +329,21 @@ void KyraEngine::setCharacterPositionHelper(int character, int *facingTable) { if (facing - 1 != 0) { if (facing != 4) { if (facing == 3 || facing == 5) { - if (facingIsFour[character] > 2) { + if (facingIsFour[character] > 2) facing = 4; - } resetTables = true; } } else { ++facingIsFour[character]; } } else { - if (facingIsZero[character] > 2) { + if (facingIsZero[character] > 2) facing = 0; - } resetTables = true; } } else { - if (facingIsZero[character] > 2) { + if (facingIsZero[character] > 2) facing = 0; - } resetTables = true; } @@ -373,35 +364,26 @@ void KyraEngine::setCharacterPositionHelper(int character, int *facingTable) { }; if (facing == 0) { - if (maxAnimationFrame[36+character] > ch->currentAnimFrame) { + if (maxAnimationFrame[36+character] > ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[36+character]; - } - if (maxAnimationFrame[30+character] < ch->currentAnimFrame) { + if (maxAnimationFrame[30+character] < ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[36+character]; - } } else if (facing == 4) { - if (maxAnimationFrame[18+character] > ch->currentAnimFrame) { + if (maxAnimationFrame[18+character] > ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[18+character]; - } - if (maxAnimationFrame[12+character] < ch->currentAnimFrame) { + if (maxAnimationFrame[12+character] < ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[18+character]; - } } else { - if (maxAnimationFrame[18+character] < ch->currentAnimFrame) { + if (maxAnimationFrame[18+character] < ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[30+character]; - } - if (maxAnimationFrame[character] == ch->currentAnimFrame) { + if (maxAnimationFrame[character] == ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[6+character]; - } - if (maxAnimationFrame[character] < ch->currentAnimFrame) { + if (maxAnimationFrame[character] < ch->currentAnimFrame) ch->currentAnimFrame = maxAnimationFrame[6+character]+2; - } } - if (character == 0) { - if (_brandonStatusBit & 0x10) - ch->currentAnimFrame = 88; - } + if (character == 0 && (_brandonStatusBit & 0x10)) + ch->currentAnimFrame = 88; _animator->animRefreshNPC(character); } @@ -455,23 +437,21 @@ void KyraEngine::startSceneScript(int brandonAlive) { _exitListPtr = 0; _scaleMode = 1; - for (int i = 0; i < 145; ++i) { + for (int i = 0; i < 145; ++i) _scaleTable[i] = 256; - } clearNoDropRects(); _scriptInterpreter->initScript(_scriptClick, _scriptClickData); strcpy(fileNameBuffer, _roomFilenameTable[tableId]); strcat(fileNameBuffer, ".EMC"); _scriptInterpreter->unloadScript(_scriptClickData); - _scriptInterpreter->loadScript(fileNameBuffer, _scriptClickData, 0); + _scriptInterpreter->loadScript(fileNameBuffer, _scriptClickData, &_opcodes); _scriptInterpreter->startScript(_scriptClick, 0); _scriptClick->variables[0] = _currentCharacter->sceneId; _scriptClick->variables[7] = brandonAlive; - while (_scriptInterpreter->validScript(_scriptClick)) { + while (_scriptInterpreter->validScript(_scriptClick)) _scriptInterpreter->runScript(_scriptClick); - } } void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) { @@ -512,26 +492,20 @@ void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) { break; } - if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) { + if ((uint8)(_northExitHeight & 0xFF) + 2 >= ypos) ypos = (_northExitHeight & 0xFF) + 4; - } - if (xpos >= 308) { + if (xpos >= 308) xpos = 304; - } - if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) { + if ((uint8)(_northExitHeight >> 8) - 2 <= ypos) ypos = (_northExitHeight >> 8) - 4; - } - if (xpos <= 12) { + if (xpos <= 12) xpos = 16; - } } - if (_brandonPosX > -1) { + if (_brandonPosX > -1) xpos = _brandonPosX; - } - if (_brandonPosY > -1) { + if (_brandonPosY > -1) ypos = _brandonPosY; - } int16 ypos2 = 0; if (_brandonPosX > -1 && _brandonPosY > -1) { @@ -640,34 +614,32 @@ void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) { initSceneObjectList(brandonAlive); - if (unk1 && brandonAlive == 0) { + if (unk1 && brandonAlive == 0) moveCharacterToPos(0, facing, xpos2, ypos2); - } _scriptClick->variables[4] = _itemInHand; _scriptClick->variables[7] = brandonAlive; _scriptInterpreter->startScript(_scriptClick, 3); - while (_scriptInterpreter->validScript(_scriptClick)) { + while (_scriptInterpreter->validScript(_scriptClick)) _scriptInterpreter->runScript(_scriptClick); - } } void KyraEngine::initSceneObjectList(int brandonAlive) { debugC(9, kDebugLevelMain, "KyraEngine::initSceneObjectList(%d)", brandonAlive); - for (int i = 0; i < 28; ++i) { + for (int i = 0; i < 28; ++i) _animator->actors()[i].active = 0; - } int startAnimFrame = 0; AnimObject *curAnimState = _animator->actors(); curAnimState->active = 1; curAnimState->drawY = _currentCharacter->y1; - curAnimState->sceneAnimPtr = _shapes[4+_currentCharacter->currentAnimFrame]; + curAnimState->sceneAnimPtr = _shapes[_currentCharacter->currentAnimFrame]; curAnimState->animFrameNumber = _currentCharacter->currentAnimFrame; startAnimFrame = _currentCharacter->currentAnimFrame-7; int xOffset = _defaultShapeTable[startAnimFrame].xOffset; int yOffset = _defaultShapeTable[startAnimFrame].yOffset; + if (_scaleMode) { curAnimState->x1 = _currentCharacter->x1; curAnimState->y1 = _currentCharacter->y1; @@ -681,6 +653,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) { curAnimState->x1 = _currentCharacter->x1 + xOffset; curAnimState->y1 = _currentCharacter->y1 + yOffset; } + curAnimState->x2 = curAnimState->x1; curAnimState->y2 = curAnimState->y1; curAnimState->refreshFlag = 1; @@ -703,7 +676,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) { } curAnimState->drawY = ch->y1; - curAnimState->sceneAnimPtr = _shapes[4+ch->currentAnimFrame]; + curAnimState->sceneAnimPtr = _shapes[ch->currentAnimFrame]; curAnimState->animFrameNumber = ch->currentAnimFrame; startAnimFrame = ch->currentAnimFrame-7; xOffset = _defaultShapeTable[startAnimFrame].xOffset; @@ -727,11 +700,10 @@ void KyraEngine::initSceneObjectList(int brandonAlive) { curAnimState->refreshFlag = 1; curAnimState->bkgdChangeFlag = 1; - if (ch->facing >= 1 && ch->facing <= 3) { + if (ch->facing >= 1 && ch->facing <= 3) curAnimState->flags |= 1; - } else if (ch->facing >= 5 && ch->facing <= 7) { + else if (ch->facing >= 5 && ch->facing <= 7) curAnimState->flags &= 0xFFFFFFFE; - } _animator->addObjectToQueue(curAnimState); @@ -782,7 +754,7 @@ void KyraEngine::initSceneObjectList(int brandonAlive) { byte curItem = curRoom->itemsTable[i]; if (curItem != 0xFF) { curAnimState->drawY = curRoom->itemsYPos[i]; - curAnimState->sceneAnimPtr = _shapes[220+curItem]; + curAnimState->sceneAnimPtr = _shapes[216+curItem]; curAnimState->animFrameNumber = (int16)0xFFFF; curAnimState->y1 = curRoom->itemsYPos[i]; curAnimState->x1 = curRoom->itemsXPos[i]; @@ -827,9 +799,8 @@ void KyraEngine::initSceneScreen(int brandonAlive) { if (_flags.platform == Common::kPlatformAmiga) { if (_unkScreenVar1 && !queryGameFlag(0xF0)) { memset(_screen->getPalette(2), 0, 32*3); - if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3)) { + if (_currentCharacter->sceneId != 117 || !queryGameFlag(0xB3)) _screen->setScreenPalette(_screen->getPalette(2)); - } } if (_unkScreenVar2 == 1) @@ -838,13 +809,11 @@ void KyraEngine::initSceneScreen(int brandonAlive) { _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); if (_unkScreenVar1 && !queryGameFlag(0xA0)) { - if (_currentCharacter->sceneId == 45 && _paletteChanged) { + if (_currentCharacter->sceneId == 45 && _paletteChanged) memcpy(_screen->getPalette(0) + 12*3, _screen->getPalette(4) + 12*3, 2); - } - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) { + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1)) memcpy(_screen->getPalette(0), _screen->getPalette(0) + 320*3, 64); - } _screen->setScreenPalette(_screen->getPalette(0)); } @@ -859,11 +828,10 @@ void KyraEngine::initSceneScreen(int brandonAlive) { _screen->setScreenPalette(_screen->getPalette(0)); } - if (_unkScreenVar2 == 1) { + if (_unkScreenVar2 == 1) _screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false); - } else { + else _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); - } if (_unkScreenVar1 && _paletteChanged) { if (!queryGameFlag(0xA0)) { @@ -902,11 +870,12 @@ void KyraEngine::initSceneScreen(int brandonAlive) { int KyraEngine::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) { debugC(9, kDebugLevelMain, "KyraEngine::handleSceneChange(%d, %d, %d, %d)", xpos, ypos, unk1, frameReset); - if (queryGameFlag(0xEF)) { + if (queryGameFlag(0xEF)) unk1 = 0; - } + int sceneId = _currentCharacter->sceneId; _pathfinderFlag = 0; + if (xpos < 12) { if (_roomTable[sceneId].westExit != 0xFFFF) { xpos = 12; @@ -938,31 +907,32 @@ int KyraEngine::handleSceneChange(int xpos, int ypos, int unk1, int frameReset) int temp = xpos - _currentCharacter->x1; if (ABS(temp) < 4) { temp = ypos - _currentCharacter->y1; - if (ABS(temp) < 2) { + if (ABS(temp) < 2) return 0; - } } int x = (int16)(_currentCharacter->x1 & 0xFFFC); int y = (int16)(_currentCharacter->y1 & 0xFFFE); xpos = (int16)(xpos & 0xFFFC); ypos = (int16)(ypos & 0xFFFE); + int ret = findWay(x, y, xpos, ypos, _movFacingTable, 150); _pathfinderFlag = 0; - if (ret >= _lastFindWayRet) { + + if (ret >= _lastFindWayRet) _lastFindWayRet = ret; - } - if (ret == 0x7D00 || ret == 0) { + + if (ret == 0x7D00 || ret == 0) return 0; - } + return processSceneChange(_movFacingTable, unk1, frameReset); } int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) { debugC(9, kDebugLevelMain, "KyraEngine::processSceneChange(%p, %d, %d)", (const void *)table, unk1, frameReset); - if (queryGameFlag(0xEF)) { + if (queryGameFlag(0xEF)) unk1 = 0; - } + int *tableStart = table; _sceneChangeState = 0; _loopFlag2 = 0; @@ -1013,23 +983,22 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) { } } - if (forceContinue || !running) { + if (forceContinue || !running) continue; - } int temp = 0; - if (table == tableStart || table[1] == 8) { + if (table == tableStart || table[1] == 8) temp = setCharacterPosition(0, 0); - } else { + else temp = setCharacterPosition(0, table); - } - if (temp) { + + if (temp) ++table; - } nextFrame = getTimerDelay(5) * _tickLength + _system->getMillis(); while (_system->getMillis() < nextFrame) { updateGameTimers(); + if (_currentCharacter->sceneId == 210) { updateKyragemFading(); if (seq_playEnd() || _beadStateVar == 4 || _beadStateVar == 5) { @@ -1038,14 +1007,15 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) { break; } } + if ((nextFrame - _system->getMillis()) >= 10) delay(10, true); } } - if (frameReset && !(_brandonStatusBit & 2)) { + if (frameReset && !(_brandonStatusBit & 2)) _currentCharacter->currentAnimFrame = 7; - } + _animator->animRefreshNPC(0); _animator->updateAllObjectShapes(); return returnValue; @@ -1054,9 +1024,8 @@ int KyraEngine::processSceneChange(int *table, int unk1, int frameReset) { int KyraEngine::changeScene(int facing) { debugC(9, kDebugLevelMain, "KyraEngine::changeScene(%d)", facing); if (queryGameFlag(0xEF)) { - if (_currentCharacter->sceneId == 5) { + if (_currentCharacter->sceneId == 5) return 0; - } } int xpos = _charXPosTable[facing] + _currentCharacter->x1; @@ -1069,7 +1038,7 @@ int KyraEngine::changeScene(int facing) { if (_exitListPtr) { int16 *ptr = _exitListPtr; - // this loop should be only entered on time, seems to be some hack in the original + // this loop should be only entered one time, seems to be some hack in the original while (true) { if (*ptr == -1) break; @@ -1078,12 +1047,14 @@ int KyraEngine::changeScene(int facing) { ptr += 10; break; } + _brandonPosX = ptr[6]; _brandonPosY = ptr[7]; uint16 sceneId = ptr[5]; facing = ptr[4]; int unk1 = ptr[8]; int unk2 = ptr[9]; + if (sceneId == 0xFFFF) { switch (facing) { case 0: @@ -1179,12 +1150,14 @@ void KyraEngine::setCharactersInDefaultScene() { for (int i = 1; i < 5; ++i) { Character *cur = &_characterList[i]; //cur->field_20 = 0; + const uint32 *curTable = defaultSceneTable[i-1]; cur->sceneId = curTable[0]; - if (cur->sceneId == _currentCharacter->sceneId) { + + if (cur->sceneId == _currentCharacter->sceneId) //++cur->field_20; cur->sceneId = curTable[1/*cur->field_20*/]; - } + //cur->field_23 = curTable[cur->field_20+1]; } } @@ -1199,6 +1172,7 @@ void KyraEngine::setCharactersPositions(int character) { 0x67, 0x67, 0x60, 0x5A, 0x71, 0x76 }; + assert(character < ARRAYSIZE(initXPosTable)); Character *edit = &_characterList[character]; edit->x1 = edit->x2 = initXPosTable[character]; @@ -1291,9 +1265,8 @@ int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int move } } - if (temp != 0x7D00 || tempValue != 0x7D00) { + if (temp != 0x7D00 || tempValue != 0x7D00) break; - } } if (temp < tempValue) { @@ -1315,10 +1288,10 @@ int KyraEngine::findWay(int x, int y, int toX, int toY, int *moveTable, int move } x = curX; y = curY; - if (curX == toX && curY == toY) { + if (curX == toX && curY == toY) break; - } } + delete [] pathTable1; delete [] pathTable2; moveTable[lastUsedEntry] = 8; @@ -1351,9 +1324,8 @@ int KyraEngine::findSubPath(int x, int y, int toX, int toY, int *moveTable, int while (true) { changePosTowardsFacing(xpos1, ypos1, facingTable1[start*8 + newFacing2]); if (!lineIsPassable(xpos1, ypos1)) { - if (facingTable1[start*8 + newFacing2] == newFacing) { + if (facingTable1[start*8 + newFacing2] == newFacing) return 0x7D00; - } newFacing2 = facingTable1[start*8 + newFacing2]; xpos1 = x; ypos1 = y; @@ -1378,19 +1350,20 @@ int KyraEngine::findSubPath(int x, int y, int toX, int toY, int *moveTable, int } } } + moveTable[position++] = newFacing; x = xpos1; y = ypos1; - if (x == toX && y == toY) { + + if (x == toX && y == toY) return position; - } - if (xpos1 == xpos2 && ypos1 == ypos2) { + if (xpos1 == xpos2 && ypos1 == ypos2) break; - } newFacing = facingTable3[start*8 + newFacing]; } + return 0x7D00; } @@ -1432,6 +1405,7 @@ int KyraEngine::getFacingFromPointToPoint(int x, int y, int toX, int toY) { } else { facingEntry <<= 1; } + assert(facingEntry < ARRAYSIZE(facingTable)); return facingTable[facingEntry]; } @@ -1471,13 +1445,11 @@ bool KyraEngine::lineIsPassable(int x, int y) { return true; } - if (y > 137) { + if (y > 137) return false; - } - if (y < 0) { + if (y < 0) y = 0; - } int ypos = 8; if (_scaleMode) { @@ -1541,19 +1513,19 @@ int KyraEngine::getMoveTableSize(int *moveTable) { } if (tempPosition == moveTable && *tempPosition == 9) { - while (*tempPosition != 8 && *tempPosition == 9) { + while (*tempPosition != 8 && *tempPosition == 9) ++tempPosition; - } - if (*tempPosition == 8) { + + if (*tempPosition == 8) return 0; - } } oldPosition = tempPosition; curPosition = oldPosition+1; - while (*curPosition != 8 && *curPosition == 9) { + + while (*curPosition != 8 && *curPosition == 9) ++curPosition; - } + continue; } @@ -1566,20 +1538,19 @@ int KyraEngine::getMoveTableSize(int *moveTable) { curPosition = oldPosition; oldPosition = tempPosition; while (true) { - if (tempPosition == moveTable) { + if (tempPosition == moveTable) break; - } + --tempPosition; - if (*tempPosition != 9) { + if (*tempPosition != 9) break; - } + } } else { while (true) { ++curPosition; - if (*curPosition != 9) { + if (*curPosition != 9) break; - } } } continue; @@ -1588,11 +1559,11 @@ int KyraEngine::getMoveTableSize(int *moveTable) { tempPosition = oldPosition; oldPosition = curPosition; ++retValue; + while (true) { ++curPosition; - if (*curPosition != 9) { + if (*curPosition != 9) break; - } } } @@ -1614,9 +1585,11 @@ void KyraEngine::setupSceneResource(int sceneId) { strcpy(file, _roomFilenameTable[tableId]); strcat(file, ".VRM"); _res->unloadPakFile(file); + strcpy(file, _roomFilenameTable[tableId]); strcat(file, ".PAK"); - _res->unloadPakFile(file); + _res->unloadPakFile(file); + strcpy(file, _roomFilenameTable[tableId]); strcat(file, ".APK"); _res->unloadPakFile(file); @@ -1632,10 +1605,12 @@ void KyraEngine::setupSceneResource(int sceneId) { strcat(file, ".VRM"); if (Common::File::exists(file)) _res->loadPakFile(file); + strcpy(file, _roomFilenameTable[tableId]); strcat(file, ".PAK"); if (Common::File::exists(file)) _res->loadPakFile(file); + strcpy(file, _roomFilenameTable[tableId]); strcat(file, ".APK"); if (Common::File::exists(file)) @@ -1643,3 +1618,4 @@ void KyraEngine::setupSceneResource(int sceneId) { } } // end of namespace Kyra + diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index ef3e7badfa..d160b35736 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -37,17 +37,19 @@ Screen::Screen(KyraEngine *vm, OSystem *system) } Screen::~Screen() { - for (int i = 0; i < SCREEN_OVLS_NUM; ++i) { + for (int i = 0; i < SCREEN_OVLS_NUM; ++i) delete [] _sjisOverlayPtrs[i]; - } + for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) { delete [] _pagePtrs[pageNum]; _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0; } + for (int f = 0; f < ARRAYSIZE(_fonts); ++f) { delete[] _fonts[f].fontData; _fonts[f].fontData = NULL; } + delete [] _sjisFontData; delete [] _sjisTempPage; delete [] _currentPalette; @@ -56,16 +58,21 @@ Screen::~Screen() { delete [] _animBlockPtr; if (_vm->gameFlags().platform != Common::kPlatformAmiga) { - for (int i = 0; i < ARRAYSIZE(_palettes); ++i) { + for (int i = 0; i < ARRAYSIZE(_palettes); ++i) delete [] _palettes[i]; - } } delete [] _bitBlitRects; + for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { delete [] _saveLoadPage[i]; _saveLoadPage[i] = 0; } + + for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) { + delete [] _saveLoadPageOvl[i]; + _saveLoadPageOvl[i] = 0; + } delete [] _unkPtr1; delete [] _unkPtr2; @@ -135,9 +142,8 @@ bool Screen::init() { assert(_currentPalette); memset(_currentPalette, 0, 1248); - for (int i = 0; i < 6; ++i) { + for (int i = 0; i < 6; ++i) _palettes[i] = _currentPalette + (i+1)*96; - } } else { _currentPalette = new uint8[768]; assert(_currentPalette); @@ -154,9 +160,8 @@ bool Screen::init() { _charWidth = 0; _charOffset = 0; memset(_fonts, 0, sizeof(_fonts)); - for (int i = 0; i < ARRAYSIZE(_textColorsMap); ++i) { + for (int i = 0; i < ARRAYSIZE(_textColorsMap); ++i) _textColorsMap[i] = i; - } _decodeShapeBuffer = NULL; _decodeShapeBufferSize = 0; _animBlockPtr = NULL; @@ -169,6 +174,7 @@ bool Screen::init() { memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS); _bitBlitNum = 0; memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); + memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl)); _unkPtr1 = new uint8[getRectSize(1, 144)]; assert(_unkPtr1); @@ -361,7 +367,7 @@ void Screen::fadeSpecialPalette(int palIndex, int startIndex, int size, int fade void Screen::fadePalette(const uint8 *palData, int delay) { debugC(9, kDebugLevelScreen, "Screen::fadePalette(%p, %d)", (const void *)palData, delay); - updateDirtyRects(); + updateScreen(); uint8 fadePal[768]; memcpy(fadePal, _screenPalette, 768); @@ -372,17 +378,18 @@ void Screen::fadePalette(const uint8 *palData, int delay) { maxDiff = diff; } } + int16 delayInc = delay << 8; - if (maxDiff != 0) { + if (maxDiff != 0) delayInc /= maxDiff; - } + delay = delayInc; for (diff = 1; diff <= maxDiff; ++diff) { - if (delayInc >= 512) { + if (delayInc >= 512) break; - } delayInc += delay; } + int delayAcc = 0; while (!_vm->quit()) { delayAcc += delayInc; @@ -394,22 +401,23 @@ void Screen::fadePalette(const uint8 *palData, int delay) { needRefresh = true; if (c1 > c2) { c2 += diff; - if (c1 < c2) { + if (c1 < c2) c2 = c1; - } } + if (c1 < c2) { c2 -= diff; - if (c1 > c2) { + if (c1 > c2) c2 = c1; - } } + fadePal[i] = (uint8)c2; } } - if (!needRefresh) { + + if (!needRefresh) break; - } + setScreenPalette(fadePal); _system->updateScreen(); //_system->delayMillis((delayAcc >> 8) * 1000 / 60); @@ -511,9 +519,8 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag if (flags & CR_X_FLIPPED) { while (h--) { for (int i = 0; i < w; ++i) { - if (src[i] || (flags & CR_NO_P_CHECK)) { + if (src[i] || (flags & CR_NO_P_CHECK)) dst[w-i] = src[i]; - } } src += SCREEN_W; dst += SCREEN_W; @@ -521,9 +528,8 @@ void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPag } else { while (h--) { for (int i = 0; i < w; ++i) { - if (src[i] || (flags & CR_NO_P_CHECK)) { + if (src[i] || (flags & CR_NO_P_CHECK)) dst[i] = src[i]; - } } src += SCREEN_W; dst += SCREEN_W; @@ -535,9 +541,9 @@ void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 * debugC(9, kDebugLevelScreen, "Screen::copyRegionToBuffer(%d, %d, %d, %d, %d)", pageNum, x, y, w, h); assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H && dest); uint8 *pagePtr = getPagePtr(pageNum); - for (int i = y; i < y + h; i++) { + + for (int i = y; i < y + h; i++) memcpy(dest + (i - y) * w, pagePtr + i * SCREEN_W + x, w); - } } void Screen::copyPage(uint8 srcPage, uint8 dstPage) { @@ -570,22 +576,22 @@ void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint void Screen::copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src) { debugC(9, kDebugLevelScreen, "Screen::copyFromCurPageBlock(%d, %d, %d, %d, %p)", x, y, w, h, (const void *)src); - if (x < 0) { + if (x < 0) x = 0; - } else if (x >= 40) { + else if (x >= 40) return; - } - if (x + w > 40) { + + if (x + w > 40) w = 40 - x; - } - if (y < 0) { + + if (y < 0) y = 0; - } else if (y >= 200) { + else if (y >= 200) return; - } - if (y + h > 200) { + + if (y + h > 200) h = 200 - y; - } + uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x * 8; if (_curPage == 0 || _curPage == 1) @@ -603,22 +609,22 @@ void Screen::copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src) void Screen::copyCurPageBlock(int x, int y, int w, int h, uint8 *dst) { debugC(9, kDebugLevelScreen, "Screen::copyCurPageBlock(%d, %d, %d, %d, %p)", x, y, w, h, (const void *)dst); assert(dst); - if (x < 0) { + if (x < 0) x = 0; - } else if (x >= 40) { + else if (x >= 40) return; - } - if (x + w > 40) { + + if (x + w > 40) w = 40 - x; - } - if (y < 0) { + + if (y < 0) y = 0; - } else if (y >= 200) { + else if (y >= 200) return; - } - if (y + h > 200) { + + if (y + h > 200) h = 200 - y; - } + const uint8 *src = getPagePtr(_curPage) + y * SCREEN_W + x * 8; while (h--) { memcpy(dst, src, w*8); @@ -632,9 +638,9 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag assert(sx >= 0 && w <= SCREEN_W); int x; uint16 x_offs[SCREEN_W]; - for (x = 0; x < SCREEN_W; ++x) { + for (x = 0; x < SCREEN_W; ++x) x_offs[x] = x; - } + for (x = 0; x < w; ++x) { int i = _vm->_rnd.getRandomNumber(w - 1); SWAP(x_offs[x], x_offs[i]); @@ -643,9 +649,9 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag assert(sy >= 0 && h <= SCREEN_H); int y; uint8 y_offs[SCREEN_H]; - for (y = 0; y < SCREEN_H; ++y) { + for (y = 0; y < SCREEN_H; ++y) y_offs[y] = y; - } + for (y = 0; y < h; ++y) { int i = _vm->_rnd.getRandomNumber(h - 1); SWAP(y_offs[y], y_offs[i]); @@ -660,22 +666,20 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag int i = sx + x_offs[x]; int j = sy + y_offs[y_cur]; ++y_cur; - if (y_cur >= h) { + if (y_cur >= h) y_cur = 0; - } + uint8 color = getPagePixel(srcPage, i, j); - if (!transparent || color != 0) { + if (!transparent || color != 0) setPagePixel(dstPage, i, j, color); - } } // forcing full update for now _forceFullUpdate = true; updateScreen(); now = (int32)_system->getMillis(); wait = ticks * _vm->tickLength() - (now - start); - if (wait > 0) { + if (wait > 0) _vm->delay(wait); - } } copyOverlayRegion(sx, sy, sx, sy, w, h, srcPage, dstPage); @@ -689,9 +693,9 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum) { debugC(9, kDebugLevelScreen, "Screen::fillRect(%d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, color, pageNum); assert(x2 < SCREEN_W && y2 < SCREEN_H); - if (pageNum == -1) { + if (pageNum == -1) pageNum = _curPage; - } + uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W + x1; if (pageNum == 0 || pageNum == 1) @@ -805,9 +809,7 @@ void Screen::setTextColorMap(const uint8 *cmap) { void Screen::setTextColor(const uint8 *cmap, int a, int b) { debugC(9, kDebugLevelScreen, "Screen::setTextColor(%p, %d, %d)", (const void *)cmap, a, b); - for (int i = a; i <= b; ++i) { - _textColorsMap[i] = *cmap++; - } + memcpy(&_textColorsMap[a], cmap, b-a+1); } bool Screen::loadFont(FontId fontId, const char *filename) { @@ -922,17 +924,16 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2 const uint8 charHeightFnt = *(fnt->fontData + fnt->charSizeOffset + 4); uint8 charHeight = 0; - if (x < 0) { + if (x < 0) x = 0; - } else if (x >= SCREEN_W) { + else if (x >= SCREEN_W) return; - } + int x_start = x; - if (y < 0) { + if (y < 0) y = 0; - } else if (y >= SCREEN_H) { + else if (y >= SCREEN_H) return; - } while (1) { uint c = *str++; @@ -970,18 +971,19 @@ void Screen::drawCharANSI(uint8 c, int x, int y) { debugC(9, kDebugLevelScreen, "Screen::drawChar('%c', %d, %d)", c, x, y); Font *fnt = &_fonts[_currentFont]; uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x; + uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2); - if (bitmapOffset == 0) { + if (bitmapOffset == 0) return; - } + uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c); - if (charWidth + x > SCREEN_W) { + if (charWidth + x > SCREEN_W) return; - } + uint8 charH0 = *(fnt->fontData + fnt->charSizeOffset + 4); - if (charH0 + y > SCREEN_H) { + if (charH0 + y > SCREEN_H) return; - } + uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2); uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1); charH0 -= charH1 + charH2; @@ -992,9 +994,8 @@ void Screen::drawCharANSI(uint8 c, int x, int y) { while (charH1--) { uint8 col = _textColorsMap[0]; for (int i = 0; i < charWidth; ++i) { - if (col != 0) { + if (col != 0) *dst = col; - } ++dst; } dst += pitch; @@ -1021,9 +1022,8 @@ void Screen::drawCharANSI(uint8 c, int x, int y) { while (charH0--) { uint8 col = _textColorsMap[0]; for (int i = 0; i < charWidth; ++i) { - if (col != 0) { + if (col != 0) *dst = col; - } ++dst; } dst += pitch; @@ -1067,19 +1067,21 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int uint8 *table3 = 0; uint8 *table4 = 0; - if (flags & 0x8000) { + if (flags & 0x8000) table2 = va_arg(args, uint8*); - } + if (flags & 0x100) { table = va_arg(args, uint8*); tableLoopCount = va_arg(args, int); if (!tableLoopCount) flags &= 0xFFFFFEFF; } + if (flags & 0x1000) { table3 = va_arg(args, uint8*); table4 = va_arg(args, uint8*); } + if (flags & 0x200) { drawShapeVar1 += 1; drawShapeVar1 &= 7; @@ -1087,12 +1089,15 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int drawShapeVar4 = 0; drawShapeVar5 = 256; } + if (flags & 0x4000) { drawShapeVar5 = va_arg(args, int); } + if (flags & 0x800) { drawLayer = va_arg(args, int); } + int scale_w, scale_h; if (flags & DSF_SCALE) { scale_w = va_arg(args, int); @@ -1105,9 +1110,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int int ppc = (flags >> 8) & 0x3F; const uint8 *src = shapeData; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) src += 2; - } + uint16 shapeFlags = READ_LE_UINT16(src); src += 2; int shapeHeight = *src++; @@ -1132,9 +1137,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int src += 3; uint16 frameSize = READ_LE_UINT16(src); src += 2; - if ((shapeFlags & 1) || (flags & 0x400)) { + if ((shapeFlags & 1) || (flags & 0x400)) src += 0x10; - } + if (!(shapeFlags & 2)) { decodeFrame4(src, _animBlockPtr, frameSize); src = _animBlockPtr; @@ -1146,6 +1151,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int _decodeShapeBuffer = new uint8[shapeSize]; _decodeShapeBufferSize = shapeSize; } + if (!_decodeShapeBuffer) { _decodeShapeBufferSize = 0; va_end(args); @@ -1156,9 +1162,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int // only used if shapeFlag & 1 is NOT zero const uint8 *colorTable = shapeData + 10; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) colorTable += 2; - } for (int j = 0; j < shapeHeight; ++j) { uint8 *dsbNextLine = decodedShapeFrame + shapeWidth; @@ -1168,9 +1173,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int if (code != 0) { // this is guessed if (shapeFlags & 1) { - if (code < 16) { + if (code < 16) *decodedShapeFrame++ = colorTable[code]; - } } else { *decodedShapeFrame++ = code; } @@ -1196,35 +1200,31 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int int x1, x2; if (x >= 0) { x1 = 0; - if (x + scaledShapeWidth < sx2) { + if (x + scaledShapeWidth < sx2) x2 = scaledShapeWidth; - } else { + else x2 = sx2 - x; - } } else { x2 = scaledShapeWidth; x1 = -x; x = 0; - if (x2 > sx2) { + if (x2 > sx2) x2 = sx2; - } } int y1, y2; if (y >= 0) { y1 = 0; - if (y + scaledShapeHeight < sy2) { + if (y + scaledShapeHeight < sy2) y2 = scaledShapeHeight; - } else { + else y2 = sy2 - y; - } } else { y2 = scaledShapeHeight; y1 = -y; y = 0; - if (y2 > sy2) { + if (y2 > sy2) y2 = sy2; - } } uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x; @@ -1235,34 +1235,31 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int int scaleYTable[SCREEN_H]; assert(y1 >= 0 && y2 < SCREEN_H); - for (y = y1; y < y2; ++y) { + for (y = y1; y < y2; ++y) scaleYTable[y] = (y << 8) / scale_h; - } + int scaleXTable[SCREEN_W]; assert(x1 >= 0 && x2 < SCREEN_W); - for (x = x1; x < x2; ++x) { + for (x = x1; x < x2; ++x) scaleXTable[x] = (x << 8) / scale_w; - } const uint8 *shapeBuffer = _decodeShapeBuffer; - if (flags & DSF_Y_FLIPPED) { + if (flags & DSF_Y_FLIPPED) shapeBuffer += shapeWidth * (shapeHeight - 1); - } - if (flags & DSF_X_FLIPPED) { + if (flags & DSF_X_FLIPPED) shapeBuffer += shapeWidth - 1; - } for (y = y1; y < y2; ++y) { uint8 *dstNextLine = dst + SCREEN_W; int j = scaleYTable[y]; - if (flags & DSF_Y_FLIPPED) { + if (flags & DSF_Y_FLIPPED) j = -j; - } + for (x = x1; x < x2; ++x) { int xpos = scaleXTable[x]; - if (flags & DSF_X_FLIPPED) { + if (flags & DSF_X_FLIPPED) xpos = -xpos; - } + uint8 color = shapeBuffer[j * shapeWidth + xpos]; if (color != 0) { switch (ppc) { @@ -1271,9 +1268,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int break; case 1: - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } break; case 2: { @@ -1292,9 +1288,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int case 7: case 3: color = *dst; - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } break; case 4: @@ -1303,9 +1298,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int case 5: color = table2[color]; - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } break; case 6: { @@ -1327,9 +1321,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int uint8 pixel = *(_shapePages[0] + offset); pixel &= 0x7F; pixel &= 0x87; - if (drawLayer < pixel) { + if (drawLayer < pixel) color = *(_shapePages[1] + offset); - } } break; @@ -1338,12 +1331,12 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int uint8 pixel = *(_shapePages[0] + offset); pixel &= 0x7F; pixel &= 0x87; + if (drawLayer < pixel) { color = *(_shapePages[1] + offset); } else { - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } } } break; @@ -1378,9 +1371,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int color = *(_shapePages[1] + offset); } else { color = *dst; - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } } } break; @@ -1407,9 +1399,8 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int color = *(_shapePages[1] + offset); } else { color = table2[color]; - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } } } break; @@ -1447,9 +1438,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int break; case 17: { - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } + uint8 newColor = table3[color]; if (!(newColor & 0x80)) { color = *dst; @@ -1479,9 +1470,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int case 23: case 19: { color = *dst; - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } + uint8 newColor = table3[color]; if (!(newColor & 0x80)) { color = *dst; @@ -1502,9 +1493,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int case 21: { color = table2[color]; - for (int i = 0; i < tableLoopCount; ++i) { + for (int i = 0; i < tableLoopCount; ++i) color = table[color]; - } + uint8 newColor = table3[color]; if (!(newColor & 0x80)) { color = *dst; @@ -1542,9 +1533,9 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int uint8 pixel = *(_shapePages[0] + offset); pixel &= 0x7F; pixel &= 0x87; - if (drawLayer < pixel) { + if (drawLayer < pixel) color = *(_shapePages[1] + offset); - } + uint8 newColor = table3[color]; if (!(newColor & 0x80)) { color = *dst; @@ -1593,44 +1584,43 @@ uint Screen::decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize) { uint8 *dstEnd = dst + dstSize; while (1) { int count = dstEnd - dst; - if (count == 0) { + if (count == 0) break; - } + uint8 code = *src++; if (!(code & 0x80)) { // 8th bit isn't set int len = MIN(count, (code >> 4) + 3); //upper half of code is the length int offs = ((code & 0xF) << 8) | *src++; //lower half of code as byte 2 of offset. const uint8 *dstOffs = dst - offs; - while (len--) { + while (len--) *dst++ = *dstOffs++; - } } else if (code & 0x40) { // 7th bit is set int len = (code & 0x3F) + 3; if (code == 0xFE) { len = READ_LE_UINT16(src); src += 2; - if (len > count) { + if (len > count) len = count; - } + memset(dst, *src++, len); dst += len; } else { if (code == 0xFF) { - len = READ_LE_UINT16(src); src += 2; + len = READ_LE_UINT16(src); + src += 2; } + int offs = READ_LE_UINT16(src); src += 2; - if (len > count) { + if (len > count) len = count; - } + const uint8 *dstOffs = dstOrig + offs; - while (len--) { + while (len--) *dst++ = *dstOffs++; - } } } else if (code != 0x80) { // not just the 8th bit set. //Copy some bytes from source to dest. int len = MIN(count, code & 0x3F); - while (len--) { + while (len--) *dst++ = *src++; - } } else { break; } @@ -1784,6 +1774,7 @@ void Screen::convertAmigaMsc(uint8 *data) { if (flagTable[x&7] & data[y*40+(x>>3)+i*5760]) layer = i; } + if (layer) dst[y*320+x] |= (layer+1); } @@ -1801,11 +1792,11 @@ void Screen::wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitc uint8 len = *src++; code = *src++; while (len--) { - if (noXor) { + if (noXor) *dst++ = code; - } else { + else *dst++ ^= code; - } + if (++count == pitch) { count = 0; dstNext += SCREEN_W; @@ -1833,11 +1824,11 @@ void Screen::wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitc uint16 len = subcode - 0x4000; code = *src++; while (len--) { - if (noXor) { + if (noXor) *dst++ = code; - } else { + else *dst++ ^= code; - } + if (++count == pitch) { count = 0; dstNext += SCREEN_W; @@ -1846,11 +1837,11 @@ void Screen::wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitc } } else { while (subcode--) { - if (noXor) { + if (noXor) *dst++ = *src++; - } else { + else *dst++ ^= *src++; - } + if (++count == pitch) { count = 0; dstNext += SCREEN_W; @@ -1872,11 +1863,11 @@ void Screen::wrapped_decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitc } } else { while (code--) { - if (noXor) { + if (noXor) *dst++ = *src++; - } else { + else *dst++ ^= *src++; - } + if (++count == pitch) { count = 0; dstNext += SCREEN_W; @@ -1934,11 +1925,11 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { } int16 shapeSize2 = shapeSize; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) shapeSize += 12; - } else { + else shapeSize += 10; - } + if (flags & 1) shapeSize += 16; @@ -1950,8 +1941,10 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { assert(newShape); byte *dst = newShape; + if (_vm->gameFlags().useAltShapeHeader) dst += 2; + WRITE_LE_UINT16(dst, (flags & 3)); dst += 2; *dst = h; dst += 1; WRITE_LE_UINT16(dst, w); dst += 2; @@ -2018,20 +2011,19 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { if (!(flags & 2)) { if (shapeSize > _animBlockSize) { dst = newShape; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) dst += 2; - } + flags = READ_LE_UINT16(dst); flags |= 2; WRITE_LE_UINT16(dst, flags); } else { src = newShape; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) src += 2; - } - if (flags & 1) { + if (flags & 1) src += 16; - } + src += 10; uint8 *shapePtrBackUp = src; dst = _animBlockPtr; @@ -2058,16 +2050,14 @@ uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { } dst = newShape; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) dst += 2; - } WRITE_LE_UINT16((dst + 6), shapeSize); if (flags & 1) { dst = newShape + 10; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) dst += 2; - } src = &table[0x100]; memcpy(dst, src, sizeof(uint8)*16); } @@ -2208,17 +2198,15 @@ int16 Screen::encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size_to) { } int Screen::getRectSize(int x, int y) { - if (x < 1) { + if (x < 1) x = 1; - } else if (x > 40) { + else if (x > 40) x = 40; - } - if (y < 1) { + if (y < 1) y = 1; - } else if (y > 200) { + else if (y > 200) y = 200; - } return ((x*y) << 3); } @@ -2232,13 +2220,11 @@ void Screen::hideMouse() { void Screen::showMouse() { debugC(9, kDebugLevelScreen, "Screen::showMouse()"); - if (_mouseLockCount == 1) { + if (_mouseLockCount == 1) CursorMan.showMouse(true); - } if (_mouseLockCount > 0) _mouseLockCount--; - } void Screen::setShapePages(int page1, int page2) { @@ -2324,9 +2310,8 @@ void Screen::copyScreenToRect(int x, int y, int w, int h, uint8 *ptr) { uint8 *Screen::getPalette(int num) { debugC(9, kDebugLevelScreen, "Screen::getPalette(%d)", num); assert(num >= 0 && num < (_vm->gameFlags().platform == Common::kPlatformAmiga ? 6 : 4)); - if (num == 0) { + if (num == 0) return _currentPalette; - } return _palettes[num-1]; } @@ -2354,6 +2339,7 @@ int Screen::setNewShapeHeight(uint8 *shape, int height) { debugC(9, kDebugLevelScreen, "Screen::setNewShapeHeight(%p, %d)", (const void *)shape, height); if (_vm->gameFlags().useAltShapeHeader) shape += 2; + int oldHeight = shape[2]; shape[2] = height; return oldHeight; @@ -2363,6 +2349,7 @@ int Screen::resetShapeHeight(uint8 *shape) { debugC(9, kDebugLevelScreen, "Screen::setNewShapeHeight(%p)", (const void *)shape); if (_vm->gameFlags().useAltShapeHeader) shape += 2; + int oldHeight = shape[2]; shape[2] = shape[5]; return oldHeight; @@ -2370,9 +2357,9 @@ int Screen::resetShapeHeight(uint8 *shape) { void Screen::addBitBlitRect(int x, int y, int w, int h) { debugC(9, kDebugLevelScreen, "Screen::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); - if (_bitBlitNum >= BITBLIT_RECTS) { + if (_bitBlitNum >= BITBLIT_RECTS) error("too many bit blit rects"); - } + _bitBlitRects[_bitBlitNum].x = x; _bitBlitRects[_bitBlitNum].y = y; _bitBlitRects[_bitBlitNum].x2 = w; @@ -2397,20 +2384,50 @@ void Screen::savePageToDisk(const char *file, int page) { assert(_saveLoadPage[page/2]); } memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H); + + if (_useOverlays) { + if (!_saveLoadPageOvl[page/2]) { + _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE]; + assert(_saveLoadPageOvl[page/2]); + } + + uint8 *srcPage = getOverlayPtr(page); + if (!srcPage) { + warning("trying to save unsupported overlay page %d", page); + return; + } + + memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE); + } } void Screen::loadPageFromDisk(const char *file, int page) { debugC(9, kDebugLevelScreen, "Screen::loadPageFromDisk('%s', %d)", file, page); copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); - clearOverlayRect(page, 0, 0, SCREEN_W, SCREEN_H); delete [] _saveLoadPage[page/2]; - _saveLoadPage[page/2] = 0; + + if (_saveLoadPageOvl[page/2]) { + uint8 *dstPage = getOverlayPtr(page); + if (!dstPage) { + warning("trying to restore unsupported overlay page %d", page); + return; + } + + memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE); + delete [] _saveLoadPageOvl[page/2]; + _saveLoadPageOvl[page/2] = 0; + } _saveLoadPage[page/2] = 0; } void Screen::deletePageFromDisk(int page) { debugC(9, kDebugLevelScreen, "Screen::deletePageFromDisk(%d)", page); delete [] _saveLoadPage[page/2]; _saveLoadPage[page/2] = 0; + + if (_saveLoadPageOvl[page/2]) { + delete [] _saveLoadPageOvl[page/2]; + _saveLoadPageOvl[page/2] = 0; + } } void Screen::blockInRegion(int x, int y, int width, int height) { @@ -2419,9 +2436,8 @@ void Screen::blockInRegion(int x, int y, int width, int height) { byte *toPtr = _shapePages[0] + (y * 320 + x); for (int i = 0; i < height; ++i) { byte *backUpTo = toPtr; - for (int i2 = 0; i2 < width; ++i2) { + for (int i2 = 0; i2 < width; ++i2) *toPtr++ &= 0x7F; - } toPtr = (backUpTo + 320); } } @@ -2432,48 +2448,22 @@ void Screen::blockOutRegion(int x, int y, int width, int height) { byte *toPtr = _shapePages[0] + (y * 320 + x); for (int i = 0; i < height; ++i) { byte *backUpTo = toPtr; - for (int i2 = 0; i2 < width; ++i2) { + for (int i2 = 0; i2 < width; ++i2) *toPtr++ |= 0x80; - } toPtr = (backUpTo + 320); } } void Screen::rectClip(int &x, int &y, int w, int h) { - if (x < 0) { + if (x < 0) x = 0; - } else if (x + w >= 320) { + else if (x + w >= 320) x = 320 - w; - } - if (y < 0) { + + if (y < 0) y = 0; - } else if (y + h >= 200) { + else if (y + h >= 200) y = 200 - h; - } -} - -void Screen::backUpRect0(int xpos, int ypos) { - debugC(9, kDebugLevelScreen, "Screen::backUpRect0(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 3<<3, 24); - copyRegionToBuffer(_curPage, xpos, ypos, 3<<3, 24, _vm->shapes()[0]); -} - -void Screen::restoreRect0(int xpos, int ypos) { - debugC(9, kDebugLevelScreen, "Screen::restoreRect0(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 3<<3, 24); - copyBlockToPage(_curPage, xpos, ypos, 3<<3, 24, _vm->shapes()[0]); -} - -void Screen::backUpRect1(int xpos, int ypos) { - debugC(9, kDebugLevelScreen, "Screen::backUpRect1(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 4<<3, 32); - copyRegionToBuffer(_curPage, xpos, ypos, 4<<3, 32, _vm->shapes()[1]); -} - -void Screen::restoreRect1(int xpos, int ypos) { - debugC(9, kDebugLevelScreen, "Screen::restoreRect1(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 4<<3, 32); - copyBlockToPage(_curPage, xpos, ypos, 4<<3, 32, _vm->shapes()[1]); } int Screen::getDrawLayer(int x, int y) { @@ -2481,14 +2471,15 @@ int Screen::getDrawLayer(int x, int y) { int xpos = x - 8; int ypos = y - 1; int layer = 1; + for (int curX = xpos; curX < xpos + 16; ++curX) { int tempLayer = getShapeFlag2(curX, ypos); - if (layer < tempLayer) { + + if (layer < tempLayer) layer = tempLayer; - } - if (layer >= 7) { + + if (layer >= 7) return 7; - } } return layer; } @@ -2502,13 +2493,12 @@ int Screen::getDrawLayer2(int x, int y, int height) { for (int useX = xpos; useX < xpos + 16; ++useX) { for (int useY = ypos - height; useY < ypos; ++useY) { int tempLayer = getShapeFlag2(useX, useY); - if (tempLayer > layer) { + + if (tempLayer > layer) layer = tempLayer; - } - if (tempLayer >= 7) { + if (tempLayer >= 7) return 7; - } } } return layer; @@ -2527,6 +2517,7 @@ void Screen::copyBackgroundBlock(int x, int page, int flag) { ++x; if (x == 19) x = 17; + uint8 *ptr1 = _unkPtr1; uint8 *ptr2 = _unkPtr2; int oldVideoPage = _curPage; @@ -2540,9 +2531,9 @@ void Screen::copyBackgroundBlock(int x, int page, int flag) { copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1); copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2); int newXPos = curX + x; - if (newXPos > 37) { + if (newXPos > 37) newXPos = newXPos % 38; - } + tempX = newXPos + 1; copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2); copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1); @@ -2714,12 +2705,15 @@ void Screen::addDirtyRect(int x, int y, int w, int h) { w += x; x = 0; } + if (x + w >= 320) w = 320 - x; + if (y < 0) { h += y; y = 0; } + if (y + h >= 200) h = 200 - y; @@ -3053,3 +3047,4 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { } } // End of namespace Kyra + diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index dab44f2b1a..8f8dd1702d 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -202,10 +202,6 @@ public: void blockInRegion(int x, int y, int width, int height); void blockOutRegion(int x, int y, int width, int height); - void backUpRect0(int xpos, int ypos); - void restoreRect0(int xpos, int ypos); - void backUpRect1(int xpos, int ypos); - void restoreRect1(int xpos, int ypos); void copyBackgroundBlock(int x, int page, int flag); void copyBackgroundBlock2(int x); @@ -286,6 +282,7 @@ private: uint8 *_sjisSourceChar; uint8 *_saveLoadPage[8]; + uint8 *_saveLoadPageOvl[8]; uint8 *_screenPalette; uint8 *_palettes[6]; @@ -322,3 +319,4 @@ private: } // End of namespace Kyra #endif + diff --git a/engines/kyra/script.cpp b/engines/kyra/script.cpp index a674fe4b2d..2f7973f5a2 100644 --- a/engines/kyra/script.cpp +++ b/engines/kyra/script.cpp @@ -68,13 +68,10 @@ ScriptHelper::ScriptHelper(KyraEngine *vm) : _vm(vm) { #undef COMMAND } -ScriptHelper::~ScriptHelper() { -} - -bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, byte *specialPtr) { +bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, const Common::Array<const Opcode*> *opcodes) { uint32 size = 0; uint8 *data = _vm->resource()->fileData(filename, &size); - byte *curData = data; + const byte *curData = data; uint32 formBlockSize = getFORMBlockSize(curData); if (formBlockSize == (uint32)-1) { @@ -85,14 +82,8 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, byte uint32 chunkSize = getIFFBlockSize(data, curData, size, TEXT_CHUNK); if (chunkSize != (uint32)-1) { - if (specialPtr) { - scriptData->mustBeFreed = 0; - scriptData->text = specialPtr; - specialPtr += chunkSize; - } else { - scriptData->mustBeFreed = 1; - scriptData->text = new byte[chunkSize]; - } + scriptData->text = new byte[chunkSize]; + if (!loadIFFBlock(data, curData, size, TEXT_CHUNK, scriptData->text, chunkSize)) { delete [] data; unloadScript(scriptData); @@ -108,24 +99,19 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, byte error("No ORDR chunk found in file: '%s'", filename); return false; } - if (specialPtr) { - scriptData->mustBeFreed = 0; - scriptData->ordr = specialPtr; - specialPtr += chunkSize; - } else { - scriptData->mustBeFreed = 1; - scriptData->ordr = new byte[chunkSize]; - } - if (!loadIFFBlock(data, curData, size, ORDR_CHUNK, scriptData->ordr, chunkSize)) { + chunkSize >>= 1; + + scriptData->ordr = new uint16[chunkSize]; + + if (!loadIFFBlock(data, curData, size, ORDR_CHUNK, scriptData->ordr, chunkSize << 1)) { delete [] data; unloadScript(scriptData); error("Couldn't load ORDR chunk from file: '%s'", filename); return false; } - chunkSize = chunkSize / 2; - while (chunkSize--) { - ((uint16*)scriptData->ordr)[chunkSize] = READ_BE_UINT16(&((uint16*)scriptData->ordr)[chunkSize]); - } + + while (chunkSize--) + scriptData->ordr[chunkSize] = READ_BE_UINT16(&scriptData->ordr[chunkSize]); chunkSize = getIFFBlockSize(data, curData, size, DATA_CHUNK); if (chunkSize == (uint32)-1) { @@ -134,21 +120,22 @@ bool ScriptHelper::loadScript(const char *filename, ScriptData *scriptData, byte error("No DATA chunk found in file: '%s'", filename); return false; } - if (specialPtr) { - scriptData->mustBeFreed = 0; - scriptData->data = specialPtr; - specialPtr += chunkSize; - } else { - scriptData->mustBeFreed = 1; - scriptData->data = new byte[chunkSize]; - } - if (!loadIFFBlock(data, curData, size, DATA_CHUNK, scriptData->data, chunkSize)) { + chunkSize >>= 1; + + scriptData->data = new uint16[chunkSize]; + + if (!loadIFFBlock(data, curData, size, DATA_CHUNK, scriptData->data, chunkSize << 1)) { delete [] data; unloadScript(scriptData); error("Couldn't load DATA chunk from file: '%s'", filename); return false; } - scriptData->dataSize = chunkSize / 2; + scriptData->dataSize = chunkSize; + + while (chunkSize--) + scriptData->data[chunkSize] = READ_BE_UINT16(&scriptData->data[chunkSize]); + + scriptData->opcodes = opcodes; delete [] data; return true; @@ -158,17 +145,15 @@ void ScriptHelper::unloadScript(ScriptData *data) { if (!data) return; - if (data->mustBeFreed) { - delete [] data->text; - delete [] data->ordr; - delete [] data->data; - } + delete [] data->text; + delete [] data->ordr; + delete [] data->data; - data->mustBeFreed = 0; - data->text = data->ordr = data->data = 0; + data->text = 0; + data->ordr = data->data = 0; } -void ScriptHelper::initScript(ScriptState *scriptStat, ScriptData *data) { +void ScriptHelper::initScript(ScriptState *scriptStat, const ScriptData *data) { scriptStat->dataPtr = data; scriptStat->ip = 0; scriptStat->stack[60] = 0; @@ -177,17 +162,18 @@ void ScriptHelper::initScript(ScriptState *scriptStat, ScriptData *data) { } bool ScriptHelper::startScript(ScriptState *script, int function) { - if (!script->dataPtr) { + if (!script->dataPtr) return false; - } - uint16 functionOffset = ((uint16*)script->dataPtr->ordr)[function]; - if (functionOffset == (uint16)-1) { + + uint16 functionOffset = script->dataPtr->ordr[function]; + if (functionOffset == 0xFFFF) return false; - } + if (_vm->gameFlags().platform == Common::kPlatformFMTowns) - script->ip = &script->dataPtr->data[functionOffset*2+2]; + script->ip = &script->dataPtr->data[functionOffset+1]; else - script->ip = &script->dataPtr->data[functionOffset*2]; + script->ip = &script->dataPtr->data[functionOffset]; + return true; } @@ -201,11 +187,10 @@ bool ScriptHelper::runScript(ScriptState *script) { _parameter = 0; _continue = true; - if (!script->ip) { + if (!script->ip) return false; - } - - int16 code = READ_BE_UINT16(script->ip); script->ip += 2; + + int16 code = *script->ip++; int16 opcode = (code >> 8) & 0x1F; if (code & 0x8000) { @@ -214,7 +199,7 @@ bool ScriptHelper::runScript(ScriptState *script) { } else if (code & 0x4000) { _parameter = (int8)(code); } else if (code & 0x2000) { - _parameter = READ_BE_UINT16(script->ip); script->ip += 2; + _parameter = *script->ip++; } else { _parameter = 0; } @@ -229,23 +214,24 @@ bool ScriptHelper::runScript(ScriptState *script) { return _continue; } -uint32 ScriptHelper::getFORMBlockSize(byte *&data) const { +uint32 ScriptHelper::getFORMBlockSize(const byte *&data) const { static const uint32 chunkName = FORM_CHUNK; - if (READ_LE_UINT32(data) != chunkName) { + + if (READ_LE_UINT32(data) != chunkName) return (uint32)-1; - } + data += 4; uint32 retValue = READ_BE_UINT32(data); data += 4; return retValue; } -uint32 ScriptHelper::getIFFBlockSize(byte *start, byte *&data, uint32 maxSize, const uint32 chunkName) const { +uint32 ScriptHelper::getIFFBlockSize(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunkName) const { uint32 size = (uint32)-1; bool special = false; - if (data == (start + maxSize)) { + if (data == (start + maxSize)) data = start + 0x0C; - } + while (data < (start + maxSize)) { uint32 chunk = READ_LE_UINT32(data); data += 4; uint32 size_temp = READ_BE_UINT32(data); data += 4; @@ -263,15 +249,16 @@ uint32 ScriptHelper::getIFFBlockSize(byte *start, byte *&data, uint32 maxSize, c break; } } + return size; } -bool ScriptHelper::loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const uint32 chunkName, byte *loadTo, uint32 ptrSize) const { +bool ScriptHelper::loadIFFBlock(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunkName, void *loadTo, uint32 ptrSize) const { bool special = false; - if (data == (start + maxSize)) { + if (data == (start + maxSize)) data = start + 0x0C; - } + while (data < (start + maxSize)) { uint32 chunk = READ_LE_UINT32(data); data += 4; uint32 chunkSize = READ_BE_UINT32(data); data += 4; @@ -290,12 +277,12 @@ bool ScriptHelper::loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const loadSize = ptrSize; memcpy(loadTo, data, loadSize); chunkSize = (chunkSize + 1) & 0xFFFFFFFE; - if (chunkSize > loadSize) { + if (chunkSize > loadSize) data += (chunkSize - loadSize); - } return true; } } + return false; } @@ -304,7 +291,7 @@ bool ScriptHelper::loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const #pragma mark - void ScriptHelper::c1_jmpTo(ScriptState* script) { - script->ip = script->dataPtr->data + (_parameter << 1); + script->ip = script->dataPtr->data + _parameter; } void ScriptHelper::c1_setRetValue(ScriptState* script) { @@ -318,7 +305,7 @@ void ScriptHelper::c1_pushRetOrPos(ScriptState* script) { break; case 1: - script->stack[--script->sp] = (script->ip - script->dataPtr->data) / 2 + 1; + script->stack[--script->sp] = script->ip - script->dataPtr->data + 1; script->stack[--script->sp] = script->bp; script->bp = script->sp + 2; break; @@ -358,7 +345,7 @@ void ScriptHelper::c1_popRetOrPos(ScriptState* script) { script->ip = 0; } else { script->bp = script->stack[script->sp++]; - script->ip = script->dataPtr->data + (script->stack[script->sp++] << 1); + script->ip = script->dataPtr->data + script->stack[script->sp++]; } break; @@ -390,13 +377,23 @@ void ScriptHelper::c1_subSP(ScriptState* script) { } void ScriptHelper::c1_execOpcode(ScriptState* script) { - script->retValue = _vm->runOpcode(script, (uint8)_parameter); + uint8 opcode = _parameter; + + assert(script->dataPtr->opcodes); + assert(opcode < script->dataPtr->opcodes->size()); + + if ((*script->dataPtr->opcodes)[opcode]) { + script->retValue = (*(*script->dataPtr->opcodes)[opcode])(script); + } else { + script->retValue = 0; + warning("calling unimplemented opcode(0x%.02X)", opcode); + } } void ScriptHelper::c1_ifNotJmp(ScriptState* script) { if (!script->stack[script->sp++]) { _parameter &= 0x7FFF; - script->ip = script->dataPtr->data + (_parameter << 1); + script->ip = script->dataPtr->data + _parameter; } } @@ -404,11 +401,10 @@ void ScriptHelper::c1_negate(ScriptState* script) { int16 value = script->stack[script->sp]; switch (_parameter) { case 0: - if (!value) { + if (!value) script->stack[script->sp] = 1; - } else { + else script->stack[script->sp] = 0; - } break; case 1: @@ -434,67 +430,59 @@ void ScriptHelper::c1_eval(ScriptState* script) { switch (_parameter) { case 0: - if (!val2 || !val1) { + if (!val2 || !val1) ret = 0; - } else { + else ret = 1; - } break; case 1: - if (val2 || val1) { + if (val2 || val1) ret = 1; - } else { + else ret = 0; - } break; case 2: - if (val1 == val2) { + if (val1 == val2) ret = 1; - } else { + else ret = 0; - } break; case 3: - if (val1 != val2) { + if (val1 != val2) ret = 1; - } else { + else ret = 0; - } break; case 4: - if (val1 > val2) { + if (val1 > val2) ret = 1; - } else { + else ret = 0; - } break; case 5: - if (val1 >= val2) { + if (val1 >= val2) ret = 1; - } else { + else ret = 0; - } break; case 6: - if (val1 < val2) { + if (val1 < val2) ret = 1; - } else { + else ret = 0; - } break; case 7: - if (val1 <= val2) { + if (val1 <= val2) ret = 1; - } else { + else ret = 0; - } break; case 8: @@ -559,7 +547,8 @@ void ScriptHelper::c1_setRetAndJmp(ScriptState* script) { script->retValue = script->stack[script->sp++]; uint16 temp = script->stack[script->sp++]; script->stack[60] = 0; - script->ip = &script->dataPtr->data[temp*2]; + script->ip = &script->dataPtr->data[temp]; } } } // end of namespace Kyra + diff --git a/engines/kyra/script.h b/engines/kyra/script.h index ebc144ab36..67aef8361c 100644 --- a/engines/kyra/script.h +++ b/engines/kyra/script.h @@ -26,19 +26,44 @@ #include "kyra/kyra.h" namespace Kyra { + +struct ScriptState; + +struct Opcode { + virtual ~Opcode() {} + + virtual operator bool() const = 0; + + virtual int operator()(ScriptState*) const = 0; +}; + +template<class T> +struct OpcodeImpl : public Opcode { + T *vm; + typedef int (T::*Callback)(ScriptState*); + Callback callback; + + OpcodeImpl(T *v, Callback c) : Opcode(), vm(v), callback(c) {} + + operator bool() const { return callback != 0; } + + int operator()(ScriptState *state) const { + return (vm->*callback)(state); + } +}; + struct ScriptData { byte *text; - byte *data; - byte *ordr; + uint16 *data; + uint16 *ordr; uint16 dataSize; - uint16 mustBeFreed; - - int opcodeTable; // indicates which opcode table to use (for Kyra3) + + const Common::Array<const Opcode*> *opcodes; }; struct ScriptState { - byte *ip; - ScriptData *dataPtr; + uint16 *ip; + const ScriptData *dataPtr; int16 retValue; uint16 bp; uint16 sp; @@ -49,21 +74,20 @@ struct ScriptState { class ScriptHelper { public: ScriptHelper(KyraEngine *vm); - virtual ~ScriptHelper(); - bool loadScript(const char *filename, ScriptData *data, byte *specialPtr = 0); + bool loadScript(const char *filename, ScriptData *data, const Common::Array<const Opcode*> *opcodes); void unloadScript(ScriptData *data); - void initScript(ScriptState *scriptState, ScriptData *data); + void initScript(ScriptState *scriptState, const ScriptData *data); bool startScript(ScriptState *script, int function); bool validScript(ScriptState *script); bool runScript(ScriptState *script); protected: - uint32 getFORMBlockSize(byte *&data) const; - uint32 getIFFBlockSize(byte *start, byte *&data, uint32 maxSize, const uint32 chunk) const; - bool loadIFFBlock(byte *start, byte *&data, uint32 maxSize, const uint32 chunk, byte *loadTo, uint32 ptrSize) const; + uint32 getFORMBlockSize(const byte *&data) const; + uint32 getIFFBlockSize(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunk) const; + bool loadIFFBlock(const byte *start, const byte *&data, uint32 maxSize, const uint32 chunk, void *loadTo, uint32 ptrSize) const; KyraEngine *_vm; int16 _parameter; @@ -100,3 +124,4 @@ private: } // end of namespace Kyra #endif + diff --git a/engines/kyra/script_v1.cpp b/engines/kyra/script_v1.cpp index d3ec7bd7eb..4882a4a948 100644 --- a/engines/kyra/script_v1.cpp +++ b/engines/kyra/script_v1.cpp @@ -22,7 +22,7 @@ #include "common/stdafx.h" #include "common/endian.h" -#include "kyra/kyra.h" +#include "kyra/kyra_v1.h" #include "kyra/script.h" #include "kyra/screen.h" #include "kyra/sprites.h" @@ -33,15 +33,15 @@ namespace Kyra { #define stackPos(x) script->stack[script->sp+x] -#define stackPosString(x) (char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])] +#define stackPosString(x) (const char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])] -int KyraEngine::o1_magicInMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_magicInMouseItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_magicInMouseItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); magicInMouseItem(stackPos(0), stackPos(1), -1); return 0; } -int KyraEngine::o1_characterSays(ScriptState *script) { +int KyraEngine_v1::o1_characterSays(ScriptState *script) { _skipFlag = false; if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "o1_characterSays(%p) (%d, '%s', %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3)); @@ -72,7 +72,7 @@ int KyraEngine::o1_characterSays(ScriptState *script) { return 0; } -int KyraEngine::o1_pauseTicks(ScriptState *script) { +int KyraEngine_v1::o1_pauseTicks(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_pauseTicks(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); if (stackPos(1)) { warning("STUB: special o1_pauseTicks"); @@ -84,56 +84,55 @@ int KyraEngine::o1_pauseTicks(ScriptState *script) { return 0; } -int KyraEngine::o1_drawSceneAnimShape(ScriptState *script) { +int KyraEngine_v1::o1_drawSceneAnimShape(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_drawSceneAnimShape(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _screen->drawShape(stackPos(4), _sprites->_sceneShapes[stackPos(0)], stackPos(1), stackPos(2), 0, (stackPos(3) != 0) ? 1 : 0); return 0; } -int KyraEngine::o1_queryGameFlag(ScriptState *script) { +int KyraEngine_v1::o1_queryGameFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return queryGameFlag(stackPos(0)); } -int KyraEngine::o1_setGameFlag(ScriptState *script) { +int KyraEngine_v1::o1_setGameFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return setGameFlag(stackPos(0)); } -int KyraEngine::o1_resetGameFlag(ScriptState *script) { +int KyraEngine_v1::o1_resetGameFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0)); return resetGameFlag(stackPos(0)); } -int KyraEngine::o1_runNPCScript(ScriptState *script) { +int KyraEngine_v1::o1_runNPCScript(ScriptState *script) { warning("STUB: o1_runNPCScript"); return 0; } -int KyraEngine::o1_setSpecialExitList(ScriptState *script) { +int KyraEngine_v1::o1_setSpecialExitList(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setSpecialExitList(%p) (%d, %d, %d, %d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7), stackPos(8), stackPos(9)); - for (int i = 0; i < 10; ++i) { + for (int i = 0; i < 10; ++i) _exitList[i] = stackPos(i); - } _exitListPtr = _exitList; return 0; } -int KyraEngine::o1_blockInWalkableRegion(ScriptState *script) { +int KyraEngine_v1::o1_blockInWalkableRegion(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->blockInRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); return 0; } -int KyraEngine::o1_blockOutWalkableRegion(ScriptState *script) { +int KyraEngine_v1::o1_blockOutWalkableRegion(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->blockOutRegion(stackPos(0), stackPos(1), stackPos(2)-stackPos(0)+1, stackPos(3)-stackPos(1)+1); return 0; } -int KyraEngine::o1_walkPlayerToPoint(ScriptState *script) { +int KyraEngine_v1::o1_walkPlayerToPoint(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_walkPlayerToPoint(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int normalTimers = stackPos(2); @@ -151,9 +150,8 @@ int KyraEngine::o1_walkPlayerToPoint(ScriptState *script) { enableTimer(18); } - if (reinitScript) { + if (reinitScript) _scriptInterpreter->initScript(script, script->dataPtr); - } if (_sceneChangeState) { _sceneChangeState = 0; @@ -162,7 +160,7 @@ int KyraEngine::o1_walkPlayerToPoint(ScriptState *script) { return 0; } -int KyraEngine::o1_dropItemInScene(ScriptState *script) { +int KyraEngine_v1::o1_dropItemInScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_dropItemInScene(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); int item = stackPos(0); int xpos = stackPos(1); @@ -179,16 +177,15 @@ int KyraEngine::o1_dropItemInScene(ScriptState *script) { _animator->animAddGameItem(freeItem, sceneId); _animator->updateAllObjectShapes(); } else { - if (item == 43) { + if (item == 43) placeItemInGenericMapScene(item, 0); - } else { + else placeItemInGenericMapScene(item, 1); - } } return 0; } -int KyraEngine::o1_drawAnimShapeIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_drawAnimShapeIntoScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_drawAnimShapeIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); @@ -206,50 +203,49 @@ int KyraEngine::o1_drawAnimShapeIntoScene(ScriptState *script) { return 0; } -int KyraEngine::o1_createMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_createMouseItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_createMouseItem(%p) (%d)", (const void *)script, stackPos(0)); createMouseItem(stackPos(0)); return 0; } -int KyraEngine::o1_savePageToDisk(ScriptState *script) { +int KyraEngine_v1::o1_savePageToDisk(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_savePageToDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->savePageToDisk(stackPosString(0), stackPos(1)); return 0; } -int KyraEngine::o1_sceneAnimOn(ScriptState *script) { +int KyraEngine_v1::o1_sceneAnimOn(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimOn(%p) (%d)", (const void *)script, stackPos(0)); _sprites->_anims[stackPos(0)].play = true; return 0; } -int KyraEngine::o1_sceneAnimOff(ScriptState *script) { +int KyraEngine_v1::o1_sceneAnimOff(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimOff(%p) (%d)", (const void *)script, stackPos(0)); _sprites->_anims[stackPos(0)].play = false; return 0; } -int KyraEngine::o1_getElapsedSeconds(ScriptState *script) { +int KyraEngine_v1::o1_getElapsedSeconds(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getElapsedSeconds(%p) ()", (const void *)script); return _system->getMillis() / 1000; } -int KyraEngine::o1_mouseIsPointer(ScriptState *script) { +int KyraEngine_v1::o1_mouseIsPointer(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_mouseIsPointer(%p) ()", (const void *)script); - if (_itemInHand == -1) { + if (_itemInHand == -1) return 1; - } return 0; } -int KyraEngine::o1_destroyMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_destroyMouseItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_destroyMouseItem(%p) ()", (const void *)script); destroyMouseItem(); return 0; } -int KyraEngine::o1_runSceneAnimUntilDone(ScriptState *script) { +int KyraEngine_v1::o1_runSceneAnimUntilDone(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_runSceneAnimUntilDone(%p) (%d)", (const void *)script, stackPos(0)); _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); @@ -267,7 +263,7 @@ int KyraEngine::o1_runSceneAnimUntilDone(ScriptState *script) { return 0; } -int KyraEngine::o1_fadeSpecialPalette(ScriptState *script) { +int KyraEngine_v1::o1_fadeSpecialPalette(ScriptState *script) { if (_flags.platform == Common::kPlatformAmiga) { debugC(3, kDebugLevelScriptFuncs, "o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); if (_currentCharacter->sceneId != 45) { @@ -285,42 +281,42 @@ int KyraEngine::o1_fadeSpecialPalette(ScriptState *script) { return 0; } -int KyraEngine::o1_playAdlibSound(ScriptState *script) { +int KyraEngine_v1::o1_playAdlibSound(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_playAdlibSound(%p) (%d)", (const void *)script, stackPos(0)); snd_playSoundEffect(stackPos(0)); return 0; } -int KyraEngine::o1_playAdlibScore(ScriptState *script) { +int KyraEngine_v1::o1_playAdlibScore(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_playAdlibScore(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); snd_playWanderScoreViaMap(stackPos(0), stackPos(1)); return 0; } -int KyraEngine::o1_phaseInSameScene(ScriptState *script) { +int KyraEngine_v1::o1_phaseInSameScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_phaseInSameScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); transcendScenes(stackPos(0), stackPos(1)); return 0; } -int KyraEngine::o1_setScenePhasingFlag(ScriptState *script) { +int KyraEngine_v1::o1_setScenePhasingFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setScenePhasingFlag(%p) ()", (const void *)script); _scenePhasingFlag = 1; return 1; } -int KyraEngine::o1_resetScenePhasingFlag(ScriptState *script) { +int KyraEngine_v1::o1_resetScenePhasingFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_resetScenePhasingFlag(%p) ()", (const void *)script); _scenePhasingFlag = 0; return 0; } -int KyraEngine::o1_queryScenePhasingFlag(ScriptState *script) { +int KyraEngine_v1::o1_queryScenePhasingFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_queryScenePhasingFlag(%p) ()", (const void *)script); return _scenePhasingFlag; } -int KyraEngine::o1_sceneToDirection(ScriptState *script) { +int KyraEngine_v1::o1_sceneToDirection(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_sceneToDirection(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < _roomTableSize); Room *curRoom = &_roomTable[stackPos(0)]; @@ -350,7 +346,7 @@ int KyraEngine::o1_sceneToDirection(ScriptState *script) { return returnValue; } -int KyraEngine::o1_setBirthstoneGem(ScriptState *script) { +int KyraEngine_v1::o1_setBirthstoneGem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setBirthstoneGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int index = stackPos(0); if (index < 4 && index >= 0) { @@ -360,19 +356,19 @@ int KyraEngine::o1_setBirthstoneGem(ScriptState *script) { return 0; } -int KyraEngine::o1_placeItemInGenericMapScene(ScriptState *script) { +int KyraEngine_v1::o1_placeItemInGenericMapScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_placeItemInGenericMapScene(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); placeItemInGenericMapScene(stackPos(0), stackPos(1)); return 0; } -int KyraEngine::o1_setBrandonStatusBit(ScriptState *script) { +int KyraEngine_v1::o1_setBrandonStatusBit(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); _brandonStatusBit |= stackPos(0); return 0; } -int KyraEngine::o1_pauseSeconds(ScriptState *script) { +int KyraEngine_v1::o1_pauseSeconds(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_pauseSeconds(%p) (%d)", (const void *)script, stackPos(0)); if (stackPos(0) > 0 && !_skipFlag) delay(stackPos(0)*1000, true); @@ -380,65 +376,62 @@ int KyraEngine::o1_pauseSeconds(ScriptState *script) { return 0; } -int KyraEngine::o1_getCharactersLocation(ScriptState *script) { +int KyraEngine_v1::o1_getCharactersLocation(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersLocation(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].sceneId; } -int KyraEngine::o1_runNPCSubscript(ScriptState *script) { +int KyraEngine_v1::o1_runNPCSubscript(ScriptState *script) { warning("STUB: o1_runNPCSubscript"); return 0; } -int KyraEngine::o1_magicOutMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_magicOutMouseItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_magicOutMouseItem(%p) (%d)", (const void *)script, stackPos(0)); magicOutMouseItem(stackPos(0), -1); return 0; } -int KyraEngine::o1_internalAnimOn(ScriptState *script) { +int KyraEngine_v1::o1_internalAnimOn(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_internalAnimOn(%p) (%d)", (const void *)script, stackPos(0)); _animator->sprites()[stackPos(0)].active = 1; return 0; } -int KyraEngine::o1_forceBrandonToNormal(ScriptState *script) { +int KyraEngine_v1::o1_forceBrandonToNormal(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_forceBrandonToNormal(%p) ()", (const void *)script); checkAmuletAnimFlags(); return 0; } -int KyraEngine::o1_poisonDeathNow(ScriptState *script) { +int KyraEngine_v1::o1_poisonDeathNow(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_poisonDeathNow(%p) ()", (const void *)script); seq_poisonDeathNow(1); return 0; } -int KyraEngine::o1_setScaleMode(ScriptState *script) { +int KyraEngine_v1::o1_setScaleMode(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setScaleMode(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int len = stackPos(0); int setValue1 = stackPos(1); int start2 = stackPos(2); int setValue2 = stackPos(3); - for (int i = 0; i < len; ++i) { + for (int i = 0; i < len; ++i) _scaleTable[i] = setValue1; - } int temp = setValue2 - setValue1; int temp2 = start2 - len; - for (int i = len, offset = 0; i < start2; ++i, ++offset) { + for (int i = len, offset = 0; i < start2; ++i, ++offset) _scaleTable[i] = (offset * temp) / temp2 + setValue1; - } - for (int i = start2; i < 145; ++i) { + for (int i = start2; i < 145; ++i) _scaleTable[i] = setValue2; - } _scaleMode = 1; return _scaleMode; } -int KyraEngine::o1_openWSAFile(ScriptState *script) { +int KyraEngine_v1::o1_openWSAFile(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_openWSAFile(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3)); - char *filename = stackPosString(0); + const char *filename = stackPosString(0); int wsaIndex = stackPos(1); _movieObjects[wsaIndex]->open(filename, (stackPos(3) != 0) ? 1 : 0, 0); @@ -447,18 +440,17 @@ int KyraEngine::o1_openWSAFile(ScriptState *script) { return 0; } -int KyraEngine::o1_closeWSAFile(ScriptState *script) { +int KyraEngine_v1::o1_closeWSAFile(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_closeWSAFile(%p) (%d)", (const void *)script, stackPos(0)); int wsaIndex = stackPos(0); - if (_movieObjects[wsaIndex]) { + if (_movieObjects[wsaIndex]) _movieObjects[wsaIndex]->close(); - } return 0; } -int KyraEngine::o1_runWSAFromBeginningToEnd(ScriptState *script) { +int KyraEngine_v1::o1_runWSAFromBeginningToEnd(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_runWSAFromBeginningToEnd(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _screen->hideMouse(); @@ -499,7 +491,7 @@ int KyraEngine::o1_runWSAFromBeginningToEnd(ScriptState *script) { return 0; } -int KyraEngine::o1_displayWSAFrame(ScriptState *script) { +int KyraEngine_v1::o1_displayWSAFrame(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_displayWSAFrame(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); int frame = stackPos(0); int xpos = stackPos(1); @@ -526,13 +518,13 @@ int KyraEngine::o1_displayWSAFrame(ScriptState *script) { return 0; } -int KyraEngine::o1_enterNewScene(ScriptState *script) { +int KyraEngine_v1::o1_enterNewScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_enterNewScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); enterNewScene(stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); return 0; } -int KyraEngine::o1_setSpecialEnterXAndY(ScriptState *script) { +int KyraEngine_v1::o1_setSpecialEnterXAndY(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setSpecialEnterXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _brandonPosX = stackPos(0); _brandonPosY = stackPos(1); @@ -541,7 +533,7 @@ int KyraEngine::o1_setSpecialEnterXAndY(ScriptState *script) { return 0; } -int KyraEngine::o1_runWSAFrames(ScriptState *script) { +int KyraEngine_v1::o1_runWSAFrames(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_runWSAFrames(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int xpos = stackPos(0); int ypos = stackPos(1); @@ -568,7 +560,7 @@ int KyraEngine::o1_runWSAFrames(ScriptState *script) { return 0; } -int KyraEngine::o1_popBrandonIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_popBrandonIntoScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_popBrandonIntoScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int changeScaleMode = stackPos(3); int xpos = (int16)(stackPos(0) & 0xFFFC); @@ -604,9 +596,8 @@ int KyraEngine::o1_popBrandonIntoScene(ScriptState *script) { } int scaleModeBackup = _scaleMode; - if (changeScaleMode) { + if (changeScaleMode) _scaleMode = 1; - } _animator->animRefreshNPC(0); _animator->preserveAllBackgrounds(); @@ -618,7 +609,7 @@ int KyraEngine::o1_popBrandonIntoScene(ScriptState *script) { return 0; } -int KyraEngine::o1_restoreAllObjectBackgrounds(ScriptState *script) { +int KyraEngine_v1::o1_restoreAllObjectBackgrounds(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_restoreAllObjectBackgrounds(%p) (%d)", (const void *)script, stackPos(0)); int disable = stackPos(0); int activeBackup = 0; @@ -632,20 +623,20 @@ int KyraEngine::o1_restoreAllObjectBackgrounds(ScriptState *script) { return 0; } -int KyraEngine::o1_setCustomPaletteRange(ScriptState *script) { +int KyraEngine_v1::o1_setCustomPaletteRange(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); memcpy(_screen->getPalette(1) + stackPos(1)*3, _specialPalettes[stackPos(0)], stackPos(2)*3); return 0; } -int KyraEngine::o1_loadPageFromDisk(ScriptState *script) { +int KyraEngine_v1::o1_loadPageFromDisk(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_loadPageFromDisk(%p) ('%s', %d)", (const void *)script, stackPosString(0), stackPos(1)); _screen->loadPageFromDisk(stackPosString(0), stackPos(1)); _animator->_updateScreen = true; return 0; } -int KyraEngine::o1_customPrintTalkString(ScriptState *script) { +int KyraEngine_v1::o1_customPrintTalkString(ScriptState *script) { if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "o1_customPrintTalkString(%p) (%d, '%s', %d, %d, %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4) & 0xFF); @@ -665,7 +656,7 @@ int KyraEngine::o1_customPrintTalkString(ScriptState *script) { return 0; } -int KyraEngine::o1_restoreCustomPrintBackground(ScriptState *script) { +int KyraEngine_v1::o1_restoreCustomPrintBackground(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_restoreCustomPrintBackground(%p) ()", (const void *)script); snd_voiceWaitForFinish(); snd_stopVoice(); @@ -673,38 +664,37 @@ int KyraEngine::o1_restoreCustomPrintBackground(ScriptState *script) { return 0; } -int KyraEngine::o1_hideMouse(ScriptState *script) { +int KyraEngine_v1::o1_hideMouse(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_hideMouse(%p) ()", (const void *)script); _screen->hideMouse(); return 0; } -int KyraEngine::o1_showMouse(ScriptState *script) { +int KyraEngine_v1::o1_showMouse(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_showMouse(%p) ()", (const void *)script); _screen->showMouse(); return 0; } -int KyraEngine::o1_getCharacterX(ScriptState *script) { +int KyraEngine_v1::o1_getCharacterX(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getCharacterX(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].x1; } -int KyraEngine::o1_getCharacterY(ScriptState *script) { +int KyraEngine_v1::o1_getCharacterY(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getCharacterY(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].y1; } -int KyraEngine::o1_changeCharactersFacing(ScriptState *script) { +int KyraEngine_v1::o1_changeCharactersFacing(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_changeCharactersFacing(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); int character = stackPos(0); int facing = stackPos(1); int newAnimFrame = stackPos(2); _animator->restoreAllObjectBackgrounds(); - if (newAnimFrame != -1) { + if (newAnimFrame != -1) _characterList[character].currentAnimFrame = newAnimFrame; - } _characterList[character].facing = facing; _animator->animRefreshNPC(character); _animator->preserveAllBackgrounds(); @@ -714,7 +704,7 @@ int KyraEngine::o1_changeCharactersFacing(ScriptState *script) { return 0; } -int KyraEngine::o1_copyWSARegion(ScriptState *script) { +int KyraEngine_v1::o1_copyWSARegion(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_copyWSARegion(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int xpos = stackPos(0); int ypos = stackPos(1); @@ -727,7 +717,7 @@ int KyraEngine::o1_copyWSARegion(ScriptState *script) { return 0; } -int KyraEngine::o1_printText(ScriptState *script) { +int KyraEngine_v1::o1_printText(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_printText(%p) ('%s', %d, %d, 0x%X, 0x%X)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); if (_flags.lang == Common::JA_JPN && stackPos(3) == 7) _screen->printText(stackPosString(0), stackPos(1), stackPos(2), 0, 0x80); @@ -737,18 +727,18 @@ int KyraEngine::o1_printText(ScriptState *script) { return 0; } -int KyraEngine::o1_random(ScriptState *script) { +int KyraEngine_v1::o1_random(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_random(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < stackPos(1)); return _rnd.getRandomNumberRng(stackPos(0), stackPos(1)); } -int KyraEngine::o1_loadSoundFile(ScriptState *script) { +int KyraEngine_v1::o1_loadSoundFile(ScriptState *script) { warning("STUB: o1_loadSoundFile"); return 0; } -int KyraEngine::o1_displayWSAFrameOnHidPage(ScriptState *script) { +int KyraEngine_v1::o1_displayWSAFrameOnHidPage(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_displayWSAFrameOnHidPage(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); int frame = stackPos(0); int xpos = stackPos(1); @@ -777,7 +767,7 @@ int KyraEngine::o1_displayWSAFrameOnHidPage(ScriptState *script) { return 0; } -int KyraEngine::o1_displayWSASequentialFrames(ScriptState *script) { +int KyraEngine_v1::o1_displayWSASequentialFrames(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_displayWSASequentialFrames(%p) (%d, %d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6)); int startFrame = stackPos(0); int endFrame = stackPos(1); @@ -796,7 +786,7 @@ int KyraEngine::o1_displayWSASequentialFrames(ScriptState *script) { // Workaround for bug #1498221 "KYRA1: Glitches when meeting Zanthia" // the original didn'to do a forced screen update after displaying a wsa frame // while we have to do it, which make brandon disappear for a short moment, - // which shouldn't happen. So we're not updating the screen for this special + // what shouldn't happen. So we're not updating the screen for this special // case too. if (startFrame == 18 && endFrame == 18 && _currentRoom == 45) { _movieObjects[wsaIndex]->displayFrame(18); @@ -842,6 +832,7 @@ int KyraEngine::o1_displayWSASequentialFrames(ScriptState *script) { --frame; } } + if (_skipFlag) break; else @@ -852,30 +843,28 @@ int KyraEngine::o1_displayWSASequentialFrames(ScriptState *script) { return 0; } -int KyraEngine::o1_drawCharacterStanding(ScriptState *script) { +int KyraEngine_v1::o1_drawCharacterStanding(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_drawCharacterStanding(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int character = stackPos(0); int animFrame = stackPos(1); int newFacing = stackPos(2); int updateShapes = stackPos(3); _characterList[character].currentAnimFrame = animFrame; - if (newFacing != -1) { + if (newFacing != -1) _characterList[character].facing = newFacing; - } _animator->animRefreshNPC(character); - if (updateShapes) { + if (updateShapes) _animator->updateAllObjectShapes(); - } return 0; } -int KyraEngine::o1_internalAnimOff(ScriptState *script) { +int KyraEngine_v1::o1_internalAnimOff(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_internalAnimOff(%p) (%d)", (const void *)script, stackPos(0)); _animator->sprites()[stackPos(0)].active = 0; return 0; } -int KyraEngine::o1_changeCharactersXAndY(ScriptState *script) { +int KyraEngine_v1::o1_changeCharactersXAndY(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_changeCharactersXAndY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); Character *ch = &_characterList[stackPos(0)]; int16 x = stackPos(1); @@ -891,25 +880,25 @@ int KyraEngine::o1_changeCharactersXAndY(ScriptState *script) { return 0; } -int KyraEngine::o1_clearSceneAnimatorBeacon(ScriptState *script) { +int KyraEngine_v1::o1_clearSceneAnimatorBeacon(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_clearSceneAnimatorBeacon(%p) ()", (const void *)script); _sprites->_sceneAnimatorBeaconFlag = 0; return 0; } -int KyraEngine::o1_querySceneAnimatorBeacon(ScriptState *script) { +int KyraEngine_v1::o1_querySceneAnimatorBeacon(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_querySceneAnimatorBeacon(%p) ()", (const void *)script); return _sprites->_sceneAnimatorBeaconFlag; } -int KyraEngine::o1_refreshSceneAnimator(ScriptState *script) { +int KyraEngine_v1::o1_refreshSceneAnimator(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_refreshSceneAnimator(%p) ()", (const void *)script); _sprites->updateSceneAnims(); _animator->updateAllObjectShapes(); return 0; } -int KyraEngine::o1_placeItemInOffScene(ScriptState *script) { +int KyraEngine_v1::o1_placeItemInOffScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_placeItemInOffScene(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); int item = stackPos(0); int xpos = stackPos(1); @@ -928,7 +917,7 @@ int KyraEngine::o1_placeItemInOffScene(ScriptState *script) { return 0; } -int KyraEngine::o1_wipeDownMouseItem(ScriptState *script) { +int KyraEngine_v1::o1_wipeDownMouseItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_wipeDownMouseItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); _screen->hideMouse(); wipeDownMouseItem(stackPos(1), stackPos(2)); @@ -937,7 +926,7 @@ int KyraEngine::o1_wipeDownMouseItem(ScriptState *script) { return 0; } -int KyraEngine::o1_placeCharacterInOtherScene(ScriptState *script) { +int KyraEngine_v1::o1_placeCharacterInOtherScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_placeCharacterInOtherScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int id = stackPos(0); int sceneId = stackPos(1); @@ -954,18 +943,18 @@ int KyraEngine::o1_placeCharacterInOtherScene(ScriptState *script) { return 0; } -int KyraEngine::o1_getKey(ScriptState *script) { +int KyraEngine_v1::o1_getKey(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getKey(%p) ()", (const void *)script); waitForEvent(); return 0; } -int KyraEngine::o1_specificItemInInventory(ScriptState *script) { +int KyraEngine_v1::o1_specificItemInInventory(ScriptState *script) { warning("STUB: o1_specificItemInInventory"); return 0; } -int KyraEngine::o1_popMobileNPCIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_popMobileNPCIntoScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_popMobileNPCIntoScene(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), (int16)(stackPos(4) & 0xFFFC), (int8)(stackPos(5) & 0xFE)); int character = stackPos(0); int sceneId = stackPos(1); @@ -986,22 +975,22 @@ int KyraEngine::o1_popMobileNPCIntoScene(ScriptState *script) { return 0; } -int KyraEngine::o1_mobileCharacterInScene(ScriptState *script) { +int KyraEngine_v1::o1_mobileCharacterInScene(ScriptState *script) { warning("STUB: o1_mobileCharacterInScene"); return 0; } -int KyraEngine::o1_hideMobileCharacter(ScriptState *script) { +int KyraEngine_v1::o1_hideMobileCharacter(ScriptState *script) { warning("STUB: o1_hideMobileCharacter"); return 0; } -int KyraEngine::o1_unhideMobileCharacter(ScriptState *script) { +int KyraEngine_v1::o1_unhideMobileCharacter(ScriptState *script) { warning("STUB: o1_unhideMobileCharacter"); return 0; } -int KyraEngine::o1_setCharactersLocation(ScriptState *script) { +int KyraEngine_v1::o1_setCharactersLocation(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersLocation(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); Character *ch = &_characterList[stackPos(0)]; AnimObject *animObj = &_animator->actors()[stackPos(0)]; @@ -1018,7 +1007,7 @@ int KyraEngine::o1_setCharactersLocation(ScriptState *script) { return 0; } -int KyraEngine::o1_walkCharacterToPoint(ScriptState *script) { +int KyraEngine_v1::o1_walkCharacterToPoint(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_walkCharacterToPoint(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); int character = stackPos(0); int toX = stackPos(1); @@ -1027,12 +1016,12 @@ int KyraEngine::o1_walkCharacterToPoint(ScriptState *script) { uint32 nextFrame; int findWayReturn = findWay(_characterList[character].x1, _characterList[character].y1, toX, toY, _movFacingTable, 150); _pathfinderFlag2 = 0; - if (_lastFindWayRet < findWayReturn) { + + if (_lastFindWayRet < findWayReturn) _lastFindWayRet = findWayReturn; - } - if (findWayReturn == 0x7D00 || findWayReturn == 0) { + if (findWayReturn == 0x7D00 || findWayReturn == 0) return 0; - } + int *curPos = _movFacingTable; bool running = true; while (running) { @@ -1080,9 +1069,8 @@ int KyraEngine::o1_walkCharacterToPoint(ScriptState *script) { break; } - if (forceContinue || !running) { + if (forceContinue || !running) continue; - } setCharacterPosition(character, 0); ++curPos; @@ -1101,19 +1089,18 @@ int KyraEngine::o1_walkCharacterToPoint(ScriptState *script) { return 0; } -int KyraEngine::o1_specialEventDisplayBrynnsNote(ScriptState *script) { +int KyraEngine_v1::o1_specialEventDisplayBrynnsNote(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_specialEventDisplayBrynnsNote(%p) ()", (const void *)script); _screen->hideMouse(); _screen->savePageToDisk("HIDPAGE.TMP", 2); _screen->savePageToDisk("SEENPAGE.TMP", 0); if (_flags.isTalkie) { - if (_flags.lang == Common::EN_ANY) { + if (_flags.lang == Common::EN_ANY) _screen->loadBitmap("NOTEENG.CPS", 3, 3, 0); - } else if (_flags.lang == Common::FR_FRA) { + else if (_flags.lang == Common::FR_FRA) _screen->loadBitmap("NOTEFRE.CPS", 3, 3, 0); - } else if (_flags.lang == Common::DE_DEU) { + else if (_flags.lang == Common::DE_DEU) _screen->loadBitmap("NOTEGER.CPS", 3, 3, 0); - } } else { _screen->loadBitmap("NOTE.CPS", 3, 3, 0); } @@ -1124,7 +1111,7 @@ int KyraEngine::o1_specialEventDisplayBrynnsNote(ScriptState *script) { return 0; } -int KyraEngine::o1_specialEventRemoveBrynnsNote(ScriptState *script) { +int KyraEngine_v1::o1_specialEventRemoveBrynnsNote(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_specialEventRemoveBrynnsNote(%p) ()", (const void *)script); _screen->hideMouse(); _screen->loadPageFromDisk("SEENPAGE.TMP", 0); @@ -1135,32 +1122,32 @@ int KyraEngine::o1_specialEventRemoveBrynnsNote(ScriptState *script) { return 0; } -int KyraEngine::o1_setLogicPage(ScriptState *script) { +int KyraEngine_v1::o1_setLogicPage(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setLogicPage(%p) (%d)", (const void *)script, stackPos(0)); _screen->_curPage = stackPos(0); return stackPos(0); } -int KyraEngine::o1_fatPrint(ScriptState *script) { +int KyraEngine_v1::o1_fatPrint(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_fatPrint(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); // Workround for bug #1582672 ("KYRA1: Text crippled and drawn wrong") // I'm not sure how the original handels this, since it seems to call // printText also, maybe it fails somewhere inside... - // TODO: fix the reason for this workaround ;-) + // TODO: fix the reason for this workaround if (_currentRoom == 117) return 0; _text->printText(stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); return 0; } -int KyraEngine::o1_preserveAllObjectBackgrounds(ScriptState *script) { +int KyraEngine_v1::o1_preserveAllObjectBackgrounds(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_preserveAllObjectBackgrounds(%p) ()", (const void *)script); _animator->preserveAllBackgrounds(); return 0; } -int KyraEngine::o1_updateSceneAnimations(ScriptState *script) { +int KyraEngine_v1::o1_updateSceneAnimations(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_updateSceneAnimations(%p) (%d)", (const void *)script, stackPos(0)); int times = stackPos(0); while (times--) { @@ -1170,23 +1157,23 @@ int KyraEngine::o1_updateSceneAnimations(ScriptState *script) { return 0; } -int KyraEngine::o1_sceneAnimationActive(ScriptState *script) { +int KyraEngine_v1::o1_sceneAnimationActive(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_sceneAnimationActive(%p) (%d)", (const void *)script, stackPos(0)); return _sprites->_anims[stackPos(0)].play; } -int KyraEngine::o1_setCharactersMovementDelay(ScriptState *script) { +int KyraEngine_v1::o1_setCharactersMovementDelay(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersMovementDelay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); setTimerDelay(stackPos(0)+5, stackPos(1)); return 0; } -int KyraEngine::o1_getCharactersFacing(ScriptState *script) { +int KyraEngine_v1::o1_getCharactersFacing(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersFacing(%p) (%d)", (const void *)script, stackPos(0)); return _characterList[stackPos(0)].facing; } -int KyraEngine::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { +int KyraEngine_v1::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_bkgdScrollSceneAndMasksRight(%p) (%d)", (const void *)script, stackPos(0)); _screen->copyBackgroundBlock(stackPos(0), 2, 0); _screen->copyBackgroundBlock2(stackPos(0)); @@ -1196,23 +1183,24 @@ int KyraEngine::o1_bkgdScrollSceneAndMasksRight(ScriptState *script) { return 0; } -int KyraEngine::o1_dispelMagicAnimation(ScriptState *script) { +int KyraEngine_v1::o1_dispelMagicAnimation(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_dispelMagicAnimation(%p) ()", (const void *)script); seq_dispelMagicAnimation(); return 0; } -int KyraEngine::o1_findBrightestFireberry(ScriptState *script) { +int KyraEngine_v1::o1_findBrightestFireberry(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_findBrightestFireberry(%p) ()", (const void *)script); - if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) { + if (_currentCharacter->sceneId >= 187 && _currentCharacter->sceneId <= 198) return 29; - } + if (_currentCharacter->sceneId == 133 || _currentCharacter->sceneId == 137 || - _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173) { + _currentCharacter->sceneId == 165 || _currentCharacter->sceneId == 173) return 29; - } + if (_itemInHand == 28) return 28; + int brightestFireberry = 107; if (_itemInHand >= 29 && _itemInHand <= 33) brightestFireberry = _itemInHand; @@ -1245,7 +1233,7 @@ int KyraEngine::o1_findBrightestFireberry(ScriptState *script) { return brightestFireberry; } -int KyraEngine::o1_setFireberryGlowPalette(ScriptState *script) { +int KyraEngine_v1::o1_setFireberryGlowPalette(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0)); int palIndex = 0; switch (stackPos(0)) { @@ -1282,19 +1270,19 @@ int KyraEngine::o1_setFireberryGlowPalette(ScriptState *script) { return 0; } -int KyraEngine::o1_setDeathHandlerFlag(ScriptState *script) { +int KyraEngine_v1::o1_setDeathHandlerFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setDeathHandlerFlag(%p) (%d)", (const void *)script, stackPos(0)); _deathHandler = stackPos(0); return 0; } -int KyraEngine::o1_drinkPotionAnimation(ScriptState *script) { +int KyraEngine_v1::o1_drinkPotionAnimation(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_drinkPotionAnimation(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); seq_playDrinkPotionAnim(stackPos(0), stackPos(1), stackPos(2)); return 0; } -int KyraEngine::o1_makeAmuletAppear(ScriptState *script) { +int KyraEngine_v1::o1_makeAmuletAppear(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_makeAmuletAppear(%p) ()", (const void *)script); WSAMovieV1 amulet(this); amulet.open("AMULET.WSA", 1, 0); @@ -1310,18 +1298,14 @@ int KyraEngine::o1_makeAmuletAppear(ScriptState *script) { nextTime = _system->getMillis() + 5 * _tickLength; uint8 code = _amuleteAnim[i]; - if (code == 3 || code == 7) { + if (code == 3 || code == 7) snd_playSoundEffect(0x71); - } - if (code == 5) { + if (code == 5) snd_playSoundEffect(0x72); - } - if (code == 14) { + if (code == 14) snd_playSoundEffect(0x73); - } - amulet.displayFrame(code); _animator->_updateScreen = true; @@ -1339,22 +1323,24 @@ int KyraEngine::o1_makeAmuletAppear(ScriptState *script) { return 0; } -int KyraEngine::o1_drawItemShapeIntoScene(ScriptState *script) { +int KyraEngine_v1::o1_drawItemShapeIntoScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_drawItemShapeIntoScene(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); int item = stackPos(0); int x = stackPos(1); int y = stackPos(2); int flags = stackPos(3); int onlyHidPage = stackPos(4); + if (flags) flags = 1; + if (onlyHidPage) { - _screen->drawShape(2, _shapes[220+item], x, y, 0, flags); + _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); } else { _screen->hideMouse(); _animator->restoreAllObjectBackgrounds(); - _screen->drawShape(2, _shapes[220+item], x, y, 0, flags); - _screen->drawShape(0, _shapes[220+item], x, y, 0, flags); + _screen->drawShape(2, _shapes[216+item], x, y, 0, flags); + _screen->drawShape(0, _shapes[216+item], x, y, 0, flags); _animator->flagAllObjectsForBkgdChange(); _animator->preserveAnyChangedBackgrounds(); _animator->flagAllObjectsForRefresh(); @@ -1364,13 +1350,13 @@ int KyraEngine::o1_drawItemShapeIntoScene(ScriptState *script) { return 0; } -int KyraEngine::o1_setCharactersCurrentFrame(ScriptState *script) { +int KyraEngine_v1::o1_setCharactersCurrentFrame(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setCharactersCurrentFrame(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _characterList[stackPos(0)].currentAnimFrame = stackPos(1); return 0; } -int KyraEngine::o1_waitForConfirmationMouseClick(ScriptState *script) { +int KyraEngine_v1::o1_waitForConfirmationMouseClick(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_waitForConfirmationMouseClick(%p) ()", (const void *)script); // if (mouseEnabled) { while (!_mousePressFlag) { @@ -1395,39 +1381,39 @@ int KyraEngine::o1_waitForConfirmationMouseClick(ScriptState *script) { return 0; } -int KyraEngine::o1_pageFlip(ScriptState *script) { +int KyraEngine_v1::o1_pageFlip(ScriptState *script) { warning("STUB: o1_pageFlip"); return 0; } -int KyraEngine::o1_setSceneFile(ScriptState *script) { +int KyraEngine_v1::o1_setSceneFile(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setSceneFile(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); setSceneFile(stackPos(0), stackPos(1)); return 0; } -int KyraEngine::o1_getItemInMarbleVase(ScriptState *script) { +int KyraEngine_v1::o1_getItemInMarbleVase(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getItemInMarbleVase(%p) ()", (const void *)script); return _marbleVaseItem; } -int KyraEngine::o1_setItemInMarbleVase(ScriptState *script) { +int KyraEngine_v1::o1_setItemInMarbleVase(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setItemInMarbleVase(%p) (%d)", (const void *)script, stackPos(0)); _marbleVaseItem = stackPos(0); return 0; } -int KyraEngine::o1_addItemToInventory(ScriptState *script) { +int KyraEngine_v1::o1_addItemToInventory(ScriptState *script) { warning("STUB: o1_addItemToInventory"); return 0; } -int KyraEngine::o1_intPrint(ScriptState *script) { +int KyraEngine_v1::o1_intPrint(ScriptState *script) { warning("STUB: o1_intPrint"); return 0; } -int KyraEngine::o1_shakeScreen(ScriptState *script) { +int KyraEngine_v1::o1_shakeScreen(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_shakeScreen(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int waitTicks = stackPos(1); int times = stackPos(0); @@ -1440,102 +1426,99 @@ int KyraEngine::o1_shakeScreen(ScriptState *script) { return 0; } -int KyraEngine::o1_createAmuletJewel(ScriptState *script) { +int KyraEngine_v1::o1_createAmuletJewel(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_createAmuletJewel(%p) (%d)", (const void *)script, stackPos(0)); seq_createAmuletJewel(stackPos(0), 0, 0, 0); return 0; } -int KyraEngine::o1_setSceneAnimCurrXY(ScriptState *script) { +int KyraEngine_v1::o1_setSceneAnimCurrXY(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setSceneAnimCurrXY(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); _sprites->_anims[stackPos(0)].x = stackPos(1); _sprites->_anims[stackPos(0)].y = stackPos(2); return 0; } -int KyraEngine::o1_poisonBrandonAndRemaps(ScriptState *script) { +int KyraEngine_v1::o1_poisonBrandonAndRemaps(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_poisonBrandonAndRemaps(%p) ()", (const void *)script); setBrandonPoisonFlags(1); return 0; } -int KyraEngine::o1_fillFlaskWithWater(ScriptState *script) { +int KyraEngine_v1::o1_fillFlaskWithWater(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_fillFlaskWithWater(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); seq_fillFlaskWithWater(stackPos(0), stackPos(1)); return 0; } -int KyraEngine::o1_getCharactersMovementDelay(ScriptState *script) { +int KyraEngine_v1::o1_getCharactersMovementDelay(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getCharactersMovementDelay(%p) (%d)", (const void *)script, stackPos(0)); return getTimerDelay(stackPos(0)+5); } -int KyraEngine::o1_getBirthstoneGem(ScriptState *script) { +int KyraEngine_v1::o1_getBirthstoneGem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getBirthstoneGem(%p) (%d)", (const void *)script, stackPos(0)); - if (stackPos(0) < 4) { + if (stackPos(0) < 4) return _birthstoneGemTable[stackPos(0)]; - } return 0; } -int KyraEngine::o1_queryBrandonStatusBit(ScriptState *script) { +int KyraEngine_v1::o1_queryBrandonStatusBit(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_queryBrandonStatusBit(%p) (%d)", (const void *)script, stackPos(0)); - if (_brandonStatusBit & stackPos(0)) { + if (_brandonStatusBit & stackPos(0)) return 1; - } return 0; } -int KyraEngine::o1_playFluteAnimation(ScriptState *script) { +int KyraEngine_v1::o1_playFluteAnimation(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_playFluteAnimation(%p) ()", (const void *)script); seq_playFluteAnimation(); return 0; } -int KyraEngine::o1_playWinterScrollSequence(ScriptState *script) { +int KyraEngine_v1::o1_playWinterScrollSequence(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_playWinterScrollSequence(%p) (%d)", (const void *)script, stackPos(0)); - if (!stackPos(0)) { + if (!stackPos(0)) seq_winterScroll2(); - } else { + else seq_winterScroll1(); - } return 0; } -int KyraEngine::o1_getIdolGem(ScriptState *script) { +int KyraEngine_v1::o1_getIdolGem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getIdolGem(%p) (%d)", (const void *)script, stackPos(0)); return _idolGemsTable[stackPos(0)]; } -int KyraEngine::o1_setIdolGem(ScriptState *script) { +int KyraEngine_v1::o1_setIdolGem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setIdolGem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _idolGemsTable[stackPos(0)] = stackPos(1); return 0; } -int KyraEngine::o1_totalItemsInScene(ScriptState *script) { +int KyraEngine_v1::o1_totalItemsInScene(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_totalItemsInScene(%p) (%d)", (const void *)script, stackPos(0)); return countItemsInScene(stackPos(0)); } -int KyraEngine::o1_restoreBrandonsMovementDelay(ScriptState *script) { +int KyraEngine_v1::o1_restoreBrandonsMovementDelay(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_restoreBrandonsMovementDelay(%p) ()", (const void *)script); setWalkspeed(_configWalkspeed); return 0; } -int KyraEngine::o1_setMousePos(ScriptState *script) { +int KyraEngine_v1::o1_setMousePos(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _system->warpMouse(stackPos(0), stackPos(1)); return 0; } -int KyraEngine::o1_getMouseState(ScriptState *script) { +int KyraEngine_v1::o1_getMouseState(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getMouseState(%p) ()", (const void *)script); return _mouseState; } -int KyraEngine::o1_setEntranceMouseCursorTrack(ScriptState *script) { +int KyraEngine_v1::o1_setEntranceMouseCursorTrack(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setEntranceMouseCursorTrack(%p) (%d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4)); _entranceMouseCursorTracks[0] = stackPos(0); _entranceMouseCursorTracks[1] = stackPos(1); @@ -1545,19 +1528,19 @@ int KyraEngine::o1_setEntranceMouseCursorTrack(ScriptState *script) { return 0; } -int KyraEngine::o1_itemAppearsOnGround(ScriptState *script) { +int KyraEngine_v1::o1_itemAppearsOnGround(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_itemAppearsOnGround(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); processItemDrop(_currentCharacter->sceneId, stackPos(0), stackPos(1), stackPos(2), 2, 0); return 0; } -int KyraEngine::o1_setNoDrawShapesFlag(ScriptState *script) { +int KyraEngine_v1::o1_setNoDrawShapesFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setNoDrawShapesFlag(%p) (%d)", (const void *)script, stackPos(0)); _animator->_noDrawShapesFlag = stackPos(0); return 0; } -int KyraEngine::o1_fadeEntirePalette(ScriptState *script) { +int KyraEngine_v1::o1_fadeEntirePalette(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_fadeEntirePalette(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); int cmd = stackPos(0); uint8 *fadePal = 0; @@ -1597,7 +1580,7 @@ int KyraEngine::o1_fadeEntirePalette(ScriptState *script) { return 0; } -int KyraEngine::o1_itemOnGroundHere(ScriptState *script) { +int KyraEngine_v1::o1_itemOnGroundHere(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_itemOnGroundHere(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < _roomTableSize); Room *curRoom = &_roomTable[stackPos(0)]; @@ -1608,53 +1591,52 @@ int KyraEngine::o1_itemOnGroundHere(ScriptState *script) { return 0; } -int KyraEngine::o1_queryCauldronState(ScriptState *script) { +int KyraEngine_v1::o1_queryCauldronState(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_queryCauldronState(%p) ()", (const void *)script); return _cauldronState; } -int KyraEngine::o1_setCauldronState(ScriptState *script) { +int KyraEngine_v1::o1_setCauldronState(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setCauldronState(%p) (%d)", (const void *)script, stackPos(0)); _cauldronState = stackPos(0); return _cauldronState; } -int KyraEngine::o1_queryCrystalState(ScriptState *script) { +int KyraEngine_v1::o1_queryCrystalState(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_queryCrystalState(%p) (%d)", (const void *)script, stackPos(0)); - if (!stackPos(0)) { + if (!stackPos(0)) return _crystalState[0]; - } else if (stackPos(0) == 1) { + else if (stackPos(0) == 1) return _crystalState[1]; - } return -1; } -int KyraEngine::o1_setCrystalState(ScriptState *script) { +int KyraEngine_v1::o1_setCrystalState(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setCrystalState(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); - if (!stackPos(0)) { + if (!stackPos(0)) _crystalState[0] = stackPos(1); - } else if (stackPos(0) == 1) { + else if (stackPos(0) == 1) _crystalState[1] = stackPos(1); - } return stackPos(1); } -int KyraEngine::o1_setPaletteRange(ScriptState *script) { +int KyraEngine_v1::o1_setPaletteRange(ScriptState *script) { warning("STUB: o1_setPaletteRange"); return 0; } -int KyraEngine::o1_shrinkBrandonDown(ScriptState *script) { +int KyraEngine_v1::o1_shrinkBrandonDown(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_shrinkBrandonDown(%p) (%d)", (const void *)script, stackPos(0)); int delayTime = stackPos(0); checkAmuletAnimFlags(); int scaleValue = _scaleTable[_currentCharacter->y1]; int scale = 0; - if (_scaleMode) { + + if (_scaleMode) scale = scaleValue; - } else { + else scale = 256; - } + int scaleModeBackUp = _scaleMode; _scaleMode = 1; int scaleEnd = scale >> 1; @@ -1669,15 +1651,15 @@ int KyraEngine::o1_shrinkBrandonDown(ScriptState *script) { return 0; } -int KyraEngine::o1_growBrandonUp(ScriptState *script) { +int KyraEngine_v1::o1_growBrandonUp(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_growBrandonUp(%p) ()", (const void *)script); int scaleValue = _scaleTable[_currentCharacter->y1]; int scale = 0; - if (_scaleMode) { + if (_scaleMode) scale = scaleValue; - } else { + else scale = 256; - } + int scaleModeBackUp = _scaleMode; _scaleMode = 1; for (int curScale = scale >> 1; curScale <= scale; ++curScale) { @@ -1690,33 +1672,33 @@ int KyraEngine::o1_growBrandonUp(ScriptState *script) { return 0; } -int KyraEngine::o1_setBrandonScaleXAndY(ScriptState *script) { +int KyraEngine_v1::o1_setBrandonScaleXAndY(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setBrandonScaleXAndY(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); _animator->_brandonScaleX = stackPos(0); _animator->_brandonScaleY = stackPos(1); return 0; } -int KyraEngine::o1_resetScaleMode(ScriptState *script) { +int KyraEngine_v1::o1_resetScaleMode(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_resetScaleMode(%p) ()", (const void *)script); _scaleMode = 0; return 0; } -int KyraEngine::o1_getScaleDepthTableValue(ScriptState *script) { +int KyraEngine_v1::o1_getScaleDepthTableValue(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getScaleDepthTableValue(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < ARRAYSIZE(_scaleTable)); return _scaleTable[stackPos(0)]; } -int KyraEngine::o1_setScaleDepthTableValue(ScriptState *script) { +int KyraEngine_v1::o1_setScaleDepthTableValue(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setScaleDepthTableValue(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < ARRAYSIZE(_scaleTable)); _scaleTable[stackPos(0)] = stackPos(1); return stackPos(1); } -int KyraEngine::o1_message(ScriptState *script) { +int KyraEngine_v1::o1_message(ScriptState *script) { if (_flags.isTalkie) { debugC(3, kDebugLevelScriptFuncs, "o1_message(%p) (%d, '%s', %d)", (const void *)script, stackPos(0), stackPosString(1), stackPos(2)); drawSentenceCommand(stackPosString(1), stackPos(2)); @@ -1728,65 +1710,65 @@ int KyraEngine::o1_message(ScriptState *script) { return 0; } -int KyraEngine::o1_checkClickOnNPC(ScriptState *script) { +int KyraEngine_v1::o1_checkClickOnNPC(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_checkClickOnNPC(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); return checkForNPCScriptRun(stackPos(0), stackPos(1)); } -int KyraEngine::o1_getFoyerItem(ScriptState *script) { +int KyraEngine_v1::o1_getFoyerItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_getFoyerItem(%p) (%d)", (const void *)script, stackPos(0)); assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); return _foyerItemTable[stackPos(0)]; } -int KyraEngine::o1_setFoyerItem(ScriptState *script) { +int KyraEngine_v1::o1_setFoyerItem(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setFoyerItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); assert(stackPos(0) < ARRAYSIZE(_foyerItemTable)); _foyerItemTable[stackPos(0)] = stackPos(1); return stackPos(1); } -int KyraEngine::o1_setNoItemDropRegion(ScriptState *script) { +int KyraEngine_v1::o1_setNoItemDropRegion(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setNoItemDropRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3)); addToNoDropRects(stackPos(0), stackPos(1), stackPos(2), stackPos(3)); return 0; } -int KyraEngine::o1_walkMalcolmOn(ScriptState *script) { +int KyraEngine_v1::o1_walkMalcolmOn(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_walkMalcolmOn(%p) ()", (const void *)script); if (!_malcolmFlag) _malcolmFlag = 1; return 0; } -int KyraEngine::o1_passiveProtection(ScriptState *script) { +int KyraEngine_v1::o1_passiveProtection(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_passiveProtection(%p) ()", (const void *)script); return 1; } -int KyraEngine::o1_setPlayingLoop(ScriptState *script) { +int KyraEngine_v1::o1_setPlayingLoop(ScriptState *script) { warning("STUB: o1_setPlayingLoop"); return 0; } -int KyraEngine::o1_brandonToStoneSequence(ScriptState *script) { +int KyraEngine_v1::o1_brandonToStoneSequence(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_brandonToStoneSequence(%p) ()", (const void *)script); seq_brandonToStone(); return 0; } -int KyraEngine::o1_brandonHealingSequence(ScriptState *script) { +int KyraEngine_v1::o1_brandonHealingSequence(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_brandonHealingSequence(%p) ()", (const void *)script); seq_brandonHealing(); return 0; } -int KyraEngine::o1_protectCommandLine(ScriptState *script) { +int KyraEngine_v1::o1_protectCommandLine(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_protectCommandLine(%p) (%d)", (const void *)script, stackPos(0)); return stackPos(0); } -int KyraEngine::o1_pauseMusicSeconds(ScriptState *script) { +int KyraEngine_v1::o1_pauseMusicSeconds(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_pauseMusicSeconds(%p) ()", (const void *)script); // if music disabled // return @@ -1794,18 +1776,18 @@ int KyraEngine::o1_pauseMusicSeconds(ScriptState *script) { return 0; } -int KyraEngine::o1_resetMaskRegion(ScriptState *script) { +int KyraEngine_v1::o1_resetMaskRegion(ScriptState *script) { warning("STUB: o1_resetMaskRegion"); return 0; } -int KyraEngine::o1_setPaletteChangeFlag(ScriptState *script) { +int KyraEngine_v1::o1_setPaletteChangeFlag(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_setPaletteChangeFlag(%p) (%d)", (const void *)script, stackPos(0)); _paletteChanged = stackPos(0); return _paletteChanged; } -int KyraEngine::o1_fillRect(ScriptState *script) { +int KyraEngine_v1::o1_fillRect(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_fillRect(%p) (%d, %d, %d, %d, %d, 0x%X)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5)); int videoPageBackup = _screen->_curPage; _screen->_curPage = stackPos(0); @@ -1814,21 +1796,22 @@ int KyraEngine::o1_fillRect(ScriptState *script) { return 0; } -int KyraEngine::o1_vocUnload(ScriptState *script) { +int KyraEngine_v1::o1_vocUnload(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_vocUnload(%p) ()", (const void *)script); // this should unload all voc files (not needed) return 0; } -int KyraEngine::o1_vocLoad(ScriptState *script) { +int KyraEngine_v1::o1_vocLoad(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_vocLoad(%p) (%d)", (const void *)script, stackPos(0)); // this should load the specified voc file (not needed) return 0; } -int KyraEngine::o1_dummy(ScriptState *script) { +int KyraEngine_v1::o1_dummy(ScriptState *script) { debugC(3, kDebugLevelScriptFuncs, "o1_dummy(%p) ()", (const void *)script); return 0; } } // end of namespace Kyra + diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp index cf5eb9cb90..591eb29f9b 100644 --- a/engines/kyra/seqplayer.cpp +++ b/engines/kyra/seqplayer.cpp @@ -74,11 +74,11 @@ uint8 *SeqPlayer::setPanPages(int pageNum, int shape) { uint16 numShapes = READ_LE_UINT16(data); if (shape < numShapes) { uint32 offs = 0; - if (_vm->gameFlags().useAltShapeHeader) { + if (_vm->gameFlags().useAltShapeHeader) offs = READ_LE_UINT32(data + 2 + shape * 4); - } else { + else offs = READ_LE_UINT16(data + 2 + shape * 2); - } + if (offs != 0) { data += offs; uint16 sz = READ_LE_UINT16(data + 6); @@ -139,9 +139,8 @@ void SeqPlayer::s1_wsaOpen() { void SeqPlayer::s1_wsaClose() { uint8 wsaObj = *_seqData++; assert(wsaObj < ARRAYSIZE(_seqMovies)); - if (_seqMovies[wsaObj].movie) { + if (_seqMovies[wsaObj].movie) _seqMovies[wsaObj].movie->close(); - } } void SeqPlayer::s1_wsaPlayFrame() { @@ -207,23 +206,21 @@ void SeqPlayer::s1_shuffleScreen() { void SeqPlayer::s1_copyView() { int y = 128; - if (!_copyViewOffs) { + if (!_copyViewOffs) y -= 8; - } - if (_specialBuffer && !_copyViewOffs) { + + if (_specialBuffer && !_copyViewOffs) _screen->copyToPage0(16, y, 3, _specialBuffer); - } else { + else _screen->copyRegion(0, 16, 0, 16, 320, y, 2, 0); - } } void SeqPlayer::s1_loopInit() { uint8 seqLoop = *_seqData++; - if (seqLoop < ARRAYSIZE(_seqLoopTable)) { + if (seqLoop < ARRAYSIZE(_seqLoopTable)) _seqLoopTable[seqLoop].ptr = _seqData; - } else { + else _seqQuitFlag = true; - } } void SeqPlayer::s1_loopInc() { @@ -250,13 +247,13 @@ void SeqPlayer::s1_loadPalette() { uint8 colNum = *_seqData++; if (_vm->gameFlags().platform == Common::kPlatformAmiga) { - if (!colNum) { + if (!colNum) memcpy(_screen->_currentPalette, _screen->_currentPalette + 576, 3*32); - } else if (colNum == 3) { + else if (colNum == 3) memcpy(_screen->_currentPalette, _screen->_currentPalette + 672, 3*32); - } else if (colNum == 4) { + else if (colNum == 4) memcpy(_screen->_currentPalette, _screen->_currentPalette + 288, 3*32); - } + _screen->setScreenPalette(_screen->_currentPalette); } else { uint32 fileSize; @@ -304,31 +301,28 @@ void SeqPlayer::s1_printTalkText() { uint8 fillColor = *_seqData++; int b; if (_seqTalkTextPrinted && !_seqTalkTextRestored) { - if (_seqWsaCurDecodePage != 0 && !_specialBuffer) { + if (_seqWsaCurDecodePage != 0 && !_specialBuffer) b = 2; - } else { + else b = 0; - } _vm->text()->restoreTalkTextMessageBkgd(2, b); } _seqTalkTextPrinted = true; _seqTalkTextRestored = false; - if (_seqWsaCurDecodePage != 0 && !_specialBuffer) { + if (_seqWsaCurDecodePage != 0 && !_specialBuffer) b = 2; - } else { + else b = 0; - } _vm->text()->printTalkTextMessage(_vm->seqTextsTable()[txt], x, y, fillColor, b, 2); } void SeqPlayer::s1_restoreTalkText() { if (_seqTalkTextPrinted && !_seqTalkTextRestored) { int b; - if (_seqWsaCurDecodePage != 0 && !_specialBuffer) { + if (_seqWsaCurDecodePage != 0 && !_specialBuffer) b = 2; - } else { + else b = 0; - } _vm->text()->restoreTalkTextMessageBkgd(2, b); _seqTalkTextRestored = true; } @@ -358,12 +352,11 @@ void SeqPlayer::s1_copyRegion() { void SeqPlayer::s1_copyRegionSpecial() { static const uint8 colorMap[] = { 0, 0, 0, 0, 0, 12, 12, 0, 0, 0, 0, 0 }; const char *copyStr = 0; - if (!_vm->gameFlags().isTalkie) { + if (!_vm->gameFlags().isTalkie) copyStr = "Copyright (c) 1992 Westwood Studios"; - } else { + else copyStr = "Copyright (c) 1992,1993 Westwood Studios"; - } - + uint8 so = *_seqData++; switch (so) { case 0: @@ -625,9 +618,9 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { if (skipSeq && _vm->seq_skipSequence()) { while (1) { uint8 code = *_seqData; - if (commands[code].proc == &SeqPlayer::s1_endOfScript || commands[code].proc == &SeqPlayer::s1_break) { + if (commands[code].proc == &SeqPlayer::s1_endOfScript || commands[code].proc == &SeqPlayer::s1_break) break; - } + _seqData += commands[code].len; } skipSeq = false; @@ -644,11 +637,11 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { _screen->printText(charStr, _seqDisplayedTextX, 180, 0xF, 0xC); _seqDisplayedTextX += _screen->getCharWidth(charStr[0]); ++_seqDisplayedChar; - if (_vm->seqTextsTable()[_seqDisplayedText][_seqDisplayedChar] == '\0') { + + if (_vm->seqTextsTable()[_seqDisplayedText][_seqDisplayedChar] == '\0') _seqDisplayedTextTimer = 0xFFFFFFFF; - } else { + else _seqDisplayedTextTimer = _system->getMillis() + 1000 / ((_vm->gameFlags().lang == Common::FR_FRA) ? 120 : 60); - } } } @@ -670,3 +663,4 @@ bool SeqPlayer::playSequence(const uint8 *seqData, bool skipSeq) { } // End of namespace Kyra + diff --git a/engines/kyra/seqplayer.h b/engines/kyra/seqplayer.h index 1032d0126e..9f2b846297 100644 --- a/engines/kyra/seqplayer.h +++ b/engines/kyra/seqplayer.h @@ -121,3 +121,4 @@ protected: } // End of namespace Kyra #endif + diff --git a/engines/kyra/sequences_v1.cpp b/engines/kyra/sequences_v1.cpp index 771949b852..56e946a526 100644 --- a/engines/kyra/sequences_v1.cpp +++ b/engines/kyra/sequences_v1.cpp @@ -89,9 +89,8 @@ void KyraEngine::seq_demo() { void KyraEngine::seq_intro() { debugC(9, kDebugLevelMain, "KyraEngine::seq_intro()"); - if (_flags.isTalkie) { + if (_flags.isTalkie) _res->loadPakFile("INTRO.VRM"); - } static const IntroProc introProcTable[] = { &KyraEngine::seq_introLogos, @@ -113,17 +112,18 @@ void KyraEngine::seq_intro() { if (_flags.platform != Common::kPlatformFMTowns) snd_playTheme(0, 2); _text->setTalkCoords(144); - for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) { + + for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) (this->*introProcTable[i])(); - } + _text->setTalkCoords(136); delay(30 * _tickLength); _seq->setCopyViewOffs(false); _sound->haltTrack(); _sound->voiceStop(); - if (_flags.isTalkie) { + + if (_flags.isTalkie) _res->unloadPakFile("INTRO.VRM"); - } } void KyraEngine::seq_introLogos() { @@ -232,23 +232,23 @@ void KyraEngine::seq_introStory() { debugC(9, kDebugLevelMain, "KyraEngine::seq_introStory()"); _screen->clearPage(3); _screen->clearPage(0); - if (_flags.isTalkie) { + + if (_flags.isTalkie) return; - } else if (_flags.lang == Common::EN_ANY && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) { + else if (_flags.lang == Common::EN_ANY && (_flags.platform == Common::kPlatformPC || _flags.platform == Common::kPlatformAmiga)) _screen->loadBitmap("TEXT.CPS", 3, 3, _screen->_currentPalette); - } else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) { + else if (_flags.lang == Common::EN_ANY || _flags.lang == Common::JA_JPN) _screen->loadBitmap("TEXT_ENG.CPS", 3, 3, _screen->_currentPalette); - } else if (_flags.lang == Common::DE_DEU) { + else if (_flags.lang == Common::DE_DEU) _screen->loadBitmap("TEXT_GER.CPS", 3, 3, _screen->_currentPalette); - } else if (_flags.lang == Common::FR_FRA) { + else if (_flags.lang == Common::FR_FRA) _screen->loadBitmap("TEXT_FRE.CPS", 3, 3, _screen->_currentPalette); - } else if (_flags.lang == Common::ES_ESP) { + else if (_flags.lang == Common::ES_ESP) _screen->loadBitmap("TEXT_SPA.CPS", 3, 3, _screen->_currentPalette); - } else if (_flags.lang == Common::IT_ITA) { + else if (_flags.lang == Common::IT_ITA) _screen->loadBitmap("TEXT_ITA.CPS", 3, 3, _screen->_currentPalette); - } else { + else warning("no story graphics file found"); - } _screen->setScreenPalette(_screen->_currentPalette); _screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0); @@ -314,7 +314,7 @@ void KyraEngine::seq_createAmuletJewel(int jewel, int page, int noSound, int dra _screen->hideMouse(); if (!drawOnly) { for (int i = 0; specialJewelTable[i] != 0xFFFF; ++i) { - _screen->drawShape(page, _shapes[4+specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->drawShape(page, _shapes[specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); _screen->updateScreen(); delayWithTicks(3); } @@ -340,13 +340,13 @@ void KyraEngine::seq_createAmuletJewel(int jewel, int page, int noSound, int dra if (opcodes) { for (int i = 0; opcodes[i] != 0xFFFF; ++i) { - _screen->drawShape(page, _shapes[4+opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->drawShape(page, _shapes[opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); _screen->updateScreen(); delayWithTicks(3); } } } - _screen->drawShape(page, _shapes[327+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->drawShape(page, _shapes[323+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0); _screen->updateScreen(); _screen->showMouse(); setGameFlag(0x55+jewel); @@ -691,11 +691,12 @@ void KyraEngine::seq_makeBrandonNormal2() { _animator->setBrandonAnimSeqSize(4, 48); _currentCharacter->currentAnimFrame = 7; _animator->animRefreshNPC(0); - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) { + + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) _screen->fadeSpecialPalette(31, 234, 13, 4); - } else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) { + else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) _screen->fadeSpecialPalette(14, 228, 15, 4); - } + freeShapes123(); _screen->showMouse(); } @@ -721,21 +722,23 @@ void KyraEngine::seq_makeBrandonWisp() { delayWithTicks(8); } _brandonStatusBit |= 2; - if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) { + + if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) setTimerCountdown(14, 18000); - } else { + else setTimerCountdown(14, 7200); - } + _animator->_brandonDrawFrame = 113; _brandonStatusBit0x02Flag = 1; _currentCharacter->currentAnimFrame = 113; _animator->animRefreshNPC(0); _animator->updateAllObjectShapes(); - if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) { + + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) _screen->fadeSpecialPalette(30, 234, 13, 4); - } else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) { + else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) _screen->fadeSpecialPalette(14, 228, 15, 4); - } + freeShapes123(); _screen->showMouse(); } @@ -909,12 +912,12 @@ void KyraEngine::seq_playDrinkPotionAnim(int item, int unk2, int flags) { int KyraEngine::seq_playEnd() { debugC(9, kDebugLevelMain, "KyraEngine::seq_playEnd()"); - if (_endSequenceSkipFlag) { + if (_endSequenceSkipFlag) return 0; - } - if (_deathHandler == 8) { + + if (_deathHandler == 8) return 0; - } + _screen->_curPage = 2; if (_endSequenceNeedLoading) { snd_playWanderScoreViaMap(50, 1); @@ -959,9 +962,8 @@ int KyraEngine::seq_playEnd() { return 1; } else { _endSequenceSkipFlag = 1; - if (_text->printed()) { + if (_text->printed()) _text->restoreTalkTextMessageBkgd(2, 0); - } _screen->_curPage = 0; _screen->hideMouse(); _screen->fadeSpecialPalette(32, 228, 20, 60); @@ -979,11 +981,10 @@ int KyraEngine::seq_playEnd() { snd_playSoundEffect(0x40); for (int i = 0; i < 22; ++i) { delayUntil(nextTime); - if (i == 4) { + if (i == 4) snd_playSoundEffect(0x3E); - } else if (i == 20) { + else if (i == 20) snd_playSoundEffect(0x0E); - } nextTime = _system->getMillis() + 8 * _tickLength; _finalA->displayFrame(i); _screen->updateScreen(); @@ -1452,10 +1453,13 @@ int KyraEngine::handleBeadState() { beadState1.y = y; } } + _screen->copyCurPageBlock(x >> 3, y, beadState1.width, beadState1.height, _endSequenceBackUpRect); _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); + if (_lastDisplayedPanPage > 17) _lastDisplayedPanPage = 0; + _screen->addBitBlitRect(x, y, beadState1.width2, beadState1.height); } break; @@ -1465,19 +1469,21 @@ int KyraEngine::handleBeadState() { timer1 = _system->getMillis() + 4 * _tickLength; _screen->copyFromCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + beadState1.x = beadState1.dstX + table1[beadState1.tableIndex]; beadState1.y = beadState1.dstY + table2[beadState1.tableIndex]; _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); + _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], beadState1.x, beadState1.y, 0, 0); - if (_lastDisplayedPanPage >= 17) { + if (_lastDisplayedPanPage >= 17) _lastDisplayedPanPage = 0; - } + _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); + ++beadState1.tableIndex; - if (beadState1.tableIndex > 24) { + if (beadState1.tableIndex > 24) beadState1.tableIndex = 0; _unkEndSeqVar4 = 1; - } if (_system->getMillis() > timer2 && _malcolmFlag == 7 && !_unkAmuletVar && !_text->printed()) { snd_playSoundEffect(0x0B); if (_currentCharacter->x1 > 233 && _currentCharacter->x1 < 305 && _currentCharacter->y1 > 85 && _currentCharacter->y1 < 105 && @@ -1491,9 +1497,9 @@ int KyraEngine::handleBeadState() { beadState1.unk9 = _currentCharacter->y1 - 30; } - if (_text->printed()) { + if (_text->printed()) _text->restoreTalkTextMessageBkgd(2, 0); - } + initBeadState(beadState1.x, beadState1.y, beadState1.unk8, beadState1.unk9, 12, &beadState2); _lastDisplayedPanPage = 18; } @@ -1569,9 +1575,8 @@ int KyraEngine::handleBeadState() { beadState1.y = y; _screen->copyCurPageBlock(beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect); _screen->drawShape(2, _panPagesTable[_lastDisplayedPanPage++], x, y, 0, 0); - if (_lastDisplayedPanPage > 17) { + if (_lastDisplayedPanPage > 17) _lastDisplayedPanPage = 0; - } _screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height); } } @@ -1595,21 +1600,20 @@ void KyraEngine::initBeadState(int x, int y, int x2, int y2, int unk, BeadState int xDiff = x2 - x; int yDiff = y2 - y; int unk1 = 0, unk2 = 0; - if (xDiff > 0) { + if (xDiff > 0) unk1 = 1; - } else if (xDiff == 0) { + else if (xDiff == 0) unk1 = 0; - } else { + else unk1 = -1; - } - if (yDiff > 0) { + + if (yDiff > 0) unk2 = 1; - } else if (yDiff == 0) { + else if (yDiff == 0) unk2 = 0; - } else { + else unk2 = -1; - } xDiff = ABS(xDiff); yDiff = ABS(yDiff); @@ -1626,9 +1630,8 @@ void KyraEngine::initBeadState(int x, int y, int x2, int y2, int unk, BeadState int KyraEngine::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { debugC(9, kDebugLevelMain, "KyraEngine::processBead(%d, %d, %p, %p, %p)", x, y, (const void *)&x2, (const void *)&y2, (const void *)ptr); - if (x == ptr->dstX && y == ptr->dstY) { + if (x == ptr->dstX && y == ptr->dstY) return 1; - } int xPos = x, yPos = y; if (ptr->width >= ptr->height) { @@ -1652,13 +1655,11 @@ int KyraEngine::processBead(int x, int y, int &x2, int &y2, BeadState *ptr) { } int temp = ABS(x - ptr->dstX); - if (ptr->unk9 > temp) { + if (ptr->unk9 > temp) xPos = ptr->dstX; - } temp = ABS(y - ptr->dstY); - if (ptr->unk9 > temp) { + if (ptr->unk9 > temp) yPos = ptr->dstY; - } x2 = xPos; y2 = yPos; return 0; @@ -1789,21 +1790,23 @@ void KyraEngine::drawJewelPress(int jewel, int drawSpecial) { debugC(9, kDebugLevelMain, "KyraEngine::drawJewelPress(%d, %d)", jewel, drawSpecial); _screen->hideMouse(); int shape = 0; - if (drawSpecial) { + + if (drawSpecial) shape = 0x14E; - } else { + else shape = jewel + 0x149; - } + snd_playSoundEffect(0x45); - _screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->drawShape(0, _shapes[shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); _screen->updateScreen(); delayWithTicks(2); - if (drawSpecial) { + + if (drawSpecial) shape = 0x148; - } else { + else shape = jewel + 0x143; - } - _screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + + _screen->drawShape(0, _shapes[shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0); _screen->updateScreen(); _screen->showMouse(); } @@ -1815,18 +1818,14 @@ void KyraEngine::drawJewelsFadeOutStart() { static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF }; static const uint16 jewelTable4[] = { 0x165, 0x161, 0x15B, 0x156, 0x151, 0xFFFF }; for (int i = 0; jewelTable1[i] != 0xFFFF; ++i) { - if (queryGameFlag(0x57)) { - _screen->drawShape(0, _shapes[4+jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0); - } - if (queryGameFlag(0x59)) { - _screen->drawShape(0, _shapes[4+jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0); - } - if (queryGameFlag(0x56)) { - _screen->drawShape(0, _shapes[4+jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0); - } - if (queryGameFlag(0x58)) { - _screen->drawShape(0, _shapes[4+jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0); - } + if (queryGameFlag(0x57)) + _screen->drawShape(0, _shapes[jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0); + if (queryGameFlag(0x59)) + _screen->drawShape(0, _shapes[jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0); + if (queryGameFlag(0x56)) + _screen->drawShape(0, _shapes[jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0); + if (queryGameFlag(0x58)) + _screen->drawShape(0, _shapes[jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0); _screen->updateScreen(); delayWithTicks(3); } @@ -1836,36 +1835,34 @@ void KyraEngine::drawJewelsFadeOutEnd(int jewel) { debugC(9, kDebugLevelMain, "KyraEngine::drawJewelsFadeOutEnd(%d)", jewel); static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF }; int newDelay = 0; + switch (jewel - 1) { case 2: - if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) { + if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) newDelay = 18900; - } else { + else newDelay = 8100; - } break; default: newDelay = 3600; break; } + setGameFlag(0xF1); setTimerCountdown(19, newDelay); _screen->hideMouse(); for (int i = 0; jewelTable[i] != 0xFFFF; ++i) { uint16 shape = jewelTable[i]; - if (queryGameFlag(0x57)) { - _screen->drawShape(0, _shapes[4+shape], _amuletX2[2], _amuletY2[2], 0, 0); - } - if (queryGameFlag(0x59)) { - _screen->drawShape(0, _shapes[4+shape], _amuletX2[4], _amuletY2[4], 0, 0); - } - if (queryGameFlag(0x56)) { - _screen->drawShape(0, _shapes[4+shape], _amuletX2[1], _amuletY2[1], 0, 0); - } - if (queryGameFlag(0x58)) { - _screen->drawShape(0, _shapes[4+shape], _amuletX2[3], _amuletY2[3], 0, 0); - } + if (queryGameFlag(0x57)) + _screen->drawShape(0, _shapes[shape], _amuletX2[2], _amuletY2[2], 0, 0); + if (queryGameFlag(0x59)) + _screen->drawShape(0, _shapes[shape], _amuletX2[4], _amuletY2[4], 0, 0); + if (queryGameFlag(0x56)) + _screen->drawShape(0, _shapes[shape], _amuletX2[1], _amuletY2[1], 0, 0); + if (queryGameFlag(0x58)) + _screen->drawShape(0, _shapes[shape], _amuletX2[3], _amuletY2[3], 0, 0); + _screen->updateScreen(); delayWithTicks(3); } @@ -1873,3 +1870,4 @@ void KyraEngine::drawJewelsFadeOutEnd(int jewel) { } } // end of namespace Kyra + diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp index c396ac0567..d5ea1da655 100644 --- a/engines/kyra/sequences_v2.cpp +++ b/engines/kyra/sequences_v2.cpp @@ -21,7 +21,7 @@ */ #include "kyra/kyra.h" -#include "kyra/kyra2.h" +#include "kyra/kyra_v2.h" #include "kyra/screen.h" #include "kyra/wsamovie.h" #include "kyra/sound.h" @@ -111,9 +111,9 @@ void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) { _screen->updateScreen(); uint32 currTime = _system->getMillis(); - if (seqDelay <= currTime && mayEndLoop) + if (seqDelay <= currTime && mayEndLoop) { break; - else { + } else { uint32 loopTime = currTime - startTime; delay(loopTime < _tickLength ? loopTime : _tickLength); } @@ -307,9 +307,9 @@ void KyraEngine_v2::seq_introOverviewOver1(int currentFrame) { void KyraEngine_v2::seq_introOverviewForest(int currentFrame) { debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverviewForest(%i)", currentFrame); - if (currentFrame == 11) + if (currentFrame == 11) { seq_waitForChatsToFinish(); - else if(currentFrame == 12) { + } else if(currentFrame == 12) { delay(25); seq_playIntroChat(2); } @@ -327,9 +327,9 @@ void KyraEngine_v2::seq_introOverviewDragon(int currentFrame) { int KyraEngine_v2::seq_introTitle(int seqNum) { debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introtitle(%i)", seqNum); - if (seqNum == 1) + if (seqNum == 1) { _sound->playTrack(3); - else if (seqNum == 25) { + } else if (seqNum == 25) { // XXX: handle menu return 200; } @@ -481,3 +481,4 @@ void KyraEngine_v2::seq_unloadWSA(int wsaNum) { } } // end of namespace Kyra + diff --git a/engines/kyra/sound.cpp b/engines/kyra/sound.cpp index d2e3a64d2d..3b7234709f 100644 --- a/engines/kyra/sound.cpp +++ b/engines/kyra/sound.cpp @@ -107,15 +107,13 @@ SoundMidiPC::SoundMidiPC(KyraEngine *vm, Audio::Mixer *mixer, MidiDriver *driver memset(_channel, 0, sizeof(MidiChannel*) * 32); memset(_channelVolume, 50, sizeof(uint8) * 16); _channelVolume[10] = 100; - for (int i = 0; i < 16; ++i) { + for (int i = 0; i < 16; ++i) _virChannel[i] = i; - } _volume = 0; int ret = open(); - if (ret != MERR_ALREADY_OPEN && ret != 0) { + if (ret != MERR_ALREADY_OPEN && ret != 0) error("couldn't open midi driver"); - } } SoundMidiPC::~SoundMidiPC() { @@ -371,9 +369,9 @@ void SoundMidiPC::onTimer(void *refCon) { music->send(0x80 | j | i << 8); } } - for (int i = 0; i < 16; ++i) { + + for (int i = 0; i < 16; ++i) music->send(0x007BB0 | i); - } } if (music->_isPlaying) { @@ -472,8 +470,9 @@ void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) { // the original does -2 here we handle this inside _sound->playTrack() _sound->playTrack(command); } - } else + } else { _sound->haltTrack(); + } } else { static const int8 soundTable[] = { -1, 0, -1, 1, 0, 3, 0, 2, @@ -496,9 +495,8 @@ void KyraEngine::snd_playWanderScoreViaMap(int command, int restart) { //} assert(command*2+1 < ARRAYSIZE(soundTable)); if (_curMusicTheme != soundTable[command*2]+1) { - if (soundTable[command*2] != -1) { + if (soundTable[command*2] != -1) snd_playTheme(soundTable[command*2]+1); - } } if (command != 1) { @@ -525,11 +523,10 @@ void KyraEngine::snd_playVoiceFile(int id) { void KyraEngine::snd_voiceWaitForFinish(bool ingame) { debugC(9, kDebugLevelMain | kDebugLevelSound, "KyraEngine::snd_voiceWaitForFinish(%d)", ingame); while (_sound->voiceIsPlaying() && !_skipFlag) { - if (ingame) { + if (ingame) delay(10, true); - } else { + else _system->delayMillis(10); - } } } @@ -559,3 +556,4 @@ const Sound::SpeechCodecs Sound::_supportedCodes[] = { }; } // end of namespace Kyra + diff --git a/engines/kyra/sound_adlib.cpp b/engines/kyra/sound_adlib.cpp index 48f6761ab8..765a20a558 100644 --- a/engines/kyra/sound_adlib.cpp +++ b/engines/kyra/sound_adlib.cpp @@ -558,9 +558,8 @@ int AdlibDriver::snd_unkOpcode3(va_list &list) { Channel &channel = _channels[_curChannel]; channel.priority = 0; channel.dataptr = 0; - if (value != 9) { + if (value != 9) noteOff(channel); - } ++value; } @@ -720,9 +719,8 @@ void AdlibDriver::executePrograms() { if ((_syncJumpMask & (1 << _curChannel)) == 0) continue; - if (_channels[_curChannel].dataptr && !_channels[_curChannel].lock) { + if (_channels[_curChannel].dataptr && !_channels[_curChannel].lock) forceUnlock = false; - } } if (forceUnlock) { @@ -735,20 +733,17 @@ void AdlibDriver::executePrograms() { for (_curChannel = 9; _curChannel >= 0; --_curChannel) { int result = 1; - if (!_channels[_curChannel].dataptr) { + if (!_channels[_curChannel].dataptr) continue; - } - if (_channels[_curChannel].lock && (_syncJumpMask & (1 << _curChannel))) { + if (_channels[_curChannel].lock && (_syncJumpMask & (1 << _curChannel))) continue; - } - + Channel &channel = _channels[_curChannel]; _curRegOffset = _regOffset[_curChannel]; - if (channel.tempoReset) { + if (channel.tempoReset) channel.tempo = _tempo; - } uint8 backup = channel.position; channel.position += channel.tempo; @@ -936,9 +931,8 @@ void AdlibDriver::setupDuration(uint8 duration, Channel &channel) { channel.duration = duration + (getRandomNr() & channel.durationRandomness); return; } - if (channel.fractionalSpacing) { + if (channel.fractionalSpacing) channel.spacing2 = (duration >> 3) * channel.fractionalSpacing; - } channel.duration = duration; } @@ -1228,9 +1222,8 @@ void AdlibDriver::secondaryEffect1(Channel &channel) { uint8 temp = channel.unk18; channel.unk18 += channel.unk19; if (channel.unk18 < temp) { - if (--channel.unk21 < 0) { + if (--channel.unk21 < 0) channel.unk21 = channel.unk20; - } writeOPL(channel.unk22 + _curRegOffset, _soundData[channel.offset + channel.unk21]); } } @@ -1336,9 +1329,8 @@ int AdlibDriver::update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 v int AdlibDriver::update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value) { channel.priority = 0; - if (_curChannel != 9) { + if (_curChannel != 9) noteOff(channel); - } dataptr = 0; return 2; } @@ -1388,9 +1380,8 @@ int AdlibDriver::update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, u uint8 *ptr = getProgram(value); uint8 chan = *ptr; - if (!_channels[chan].dataptr) { + if (!_channels[chan].dataptr) return 0; - } dataptr -= 2; return 2; @@ -1454,9 +1445,8 @@ int AdlibDriver::updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value } } - if (!(value & _unkValue4)) { + if (!(value & _unkValue4)) ++_unkValue5; - } dataptr -= 2; channel.duration = 1; @@ -2225,7 +2215,7 @@ SoundAdlibPC::SoundAdlibPC(KyraEngine *vm, Audio::Mixer *mixer) if (_v2) { // TODO: Figure out if Kyra 2 uses sound triggers at all. - _soundTriggers = NULL; + _soundTriggers = 0; _numSoundTriggers = 0; } else { _soundTriggers = _kyra1SoundTriggers; @@ -2250,9 +2240,8 @@ void SoundAdlibPC::process() { if (trigger < _numSoundTriggers) { int soundId = _soundTriggers[trigger]; - if (soundId) { + if (soundId) playTrack(soundId); - } } else { warning("Unknown sound trigger %d", trigger); // TODO: At this point, we really want to clear the trigger... @@ -2408,3 +2397,4 @@ void SoundAdlibPC::unk2() { } } // end of namespace Kyra + diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp index 74d6cc00a9..e046335131 100644 --- a/engines/kyra/sound_digital.cpp +++ b/engines/kyra/sound_digital.cpp @@ -321,9 +321,8 @@ SoundDigital::SoundDigital(KyraEngine *vm, Audio::Mixer *mixer) : _vm(vm), _mixe } SoundDigital::~SoundDigital() { - for (int i = 0; i < SOUND_STREAMS; ++i) { + for (int i = 0; i < SOUND_STREAMS; ++i) stopSound(i); - } } bool SoundDigital::init() { @@ -383,9 +382,9 @@ void SoundDigital::stopSound(int channel) { } void SoundDigital::beginFadeOut(int channel) { - if (isPlaying(channel)) { + if (isPlaying(channel)) _sounds[channel].stream->beginFadeOut(); - } } } // end of namespace Kyra + diff --git a/engines/kyra/sound_towns.cpp b/engines/kyra/sound_towns.cpp index bfc4655277..539017b20b 100644 --- a/engines/kyra/sound_towns.cpp +++ b/engines/kyra/sound_towns.cpp @@ -318,7 +318,7 @@ void MidiChannel_EuD_WAVE::controlChange(byte control, byte value) { // pan position break; case 0x79: - // Reset controller + // Reset controller for (uint8 i = 0; i < 8; i++) { if (_voice->_snd[i]) delete _voice->_snd[i]; @@ -1300,3 +1300,4 @@ const uint8 SoundTowns::_sfxBTTable[256] = { }; } // end of namespace Kyra + diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp index a8825751ac..18620471db 100644 --- a/engines/kyra/sprites.cpp +++ b/engines/kyra/sprites.cpp @@ -463,9 +463,8 @@ void Sprites::loadDat(const char *filename, SceneExits &exits) { case 0xFF84: data += 2; _spriteDefStart = data; - while (READ_LE_UINT16(data) != 0xFF85) { + while (READ_LE_UINT16(data) != 0xFF85) data += 2; - } data += 2; break; case 0xFF86: @@ -575,16 +574,17 @@ int Sprites::getDrawLayer(int y) { for (int i = 0; i < ARRAYSIZE(_drawLayerTable); ++i) { uint8 temp = _drawLayerTable[i]; if (temp) { - if (temp <= y) { + if (temp <= y) returnValue = i; - } } } - if (returnValue <= 0) { + + if (returnValue <= 0) returnValue = 1; - } else if (returnValue >= 7) { + else if (returnValue >= 7) returnValue = 6; - } + return returnValue; } } // end of namespace Kyra + diff --git a/engines/kyra/sprites.h b/engines/kyra/sprites.h index 965e2888dc..8f6db3fd64 100644 --- a/engines/kyra/sprites.h +++ b/engines/kyra/sprites.h @@ -93,3 +93,4 @@ protected: } // End of namespace Kyra #endif + diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 14dc5041d7..1be5895e75 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -24,8 +24,8 @@ #include "common/endian.h" #include "common/md5.h" #include "kyra/kyra.h" -#include "kyra/kyra2.h" -#include "kyra/kyra3.h" +#include "kyra/kyra_v2.h" +#include "kyra/kyra_v3.h" #include "kyra/screen.h" #include "kyra/resource.h" @@ -237,22 +237,18 @@ bool StaticResource::init() { delete [] temp; temp = 0; - if (version != RESFILE_VERSION) { + if (version != RESFILE_VERSION) error("invalid KYRA.DAT file version (%d, required %d)", version, RESFILE_VERSION); - } - if (gameID != _vm->game()) { + if (gameID != _vm->game()) error("invalid game id (%d)", gameID); - } uint32 gameFeatures = createFeatures(_vm->gameFlags()); - if ((featuresValue & GAME_FLAGS) != gameFeatures) { + if ((featuresValue & GAME_FLAGS) != gameFeatures) error("your data file has a different game flags (0x%.08X has the data and your version has 0x%.08X)", (featuresValue & GAME_FLAGS), gameFeatures); - } // load all tables for now - if (!prefetchId(-1)) { + if (!prefetchId(-1)) error("couldn't load all needed resources from 'KYRA.DAT'"); - } return true; } @@ -285,21 +281,18 @@ const uint8 * const*StaticResource::loadPaletteTable(int id, int &entries) { bool StaticResource::prefetchId(int id) { if (id == -1) { - for (int i = 0; _filenameTable[i].filename; ++i) { + for (int i = 0; _filenameTable[i].filename; ++i) prefetchId(_filenameTable[i].id); - } return true; } const void *ptr = 0; int type = -1, size = -1; - if (checkResList(id, type, ptr, size)) { + if (checkResList(id, type, ptr, size)) return true; - } - if (checkForBuiltin(id, type, size)) { + if (checkForBuiltin(id, type, size)) return true; - } const FilenameTable *filename = searchFile(id); if (!filename) @@ -311,9 +304,8 @@ bool StaticResource::prefetchId(int id) { ResData data; data.id = id; data.type = filetype->type; - if (!(this->*(filetype->load))(filename->filename, data.data, data.size)) { + if (!(this->*(filetype->load))(filename->filename, data.data, data.size)) return false; - } _resList.push_back(data); return true; @@ -376,9 +368,8 @@ const StaticResource::FileType *StaticResource::getFiletype(int type) { return 0; for (int i = 0; _fileLoader[i].load; ++i) { - if (_fileLoader[i].type == type) { + if (_fileLoader[i].type == type) return &_fileLoader[i]; - } } return 0; @@ -416,9 +407,8 @@ const void *StaticResource::getData(int id, int requesttype, int &size) { bool StaticResource::loadLanguageTable(const char *filename, void *&ptr, int &size) { char file[64]; for (int i = 0; languages[i].ext; ++i) { - if (languages[i].flags != createLanguage(_vm->gameFlags())) { + if (languages[i].flags != createLanguage(_vm->gameFlags())) continue; - } strcpy(file, filename); strcat(file, languages[i].ext); @@ -576,9 +566,8 @@ void StaticResource::freeRawData(void *&ptr, int &size) { void StaticResource::freeStringTable(void *&ptr, int &size) { char **data = (char**)ptr; - while (size--) { + while (size--) delete [] data[size]; - } ptr = 0; size = 0; } @@ -599,9 +588,8 @@ void StaticResource::freeRoomTable(void *&ptr, int &size) { void StaticResource::freePaletteTable(void *&ptr, int &size) { uint8 **data = (uint8**)ptr; - while (size--) { + while (size--) delete [] data[size]; - } ptr = 0; size = 0; } @@ -609,15 +597,14 @@ void StaticResource::freePaletteTable(void *&ptr, int &size) { uint8 *StaticResource::getFile(const char *name, int &size) { char buffer[64]; const char *ext = ""; - if (_vm->gameFlags().isTalkie) { + if (_vm->gameFlags().isTalkie) ext = ".CD"; - } else if (_vm->gameFlags().isDemo) { + else if (_vm->gameFlags().isDemo) ext = ".DEM"; - } else if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { + else if (_vm->gameFlags().platform == Common::kPlatformFMTowns) ext = ".TNS"; - } else if (_vm->gameFlags().platform == Common::kPlatformAmiga) { + else if (_vm->gameFlags().platform == Common::kPlatformAmiga) ext = ".AMG"; - } snprintf(buffer, 64, "%s%s", name, ext); uint32 tempSize = 0; uint8 *data = _vm->resource()->fileData(buffer, &tempSize); @@ -721,16 +708,16 @@ void KyraEngine::initStaticResource() { void KyraEngine::loadMouseShapes() { _screen->loadBitmap("MOUSE.CPS", 3, 3, 0); _screen->_curPage = 2; - _shapes[4] = _screen->encodeShape(0, 0, 8, 10, 0); - _shapes[5] = _screen->encodeShape(0, 0x17, 0x20, 7, 0); - _shapes[6] = _screen->encodeShape(0x50, 0x12, 0x10, 9, 0); - _shapes[7] = _screen->encodeShape(0x60, 0x12, 0x10, 11, 0); - _shapes[8] = _screen->encodeShape(0x70, 0x12, 0x10, 9, 0); - _shapes[9] = _screen->encodeShape(0x80, 0x12, 0x10, 11, 0); - _shapes[10] = _screen->encodeShape(0x90, 0x12, 0x10, 10, 0); - _shapes[364] = _screen->encodeShape(0x28, 0, 0x10, 13, 0); + _shapes[0] = _screen->encodeShape(0, 0, 8, 10, 0); + _shapes[1] = _screen->encodeShape(0, 0x17, 0x20, 7, 0); + _shapes[2] = _screen->encodeShape(0x50, 0x12, 0x10, 9, 0); + _shapes[3] = _screen->encodeShape(0x60, 0x12, 0x10, 11, 0); + _shapes[4] = _screen->encodeShape(0x70, 0x12, 0x10, 9, 0); + _shapes[5] = _screen->encodeShape(0x80, 0x12, 0x10, 11, 0); + _shapes[6] = _screen->encodeShape(0x90, 0x12, 0x10, 10, 0); + _shapes[360] = _screen->encodeShape(0x28, 0, 0x10, 13, 0); _screen->setMouseCursor(1, 1, 0); - _screen->setMouseCursor(1, 1, _shapes[4]); + _screen->setMouseCursor(1, 1, _shapes[0]); _screen->setShapePages(5, 3); } @@ -742,7 +729,7 @@ void KyraEngine::loadCharacterShapes() { assert(i < _defaultShapeTableSize); Shape *shape = &_defaultShapeTable[i]; if (shape->imageIndex == 0xFF) { - _shapes[i+7+4] = 0; + _shapes[i+7] = 0; continue; } if (shape->imageIndex != curImage) { @@ -750,7 +737,7 @@ void KyraEngine::loadCharacterShapes() { _screen->loadBitmap(_characterImageTable[shape->imageIndex], 3, 3, 0); curImage = shape->imageIndex; } - _shapes[i+7+4] = _screen->encodeShape(shape->x<<3, shape->y, shape->w<<3, shape->h, 1); + _shapes[i+7] = _screen->encodeShape(shape->x<<3, shape->y, shape->w<<3, shape->h, 1); } _screen->_curPage = videoPage; } @@ -761,16 +748,16 @@ void KyraEngine::loadSpecialEffectShapes() { int currShape; for (currShape = 173; currShape < 183; currShape++) - _shapes[4 + currShape] = _screen->encodeShape((currShape-173) * 24, 0, 24, 24, 1); + _shapes[currShape] = _screen->encodeShape((currShape-173) * 24, 0, 24, 24, 1); for (currShape = 183; currShape < 190; currShape++) - _shapes[4 + currShape] = _screen->encodeShape((currShape-183) * 24, 24, 24, 24, 1); + _shapes[currShape] = _screen->encodeShape((currShape-183) * 24, 24, 24, 24, 1); for (currShape = 190; currShape < 201; currShape++) - _shapes[4 + currShape] = _screen->encodeShape((currShape-190) * 24, 48, 24, 24, 1); + _shapes[currShape] = _screen->encodeShape((currShape-190) * 24, 48, 24, 24, 1); for (currShape = 201; currShape < 206; currShape++) - _shapes[4 + currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1); + _shapes[currShape] = _screen->encodeShape((currShape-201) * 16, 106, 16, 16, 1); } void KyraEngine::loadItems() { @@ -779,28 +766,28 @@ void KyraEngine::loadItems() { _screen->loadBitmap("JEWELS3.CPS", 3, 3, 0); _screen->_curPage = 2; - _shapes[327] = 0; + _shapes[323] = 0; for (shape = 1; shape < 6; shape++ ) - _shapes[327 + shape] = _screen->encodeShape((shape - 1) * 32, 0, 32, 17, 0); + _shapes[323 + shape] = _screen->encodeShape((shape - 1) * 32, 0, 32, 17, 0); for (shape = 330; shape <= 334; shape++) - _shapes[4 + shape] = _screen->encodeShape((shape-330) * 32, 102, 32, 17, 0); + _shapes[shape] = _screen->encodeShape((shape-330) * 32, 102, 32, 17, 0); for (shape = 335; shape <= 339; shape++) - _shapes[4 + shape] = _screen->encodeShape((shape-335) * 32, 17, 32, 17, 0); + _shapes[shape] = _screen->encodeShape((shape-335) * 32, 17, 32, 17, 0); for (shape = 340; shape <= 344; shape++) - _shapes[4 + shape] = _screen->encodeShape((shape-340) * 32, 34, 32, 17, 0); + _shapes[shape] = _screen->encodeShape((shape-340) * 32, 34, 32, 17, 0); for (shape = 345; shape <= 349; shape++) - _shapes[4 + shape] = _screen->encodeShape((shape-345) * 32, 51, 32, 17, 0); + _shapes[shape] = _screen->encodeShape((shape-345) * 32, 51, 32, 17, 0); for (shape = 350; shape <= 354; shape++) - _shapes[4 + shape] = _screen->encodeShape((shape-350) * 32, 68, 32, 17, 0); + _shapes[shape] = _screen->encodeShape((shape-350) * 32, 68, 32, 17, 0); for (shape = 355; shape <= 359; shape++) - _shapes[4 + shape] = _screen->encodeShape((shape-355) * 32, 85, 32, 17, 0); + _shapes[shape] = _screen->encodeShape((shape-355) * 32, 85, 32, 17, 0); _screen->loadBitmap("ITEMS.CPS", 3, 3, 0); @@ -810,9 +797,9 @@ void KyraEngine::loadItems() { shape = findDuplicateItemShape(i); if (shape != -1) - _shapes[220 + i] = _shapes[220 + shape]; + _shapes[216 + i] = _shapes[216 + shape]; else - _shapes[220 + i] = _screen->encodeShape( (i % 20) * 16, i/20 * 16, 16, 16, 0); + _shapes[216 + i] = _screen->encodeShape( (i % 20) * 16, i/20 * 16, 16, 16, 0); } uint32 size; @@ -888,212 +875,6 @@ const ScreenDim Screen::_screenDimTableK3[] = { const int Screen::_screenDimTableCountK3 = ARRAYSIZE(_screenDimTableK3); -#define Opcode(x) &KyraEngine::x -void KyraEngine::setupOpcodeTable() { - static const OpcodeProc opcodeTable[] = { - // 0x00 - Opcode(o1_magicInMouseItem), - Opcode(o1_characterSays), - Opcode(o1_pauseTicks), - Opcode(o1_drawSceneAnimShape), - // 0x04 - Opcode(o1_queryGameFlag), - Opcode(o1_setGameFlag), - Opcode(o1_resetGameFlag), - Opcode(o1_runNPCScript), - // 0x08 - Opcode(o1_setSpecialExitList), - Opcode(o1_blockInWalkableRegion), - Opcode(o1_blockOutWalkableRegion), - Opcode(o1_walkPlayerToPoint), - // 0x0c - Opcode(o1_dropItemInScene), - Opcode(o1_drawAnimShapeIntoScene), - Opcode(o1_createMouseItem), - Opcode(o1_savePageToDisk), - // 0x10 - Opcode(o1_sceneAnimOn), - Opcode(o1_sceneAnimOff), - Opcode(o1_getElapsedSeconds), - Opcode(o1_mouseIsPointer), - // 0x14 - Opcode(o1_destroyMouseItem), - Opcode(o1_runSceneAnimUntilDone), - Opcode(o1_fadeSpecialPalette), - Opcode(o1_playAdlibSound), - // 0x18 - Opcode(o1_playAdlibScore), - Opcode(o1_phaseInSameScene), - Opcode(o1_setScenePhasingFlag), - Opcode(o1_resetScenePhasingFlag), - // 0x1c - Opcode(o1_queryScenePhasingFlag), - Opcode(o1_sceneToDirection), - Opcode(o1_setBirthstoneGem), - Opcode(o1_placeItemInGenericMapScene), - // 0x20 - Opcode(o1_setBrandonStatusBit), - Opcode(o1_pauseSeconds), - Opcode(o1_getCharactersLocation), - Opcode(o1_runNPCSubscript), - // 0x24 - Opcode(o1_magicOutMouseItem), - Opcode(o1_internalAnimOn), - Opcode(o1_forceBrandonToNormal), - Opcode(o1_poisonDeathNow), - // 0x28 - Opcode(o1_setScaleMode), - Opcode(o1_openWSAFile), - Opcode(o1_closeWSAFile), - Opcode(o1_runWSAFromBeginningToEnd), - // 0x2c - Opcode(o1_displayWSAFrame), - Opcode(o1_enterNewScene), - Opcode(o1_setSpecialEnterXAndY), - Opcode(o1_runWSAFrames), - // 0x30 - Opcode(o1_popBrandonIntoScene), - Opcode(o1_restoreAllObjectBackgrounds), - Opcode(o1_setCustomPaletteRange), - Opcode(o1_loadPageFromDisk), - // 0x34 - Opcode(o1_customPrintTalkString), - Opcode(o1_restoreCustomPrintBackground), - Opcode(o1_hideMouse), - Opcode(o1_showMouse), - // 0x38 - Opcode(o1_getCharacterX), - Opcode(o1_getCharacterY), - Opcode(o1_changeCharactersFacing), - Opcode(o1_copyWSARegion), - // 0x3c - Opcode(o1_printText), - Opcode(o1_random), - Opcode(o1_loadSoundFile), - Opcode(o1_displayWSAFrameOnHidPage), - // 0x40 - Opcode(o1_displayWSASequentialFrames), - Opcode(o1_drawCharacterStanding), - Opcode(o1_internalAnimOff), - Opcode(o1_changeCharactersXAndY), - // 0x44 - Opcode(o1_clearSceneAnimatorBeacon), - Opcode(o1_querySceneAnimatorBeacon), - Opcode(o1_refreshSceneAnimator), - Opcode(o1_placeItemInOffScene), - // 0x48 - Opcode(o1_wipeDownMouseItem), - Opcode(o1_placeCharacterInOtherScene), - Opcode(o1_getKey), - Opcode(o1_specificItemInInventory), - // 0x4c - Opcode(o1_popMobileNPCIntoScene), - Opcode(o1_mobileCharacterInScene), - Opcode(o1_hideMobileCharacter), - Opcode(o1_unhideMobileCharacter), - // 0x50 - Opcode(o1_setCharactersLocation), - Opcode(o1_walkCharacterToPoint), - Opcode(o1_specialEventDisplayBrynnsNote), - Opcode(o1_specialEventRemoveBrynnsNote), - // 0x54 - Opcode(o1_setLogicPage), - Opcode(o1_fatPrint), - Opcode(o1_preserveAllObjectBackgrounds), - Opcode(o1_updateSceneAnimations), - // 0x58 - Opcode(o1_sceneAnimationActive), - Opcode(o1_setCharactersMovementDelay), - Opcode(o1_getCharactersFacing), - Opcode(o1_bkgdScrollSceneAndMasksRight), - // 0x5c - Opcode(o1_dispelMagicAnimation), - Opcode(o1_findBrightestFireberry), - Opcode(o1_setFireberryGlowPalette), - Opcode(o1_setDeathHandlerFlag), - // 0x60 - Opcode(o1_drinkPotionAnimation), - Opcode(o1_makeAmuletAppear), - Opcode(o1_drawItemShapeIntoScene), - Opcode(o1_setCharactersCurrentFrame), - // 0x64 - Opcode(o1_waitForConfirmationMouseClick), - Opcode(o1_pageFlip), - Opcode(o1_setSceneFile), - Opcode(o1_getItemInMarbleVase), - // 0x68 - Opcode(o1_setItemInMarbleVase), - Opcode(o1_addItemToInventory), - Opcode(o1_intPrint), - Opcode(o1_shakeScreen), - // 0x6c - Opcode(o1_createAmuletJewel), - Opcode(o1_setSceneAnimCurrXY), - Opcode(o1_poisonBrandonAndRemaps), - Opcode(o1_fillFlaskWithWater), - // 0x70 - Opcode(o1_getCharactersMovementDelay), - Opcode(o1_getBirthstoneGem), - Opcode(o1_queryBrandonStatusBit), - Opcode(o1_playFluteAnimation), - // 0x74 - Opcode(o1_playWinterScrollSequence), - Opcode(o1_getIdolGem), - Opcode(o1_setIdolGem), - Opcode(o1_totalItemsInScene), - // 0x78 - Opcode(o1_restoreBrandonsMovementDelay), - Opcode(o1_setMousePos), - Opcode(o1_getMouseState), - Opcode(o1_setEntranceMouseCursorTrack), - // 0x7c - Opcode(o1_itemAppearsOnGround), - Opcode(o1_setNoDrawShapesFlag), - Opcode(o1_fadeEntirePalette), - Opcode(o1_itemOnGroundHere), - // 0x80 - Opcode(o1_queryCauldronState), - Opcode(o1_setCauldronState), - Opcode(o1_queryCrystalState), - Opcode(o1_setCrystalState), - // 0x84 - Opcode(o1_setPaletteRange), - Opcode(o1_shrinkBrandonDown), - Opcode(o1_growBrandonUp), - Opcode(o1_setBrandonScaleXAndY), - // 0x88 - Opcode(o1_resetScaleMode), - Opcode(o1_getScaleDepthTableValue), - Opcode(o1_setScaleDepthTableValue), - Opcode(o1_message), - // 0x8c - Opcode(o1_checkClickOnNPC), - Opcode(o1_getFoyerItem), - Opcode(o1_setFoyerItem), - Opcode(o1_setNoItemDropRegion), - // 0x90 - Opcode(o1_walkMalcolmOn), - Opcode(o1_passiveProtection), - Opcode(o1_setPlayingLoop), - Opcode(o1_brandonToStoneSequence), - // 0x94 - Opcode(o1_brandonHealingSequence), - Opcode(o1_protectCommandLine), - Opcode(o1_pauseMusicSeconds), - Opcode(o1_resetMaskRegion), - // 0x98 - Opcode(o1_setPaletteChangeFlag), - Opcode(o1_fillRect), - Opcode(o1_vocUnload), - Opcode(o1_vocLoad), - Opcode(o1_dummy) - }; - - _opcodeTable = opcodeTable; - _opcodeTableSize = ARRAYSIZE(opcodeTable); -} -#undef Opcode - const char *KyraEngine::_soundFiles[] = { "INTRO", "KYRA1A", @@ -1471,3 +1252,4 @@ const char *KyraEngine_v3::_languageExtension[] = { const int KyraEngine_v3::_languageExtensionSize = ARRAYSIZE(KyraEngine_v3::_languageExtension); } // End of namespace Kyra + diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp index 10353f97ca..70d20cd102 100644 --- a/engines/kyra/timer.cpp +++ b/engines/kyra/timer.cpp @@ -259,16 +259,16 @@ void KyraEngine::drawAmulet() { int i = 0; while (amuletTable1[i] != -1) { if (queryGameFlag(87)) - _screen->drawShape(0, _shapes[4+amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0); + _screen->drawShape(0, _shapes[amuletTable1[i]], _amuletX[0], _amuletY[0], 0, 0); if (queryGameFlag(89)) - _screen->drawShape(0, _shapes[4+amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0); + _screen->drawShape(0, _shapes[amuletTable2[i]], _amuletX[1], _amuletY[1], 0, 0); if (queryGameFlag(86)) - _screen->drawShape(0, _shapes[4+amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0); + _screen->drawShape(0, _shapes[amuletTable3[i]], _amuletX[2], _amuletY[2], 0, 0); if (queryGameFlag(88)) - _screen->drawShape(0, _shapes[4+amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0); + _screen->drawShape(0, _shapes[amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0); _screen->updateScreen(); delayWithTicks(3); diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index e0a6817d82..b2b43b86aa 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -25,7 +25,6 @@ #include "common/system.h" #include "kyra/kyra.h" -#include "kyra/kyra3.h" #include "kyra/screen.h" #include "kyra/wsamovie.h" @@ -52,16 +51,16 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { _offscreenBuffer = NULL; _flags = 0; if (_vm->gameFlags().useAltShapeHeader) { - flags = READ_LE_UINT16(wsaData); wsaData += 2; + flags = READ_LE_UINT16(wsaData); + wsaData += 2; } uint32 offsPal = 0; if (flags & 1) { offsPal = 0x300; _flags |= WF_HAS_PALETTE; - if (palBuf) { + if (palBuf) memcpy(palBuf, wsaData + (_numFrames + 2) * 4, 0x300); - } } if (offscreenDecode) { @@ -89,11 +88,13 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { _frameOffsTable[0] = 0; uint32 frameDataOffs = READ_LE_UINT32(wsaData); wsaData += 4; bool firstFrame = true; + if (frameDataOffs == 0) { firstFrame = false; frameDataOffs = READ_LE_UINT32(wsaData); _flags |= WF_NO_FIRST_FRAME; } + for (int i = 1; i < _numFrames + 2; ++i) { _frameOffsTable[i] = READ_LE_UINT32(wsaData) - frameDataOffs; wsaData += 4; @@ -108,9 +109,8 @@ int WSAMovieV1::open(const char *filename, int offscreenDecode, uint8 *palBuf) { memcpy(_frameData, wsaData, frameDataSize); // decode first frame - if (firstFrame) { + if (firstFrame) Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize); - } delete [] p; _opened = true; @@ -135,19 +135,17 @@ void WSAMovieV1::displayFrame(int frameNum) { return; uint8 *dst; - if (_flags & WF_OFFSCREEN_DECODE) { + if (_flags & WF_OFFSCREEN_DECODE) dst = _offscreenBuffer; - } else { + else dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height); - } if (_currentFrame == _numFrames) { if (!(_flags & WF_NO_FIRST_FRAME)) { - if (_flags & WF_OFFSCREEN_DECODE) { + if (_flags & WF_OFFSCREEN_DECODE) Screen::decodeFrameDelta(dst, _deltaBuffer); - } else { + else Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width, (_flags & WF_XOR) == 0); - } } _currentFrame = 0; } @@ -158,11 +156,10 @@ void WSAMovieV1::displayFrame(int frameNum) { int frameCount; if (_currentFrame < frameNum) { frameCount = _numFrames - frameNum + _currentFrame; - if (diffCount > frameCount) { + if (diffCount > frameCount) frameStep = -1; - } else { + else frameCount = diffCount; - } } else { frameCount = _numFrames - _currentFrame + frameNum; if (frameCount >= diffCount) { @@ -177,16 +174,14 @@ void WSAMovieV1::displayFrame(int frameNum) { while (frameCount--) { cf += frameStep; processFrame(cf, dst); - if (cf == _numFrames) { + if (cf == _numFrames) cf = 0; - } } } else { uint16 cf = _currentFrame; while (frameCount--) { - if (cf == 0) { + if (cf == 0) cf = _numFrames; - } processFrame(cf, dst); cf += frameStep; } @@ -194,9 +189,8 @@ void WSAMovieV1::displayFrame(int frameNum) { // display _currentFrame = frameNum; - if (_flags & WF_OFFSCREEN_DECODE) { + if (_flags & WF_OFFSCREEN_DECODE) _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); - } } void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { @@ -206,11 +200,10 @@ void WSAMovieV1::processFrame(int frameNum, uint8 *dst) { assert(frameNum <= _numFrames); const uint8 *src = _frameData + _frameOffsTable[frameNum]; Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize); - if (_flags & WF_OFFSCREEN_DECODE) { + if (_flags & WF_OFFSCREEN_DECODE) Screen::decodeFrameDelta(dst, _deltaBuffer); - } else { + else Screen::decodeFrameDeltaPage(dst, _deltaBuffer, _width, false); - } } #pragma mark - @@ -257,9 +250,8 @@ void WSAMovieAmiga::displayFrame(int frameNum) { const uint8 *src = _buffer; int size = _width * _height; - for (int i = 0; i < size; ++i) { + for (int i = 0; i < size; ++i) *dst++ ^= *src++; - } dst = _buffer; } else { @@ -275,11 +267,10 @@ void WSAMovieAmiga::displayFrame(int frameNum) { int frameCount; if (_currentFrame < frameNum) { frameCount = _numFrames - frameNum + _currentFrame; - if (diffCount > frameCount) { + if (diffCount > frameCount) frameStep = -1; - } else { + else frameCount = diffCount; - } } else { frameCount = _numFrames - _currentFrame + frameNum; if (frameCount >= diffCount) { @@ -294,16 +285,14 @@ void WSAMovieAmiga::displayFrame(int frameNum) { while (frameCount--) { cf += frameStep; processFrame(cf, dst); - if (cf == _numFrames) { + if (cf == _numFrames) cf = 0; - } } } else { uint16 cf = _currentFrame; while (frameCount--) { - if (cf == 0) { + if (cf == 0) cf = _numFrames; - } processFrame(cf, dst); cf += frameStep; } @@ -311,9 +300,8 @@ void WSAMovieAmiga::displayFrame(int frameNum) { // display _currentFrame = frameNum; - if (_flags & WF_OFFSCREEN_DECODE) { + if (_flags & WF_OFFSCREEN_DECODE) _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); - } } void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { @@ -341,9 +329,8 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { } for (int y = 0; y < _height; ++y) { - for (int x = 0; x < _width; ++x) { + for (int x = 0; x < _width; ++x) *dst++ ^= *src++; - } dst += dstPitch - _width; } } @@ -379,9 +366,8 @@ int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { if (flags & 1) { offsPal = 0x300; _flags |= WF_HAS_PALETTE; - if (palBuf) { + if (palBuf) memcpy(palBuf, wsaData + 8 + ((_numFrames << 2) & 0xFFFF), 0x300); - } } if (flags & 2) @@ -431,3 +417,4 @@ int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { } } // end of namespace Kyra + diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index e9b84a0bbb..3e35fcb47d 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -128,3 +128,4 @@ protected: } // end of namespace Kyra #endif + diff --git a/engines/lure/debugger.cpp b/engines/lure/debugger.cpp index c098ca6919..f9d94d4c1d 100644 --- a/engines/lure/debugger.cpp +++ b/engines/lure/debugger.cpp @@ -105,13 +105,12 @@ bool Debugger::cmd_enterRoom(int argc, const char **argv) { bool Debugger::cmd_listRooms(int argc, const char **argv) { RoomDataList &rooms = Resources::getReference().roomData(); - RoomDataList::iterator i; StringData &strings = StringData::getReference(); char buffer[MAX_DESC_SIZE]; int ctr = 0; DebugPrintf("Available rooms are:\n"); - for (i = rooms.begin(); i != rooms.end(); ++i) { + for (RoomDataList::iterator i = rooms.begin(); i != rooms.end(); ++i) { RoomData *room = *i; strings.getString(room->roomNumber, buffer); // DEBUG: Explictly note the second drawbridge room as "Alt" for now @@ -131,6 +130,18 @@ bool Debugger::cmd_listRooms(int argc, const char **argv) { } DebugPrintf("\n"); DebugPrintf("Current room: %d\n", Room::getReference().roomNumber()); + + Resources &res = Resources::getReference(); + HotspotDataList &list = res.hotspotData(); + for (HotspotDataList::iterator i = list.begin(); i != list.end(); ++i) + { + HotspotData *data = *i; + strings.getString(data->nameId, buffer); + + DebugPrintf("%xh - %s\n", data->hotspotId, buffer); + } + DebugPrintf("\n"); + return true; } @@ -298,8 +309,8 @@ bool Debugger::cmd_hotspot(int argc, const char **argv) { DebugPrintf("Talk bubble offset = %d,%d\n", hs->talkX, hs->talkY); DebugPrintf("load offset = %xh, script load = %d\n", hs->loadOffset, hs->scriptLoadFlag); DebugPrintf("Animation Id = %xh, Colour offset = %d\n", hs->animRecordId, hs->colourOffset); - DebugPrintf("Script offset = %xh, Tick Script offset = %xh\n", - hs->sequenceOffset, hs->tickSequenceOffset); + DebugPrintf("Talk Script offset = %xh, Tick Script offset = %xh\n", + hs->talkScriptOffset, hs->tickScriptOffset); DebugPrintf("Tick Proc offset = %xh\n", hs->tickProcOffset); DebugPrintf("Tick timeout = %d\n", hs->tickTimeout); DebugPrintf("NPC Shcedule = %xh\n", hs->npcSchedule); diff --git a/engines/lure/detection.cpp b/engines/lure/detection.cpp new file mode 100644 index 0000000000..211874690d --- /dev/null +++ b/engines/lure/detection.cpp @@ -0,0 +1,226 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" + +#include "base/plugins.h" + +#include "common/endian.h" +#include "common/file.h" +#include "common/fs.h" +#include "common/md5.h" + +#include "lure/luredefs.h" +#include "lure/lure.h" + +namespace Lure { + +enum { + // We only compute MD5 of the first kilobyte of our data files. + kMD5FileSizeLimit = 1024 +}; + +struct GameSettings { + const char *gameid; + const char *description; + byte id; + uint32 features; + Common::Language language; + const char *md5sum; + const char *checkFile; +}; + +// +static const GameSettings lure_games[] = { + { "lure", "Lure of the Temptress", GI_LURE, GF_FLOPPY, Common::EN_ANY, + "b2a8aa6d7865813a17a3c636e063572e", "disk1.vga" }, +/* + { "lure", "Lure of the Temptress", GI_LURE, GF_FLOPPY, Common::DE_DEU, + "7aa19e444dab1ac7194d9f7a40ffe54a", "disk1.vga" }, + { "lure", "Lure of the Temptress", GI_LURE, GF_FLOPPY, Common::FR_FRA, + "1c94475c1bb7e0e88c1757d3b5377e94", "disk1.vga" }, +*/ + { 0, 0, 0, 0, Common::UNK_LANG, 0, 0 } +}; + +// Keep list of different supported games + +static const PlainGameDescriptor lure_list[] = { + { "lure", "Lure of the Temptress" }, + { 0, 0 } +}; + +} // End of namespace Lure + +using namespace Lure; + +GameList Engine_LURE_gameIDList() { + GameList games; + const PlainGameDescriptor *g = lure_list; + + while (g->gameid) { + games.push_back(*g); + g++; + } + return games; +} + +GameDescriptor Engine_LURE_findGameID(const char *gameid) { + const PlainGameDescriptor *g = lure_list; + while (g->gameid) { + if (0 == scumm_stricmp(gameid, g->gameid)) + break; + g++; + } + return GameDescriptor(g->gameid, g->description); +} + +GameList Engine_LURE_detectGames(const FSList &fslist) { + GameList detectedGames; + const GameSettings *g; + FSList::const_iterator file; + + // Iterate over all files in the given directory + bool isFound = false; + for (file = fslist.begin(); file != fslist.end(); file++) { + if (file->isDirectory()) + continue; + + for (g = lure_games; g->gameid; g++) { + if (scumm_stricmp(file->name().c_str(), g->checkFile) == 0) + isFound = true; + } + if (isFound) + break; + } + + if (file == fslist.end()) + return detectedGames; + + char md5str[32 + 1]; + + if (Common::md5_file_string(*file, md5str, kMD5FileSizeLimit)) { + for (g = lure_games; g->gameid; g++) { + if (strcmp(g->md5sum, (char *)md5str) == 0) { + GameDescriptor dg(g->gameid, g->description, g->language); + dg.updateDesc((g->features & GF_FLOPPY) ? "Floppy" : 0); + detectedGames.push_back(dg); + } + } + if (detectedGames.empty()) { + printf("Your game version appears to be unknown. Please, report the following\n"); + printf("data to the ScummVM team along with name of the game you tried to add\n"); + printf("and its version/language/etc.:\n"); + + printf(" LURE MD5 '%s'\n\n", md5str); + + const PlainGameDescriptor *g1 = lure_list; + while (g1->gameid) { + detectedGames.push_back(*g1); + g1++; + } + } + } + return detectedGames; +} + +PluginError Engine_LURE_create(OSystem *syst, Engine **engine) { + assert(engine); + *engine = new LureEngine(syst); + return kNoError; +} + +REGISTER_PLUGIN(LURE, "Lure of the Temptress Engine", "Lure of the Temptress (C) Revolution"); + +namespace Lure { + +void LureEngine::detectGame() { + // Make sure all the needed files are present + + if (!Common::File::exists(SUPPORT_FILENAME)) + error("Missing %s - this is a custom file containing resources from the\n" + "Lure of the Temptress executable. See the documentation for creating it.", + SUPPORT_FILENAME); + + for (uint8 fileNum = 1; fileNum <= 4; ++fileNum) + { + char sFilename[10]; + sprintf(sFilename, "disk%d.vga", fileNum); + + if (!Common::File::exists(sFilename)) + error("Missing disk%d.vga", fileNum); + } + + // Check the version of the lure.dat file + Common::File f; + if (!f.open(SUPPORT_FILENAME)) { + error("Error opening %s for validation", SUPPORT_FILENAME); + } else { + f.seek(0xbf * 8); + VersionStructure version; + f.read(&version, sizeof(VersionStructure)); + f.close(); + + if (READ_LE_UINT16(&version.id) != 0xffff) + error("Error validating %s - file is invalid or out of date", SUPPORT_FILENAME); + else if ((version.vMajor != LURE_DAT_MAJOR) || (version.vMinor != LURE_DAT_MINOR)) + error("Incorrect version of %s file - expected %d.%d but got %d.%d", + SUPPORT_FILENAME, LURE_DAT_MAJOR, LURE_DAT_MINOR, + version.vMajor, version.vMinor); + } + + // Do an md5 check + + char md5str[32 + 1]; + const GameSettings *g; + bool found = false; + + *md5str = 0; + + for (g = lure_games; g->gameid; g++) { + if (!Common::File::exists(g->checkFile)) + continue; + + if (!Common::md5_file_string(g->checkFile, md5str, kMD5FileSizeLimit)) + continue; + + if (strcmp(g->md5sum, (char *)md5str) == 0) { + _features = g->features; + _game = g->id; + _language = g->language; + + if (g->description) + g_system->setWindowCaption(g->description); + + found = true; + break; + } + } + + if (!found) { + debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team", md5str); + _features = GF_LNGUNK || GF_FLOPPY; + _game = GI_LURE; + } +} + +} // End of namespace Lure diff --git a/engines/lure/game.cpp b/engines/lure/game.cpp index 6a2ebedcf2..62425ae926 100644 --- a/engines/lure/game.cpp +++ b/engines/lure/game.cpp @@ -282,6 +282,17 @@ void Game::playerChangeRoom() { player->setPosition(newPos.x, newPos.y); player->setOccupied(true); room.setRoomNumber(roomNum, false); + + // Special check for change back from Selena + if ((roomNum != 31) && (roomNum != 14) && (fields.getField(74) != 0)) { + uint16 v = fields.getField(29); + if (v != 0) { + --v; + fields.setField(29, v); + if (v == 0) + res.delayList().add(2, 0xCB7, true); + } + } } void Game::displayChuteAnimation() diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp index 2944091f4f..f3b1c01d3d 100644 --- a/engines/lure/hotspots.cpp +++ b/engines/lure/hotspots.cpp @@ -62,9 +62,8 @@ Hotspot::Hotspot(HotspotData *res): _pathFinder(this) { _talkX = res->talkX; _talkY = res->talkY; _layer = res->layer; - _sequenceOffset = res->sequenceOffset; + _hotspotScriptOffset = res->hotspotScriptOffset; _tickCtr = res->tickTimeout; - _actions = res->actions; _colourOffset = res->colourOffset; _override = resources.getHotspotOverride(res->hotspotId); @@ -405,7 +404,7 @@ void Hotspot::setSize(uint16 newWidth, uint16 newHeight) { } bool Hotspot::executeScript() { - if (_data->sequenceOffset == 0xffff) + if (_data->hotspotScriptOffset == 0xffff) return false; else return HotspotScript::execute(this); @@ -478,7 +477,8 @@ void Hotspot::setDirection(Direction dir) { _charRectY = 0; break; default: - break; + // No need to change + return; } setFrameNumber(newFrameNumber); @@ -488,14 +488,26 @@ void Hotspot::setDirection(Direction dir) { // Makes the character face the given hotspot void Hotspot::faceHotspot(HotspotData *hotspot) { + Resources &res = Resources::getReference(); + Room &room = Room::getReference(); + Screen &screen = Screen::getReference(); + if (hotspot->hotspotId >= START_NONVISUAL_HOTSPOT_ID) { // Non visual hotspot setDirection(hotspot->nonVisualDirection()); } else { // Visual hotspot - int xp = x() - hotspot->startX; - int yp = y() + heightCopy() - (hotspot->startY + hotspot->heightCopy); + int xp, yp; + + HotspotOverrideData *hsEntry = res.getHotspotOverride(hotspot->hotspotId); + if (hsEntry != NULL) { + xp = x() - hsEntry->xs; + yp = y() + heightCopy() - (hsEntry->ys + hotspot->heightCopy); + } else { + xp = x() - hotspot->startX; + yp = y() + heightCopy() - (hotspot->startY + hotspot->heightCopy); + } if (ABS(yp) >= ABS(xp)) { if (yp < 0) setDirection(DOWN); @@ -507,8 +519,8 @@ void Hotspot::faceHotspot(HotspotData *hotspot) { } if (hotspotId() == PLAYER_ID) { - Room::getReference().update(); - Screen::getReference().update(); + room.update(); + screen.update(); } } @@ -525,7 +537,6 @@ void Hotspot::setRandomDest() { RoomData *roomData = res.getRoom(roomNumber()); Common::Rect &rect = roomData->walkBounds; Common::RandomSource rnd; - int tryCtr = 0; int16 xp, yp; if (_currentActions.isEmpty()) @@ -534,13 +545,15 @@ void Hotspot::setRandomDest() { _currentActions.top().setAction(START_WALKING); _walkFlag = true; - while (tryCtr ++ <= 20) { + // Try up to 20 times to find an unoccupied destination + for (int tryCtr = 0; tryCtr < 20; ++tryCtr) { xp = rect.left + rnd.getRandomNumber(rect.right - rect.left); - yp = rect.left + rnd.getRandomNumber(rect.right - rect.left); + yp = rect.top + rnd.getRandomNumber(rect.bottom - rect.top); setDestPosition(xp, yp); setDestHotspot(0); - if (!roomData->paths.isOccupied(xp, yp) && !roomData->paths.isOccupied(xp, yp)) + // Check if three sequential blocks at chosen destination are unoccupied + if (!roomData->paths.isOccupied(xp, yp, 3)) break; } } @@ -555,7 +568,7 @@ void Hotspot::setOccupied(bool occupiedFlag) { int xp = x() >> 3; int yp = (y() - 8 + heightCopy() - 4) >> 3; - int widthVal = MAX((widthCopy() >> 3), 1); + int widthVal = MAX(widthCopy() >> 3, 1); // Handle cropping for screen left if (xp < 0) { @@ -660,12 +673,15 @@ void Hotspot::converse(uint16 destCharacterId, uint16 messageId, bool standStill // in case the destination is already in process of talking HotspotData *hotspot = Resources::getReference().getHotspot(destCharacterId); _data->talkCountdown += hotspot->talkCountdown; + + _data->talkDestCharacterId = destCharacterId; + _data->talkGate = 0; } if (standStill) { setDelayCtr(_data->talkCountdown); _data->characterMode = CHARMODE_CONVERSING; - //TODO: HS[3Eh]=use_hotspot_id, HS[40h]=active_hotspot_id + //TODO: HS[3Eh]=character_hotspot_id, HS[40h]=active_hotspot_id } } @@ -766,7 +782,8 @@ void Hotspot::handleTalkDialog() { // Talking is finish - stop talking and free voice animation debugC(ERROR_DETAILED, kLureDebugAnimations, "Talk dialog close"); room.setTalkDialog(0, 0, 0, 0); - res.setTalkingCharacter(0); + _data->talkDestCharacterId = 0; + _data->talkGate = 0; } debugC(ERROR_DETAILED, kLureDebugAnimations, "Talk handler method end"); @@ -817,7 +834,7 @@ HotspotPrecheckResult Hotspot::actionPrecheck(HotspotData *hotspot) { if (actionCtr() >= 6) { warning("actionCtr exceeded"); setActionCtr(0); - converse(0, 0xD); + converse(NOONE_ID, 0xD); return PC_EXCESS; } @@ -831,11 +848,12 @@ HotspotPrecheckResult Hotspot::actionPrecheck(HotspotData *hotspot) { } else { // loc_886 setActionCtr(0); - converse(0, 0xE); + showMessage(14, NOONE_ID); return PC_FAILED; } } else { setActionCtr(1); + if ((hotspot->hotspotId >= FIRST_NONCHARACTER_ID) || ((hotspot->actionHotspotId != _hotspotId) && (hotspot->characterMode == CHARMODE_WAIT_FOR_PLAYER))) { @@ -844,15 +862,14 @@ HotspotPrecheckResult Hotspot::actionPrecheck(HotspotData *hotspot) { return PC_WAIT; } else if (hotspot->actionHotspotId != _hotspotId) { - if (fields.getField(88) == 2) { - // loc_882 - hotspot->v2b = 0x2A; - hotspot->useHotspotId = _hotspotId; - return PC_WAIT; - } else { - converse(NOONE_ID, 5); + if (fields.getField(82) != 2) { + showMessage(5, hotspot->hotspotId); setDelayCtr(4); } + + hotspot->talkGate = 0x2A; + hotspot->talkDestCharacterId = _hotspotId; + return PC_WAIT; } } @@ -1017,15 +1034,16 @@ bool Hotspot::doorCloseCheck(uint16 doorId) { if ((hsCurrent->hotspotId() == 0xfffe) || (hsCurrent->hotspotId() == 0xffff)) continue; - // Check the dimensions of the animation - if ((hsCurrent->x() < bounds.right) && - ((hsCurrent->x() + hsCurrent->widthCopy()) > bounds.left) && - ((hsCurrent->y() + hsCurrent->heightCopy() + hsCurrent->charRectY()) >= bounds.top) && - ((hsCurrent->y() + hsCurrent->heightCopy() - hsCurrent->charRectY() - - hsCurrent->yCorrection()) > bounds.bottom)) { - // Return false - the door can't be closed - return false; - } + // Check to see if the character is intersecting the door area + int tempY = hsCurrent->y() + hsCurrent->heightCopy(); + if ((hsCurrent->x() >= bounds.right) || + (hsCurrent->x() + hsCurrent->widthCopy() <= bounds.left) || + (tempY + hsCurrent->charRectY() < bounds.top) || + (tempY - hsCurrent->yCorrection() - hsCurrent->charRectY() > bounds.bottom)) + continue; + + // At this point we know a character is blocking door, so return false + return false; } // No blocking characters, so return true that the door can be closed @@ -1087,7 +1105,7 @@ void Hotspot::doAction(Action action, HotspotData *hotspot) { &Hotspot::npcSetSupportOffset, &Hotspot::npcSupportOffsetConditional, &Hotspot::npcDispatchAction, - &Hotspot::npcUnknown3, + &Hotspot::npcTalkNpcToNpc, &Hotspot::npcPause, &Hotspot::npcStartTalking, &Hotspot::npcJumpAddress}; @@ -1350,7 +1368,7 @@ void Hotspot::doGive(HotspotData *hotspot) { endAction(); if ((hotspot->hotspotId != PRISONER_ID) || (usedId != BOTTLE_HOTSPOT_ID)) - showMessage(7); + showMessage(7, hotspot->hotspotId); uint16 sequenceOffset = res.getHotspotAction(hotspot->actionsOffset, GIVE); @@ -1367,7 +1385,7 @@ void Hotspot::doGive(HotspotData *hotspot) { } else if (sequenceOffset == 0) { // Move item into character's inventory HotspotData *usedItem = res.getHotspot(usedId); - usedItem->roomNumber = hotspotId(); + usedItem->roomNumber = hotspot->hotspotId; } else if (sequenceOffset > 1) { showMessage(result); } @@ -1381,7 +1399,7 @@ void Hotspot::doTalkTo(HotspotData *hotspot) { fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId); if ((hotspot->hotspotId != SKORL_ID) && ((hotspot->roomNumber != 28) || - (hotspot->hotspotId != 0x3EB))) { + (hotspot->hotspotId != BLACKSMITH_ID))) { HotspotPrecheckResult result = actionPrecheck(hotspot); if (result == PC_WAIT) return; @@ -1889,8 +1907,38 @@ void Hotspot::npcDispatchAction(HotspotData *hotspot) { } } -void Hotspot::npcUnknown3(HotspotData *hotspot) { - warning("npcUnknown3: Not yet implemented"); +void Hotspot::npcTalkNpcToNpc(HotspotData *hotspot) { + Resources &res = Resources::getReference(); + ValueTableData &fields = res.fieldList(); + CharacterScheduleEntry &entry = _currentActions.top().supportData(); + fields.setField(ACTIVE_HOTSPOT_ID, hotspot->hotspotId); + fields.setField(USE_HOTSPOT_ID, hotspot->hotspotId); + + HotspotPrecheckResult result = actionPrecheck(hotspot); + if (result == PC_WAIT) return; + else if (result != PC_EXECUTE) { + endAction(); + return; + } + + // If dest is already talking, keep exiting until they're free + if (hotspot->talkCountdown != 0) + return; + + // Handle the source's talk message + if (entry.param(1) != 0) { + converse(hotspot->hotspotId, entry.param(1)); + resource()->talkCountdown += entry.param(2); + resource()->delayCtr = entry.param(2); + } + + // Handle the destination's response message + if (entry.param(3) != 0) { + Hotspot *destHotspot = res.getActiveHotspot(hotspot->hotspotId); + assert(destHotspot); + destHotspot->converse(this->hotspotId(), entry.param(3)); + } + endAction(); } @@ -1977,6 +2025,7 @@ void Hotspot::startTalk(HotspotData *charHotspot, uint16 id) { // Signal the character that they're being talked to charHotspot->talkDestCharacterId = _hotspotId; _data->talkDestCharacterId = charHotspot->hotspotId; + _data->talkGate = 0; // Set the active talk data res.setTalkStartEntry(0); @@ -1995,6 +2044,7 @@ void Hotspot::saveToStream(Common::WriteStream *stream) { stream->writeSint16LE(_startY); stream->writeSint16LE(_destX); stream->writeSint16LE(_destY); + stream->writeUint16LE(_destHotspotId); stream->writeUint16LE(_frameWidth); stream->writeUint16LE(_height); stream->writeUint16LE(_width); @@ -2004,9 +2054,8 @@ void Hotspot::saveToStream(Common::WriteStream *stream) { stream->writeUint16LE(_talkX); stream->writeUint16LE(_talkY); stream->writeByte(_layer); - stream->writeUint16LE(_sequenceOffset); + stream->writeUint16LE(_hotspotScriptOffset); stream->writeUint16LE(_tickCtr); - stream->writeUint32LE(_actions); stream->writeByte(_colourOffset); stream->writeUint16LE(_animId); stream->writeUint16LE(_frameNumber); @@ -2031,6 +2080,7 @@ void Hotspot::loadFromStream(Common::ReadStream *stream) { _startY = stream->readSint16LE(); _destX = stream->readSint16LE(); _destY = stream->readSint16LE(); + _destHotspotId = stream->readUint16LE(); _frameWidth = stream->readUint16LE(); _height = stream->readUint16LE(); _width = stream->readUint16LE(); @@ -2040,9 +2090,8 @@ void Hotspot::loadFromStream(Common::ReadStream *stream) { _talkX = stream->readUint16LE(); _talkY = stream->readUint16LE(); _layer = stream->readByte(); - _sequenceOffset = stream->readUint16LE(); + _hotspotScriptOffset = stream->readUint16LE(); _tickCtr = stream->readUint16LE(); - _actions = stream->readUint32LE(); _colourOffset = stream->readByte(); setAnimation(stream->readUint16LE()); setFrameNumber(stream->readUint16LE()); @@ -2062,6 +2111,9 @@ void Hotspot::loadFromStream(Common::ReadStream *stream) { HandlerMethodPtr HotspotTickHandlers::getHandler(uint16 procOffset) { switch (procOffset) { + case 0: + case 0x41BD: + return defaultHandler; case STANDARD_CHARACTER_TICK_PROC: return standardCharacterAnimHandler; case VOICE_TICK_PROC_ID: @@ -2076,16 +2128,22 @@ HandlerMethodPtr HotspotTickHandlers::getHandler(uint16 procOffset) { return followerAnimHandler; case 0x7EFA: return skorlAnimHandler; - case 0x7F37: + case STANDARD_ANIM_2_TICK_PROC: return standardAnimHandler2; - case 0x7F3A: + case STANDARD_ANIM_TICK_PROC: return standardAnimHandler; + case 0x7F54: + return sonicRatAnimHandler; case 0x7F69: return droppingTorchAnimHandler; case 0x7FA1: return playerSewerExitAnimHandler; case 0x8009: return fireAnimHandler; + case 0x80C6: + return sparkleAnimHandler; + case 0x813F: + return teaAnimHandler; case 0x8180: return goewinCaptiveAnimHandler; case 0x81B3: @@ -2095,17 +2153,23 @@ HandlerMethodPtr HotspotTickHandlers::getHandler(uint16 procOffset) { case 0x820E: return morkusAnimHandler; case 0x8241: - return headAnimHandler; + return grubAnimHandler; case 0x82A0: return barmanAnimHandler; case 0x85ce: return skorlGaurdAnimHandler; + case 0x862D: + return gargoyleAnimHandler; + case 0x86FA: + case 0x86FF: + return skullAnimHandler; case 0x882A: return rackSerfAnimHandler; case TALK_TICK_PROC_ID: return talkAnimHandler; default: - return defaultHandler; + error("Unknown tick proc %xh for hotspot", procOffset); +// return defaultHandler; } } @@ -2147,14 +2211,14 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) { // Handle any active hotspot the character is using (for example, if the player is // talking to a character, this stops them from moving for the duration) - if (h.useHotspotId() != 0) { - debugC(ERROR_DETAILED, kLureDebugAnimations, "Use Hotspot Id = %xh, v2b = %d", - h.useHotspotId(), h.v2b()); - if (h.v2b() == 0x2A) { - fields.setField(ACTIVE_HOTSPOT_ID, h.v2b()); - fields.setField(USE_HOTSPOT_ID, h.useHotspotId()); - Script::execute(h.script()); - h.setUseHotspotId(0); + if (h.resource()->talkDestCharacterId != 0) { + debugC(ERROR_DETAILED, kLureDebugAnimations, "Use Hotspot Id = %xh, talk_gate = %d", + h.resource()->talkDestCharacterId, h.talkGate()); + if (h.talkGate() == 0x2A) { + fields.setField(ACTIVE_HOTSPOT_ID, h.talkGate()); + fields.setField(USE_HOTSPOT_ID, h.resource()->talkDestCharacterId); + Script::execute(h.talkScript()); + h.resource()->talkDestCharacterId = 0; } else { h.updateMovement(); return; @@ -2265,6 +2329,7 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) { debugC(ERROR_DETAILED, kLureDebugAnimations, "Hotspot standard character point 6"); CurrentAction action = actions.action(); + PathFinderResult pfResult; switch (action) { case NO_ACTION: @@ -2314,14 +2379,15 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) { debugC(ERROR_DETAILED, kLureDebugAnimations, "Hotspot standard character processing path"); res.pausedList().scan(h); - if (!pathFinder.process()) break; + pfResult = pathFinder.process(); + if (pfResult == PF_UNFINISHED) break; debugC(ERROR_DETAILED, kLureDebugAnimations, - "pathFinder done: result = %d", pathFinder.result()); + "pathFinder done: result = %d", pfResult); // Post-processing checks - if ((pathFinder.result() == PF_OK) || - ((h.destHotspotId() == 0) && (pathFinder.result() == PF_DEST_OCCUPIED))) { + if ((pfResult == PF_OK) || + ((h.destHotspotId() == 0) && (pfResult == PF_DEST_OCCUPIED))) { // Standard processing debugC(ERROR_DETAILED, kLureDebugAnimations, "Standard result handling"); @@ -2581,6 +2647,7 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) { } CurrentAction action = actions.action(); + PathFinderResult pfResult; switch (action) { case NO_ACTION: @@ -2633,16 +2700,16 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) { h.setCharacterMode(CHARMODE_NONE); res.pausedList().scan(h); - if (!pathFinder.process()) break; + pfResult = pathFinder.process(); + if (pfResult == PF_UNFINISHED) break; // Pathfinding is now complete pathFinder.list(buffer); debugC(ERROR_DETAILED, kLureDebugAnimations, "Pathfind processing done; result=%d, walkFlag=%d\n%s", - pathFinder.result(), h.walkFlag(), buffer); + pfResult, h.walkFlag(), buffer); - if ((pathFinder.result() != PF_OK) && - (h.walkFlag() || (pathFinder.result() != PF_DEST_OCCUPIED))) { + if ((pfResult != PF_OK) && (h.walkFlag() || (pfResult != PF_DEST_OCCUPIED))) { debugC(ERROR_DETAILED, kLureDebugAnimations, "Blocked state checking"); if (h.blockedState() == BS_FINAL) { @@ -2681,11 +2748,10 @@ void HotspotTickHandlers::playerAnimHandler(Hotspot &h) { // The character is currently moving h.setOccupied(false); - if ((h.destHotspotId() != 0) && (h.destHotspotId() != 0xffff)) { - // Player is walking to a room exit hotspot + if (h.destHotspotId() != 0) { RoomExitJoinData *joinRec = res.getExitJoin(h.destHotspotId()); - if (joinRec->blocked) { - // Exit now blocked, so stop walking + if ((joinRec != NULL) && (joinRec->blocked)) { + // Player is walking to a blocked room exit, so stop walking actions.pop(); h.setOccupied(true); break; @@ -2757,18 +2823,6 @@ void HotspotTickHandlers::followerAnimHandler(Hotspot &h) { return; } - if (fields.wanderingCharsLoaded()) { - // Start Ratpouch to sewer exit to meet player - fields.wanderingCharsLoaded() = false; - h.setBlockedFlag(false); - CharacterScheduleEntry *newEntry = res.charSchedules().getEntry(RETURN_SUPPORT_ID); - h.currentActions().addFront(DISPATCH_ACTION, newEntry, 7); - h.setActionCtr(0); - - standardCharacterAnimHandler(h); - return; - } - // Handle any pause countdown if (countdownCtr > 0) { --countdownCtr; @@ -2841,6 +2895,16 @@ void HotspotTickHandlers::skorlAnimHandler(Hotspot &h) { standardCharacterAnimHandler(h); } +void HotspotTickHandlers::sonicRatAnimHandler(Hotspot &h) { + if (h.actionCtr() == 0) { + HotspotData *player = Resources::getReference().getHotspot(PLAYER_ID); + if (Support::charactersIntersecting(h.resource(), player)) + h.setActionCtr(1); + } else { + standardAnimHandler(h); + } +} + void HotspotTickHandlers::droppingTorchAnimHandler(Hotspot &h) { if (h.frameCtr() > 0) h.setFrameCtr(h.frameCtr() - 1); @@ -2886,6 +2950,10 @@ void HotspotTickHandlers::playerSewerExitAnimHandler(Hotspot &h) { ratpouchHotspot->setCharacterMode(CHARMODE_NONE); ratpouchHotspot->setDelayCtr(0); ratpouchHotspot->setActions(0x821C00); + + // Ratpouch has previously been moved to room 8. Start him moving to room 7 + ratpouchHotspot->currentActions().clear(); + ratpouchHotspot->currentActions().addFront(DISPATCH_ACTION, 7); } } @@ -2894,6 +2962,59 @@ void HotspotTickHandlers::fireAnimHandler(Hotspot &h) { h.setOccupied(true); } +void HotspotTickHandlers::sparkleAnimHandler(Hotspot &h) { + Resources &res = Resources::getReference(); + Hotspot *player = res.getActiveHotspot(PLAYER_ID); + ValueTableData &fields = res.fieldList(); + + h.setRoomNumber(player->roomNumber()); + h.setPosition(player->x() - 14, player->y() - 10); + h.setActionCtr(h.actionCtr() + 1); + if (h.actionCtr() == 6) { + uint16 animId; + if ((fields.getField(11) == 2) || (fields.getField(28) != 0)) { + fields.setField(28, 0); + animId = PLAYER_ANIM_ID; + } else { + fields.setField(28, fields.getField(28) + 1); + animId = SELENA_ANIM_ID; + } + + player->setAnimation(animId); + } + + if (h.executeScript()) { + HotspotData *data = h.resource(); + res.deactivateHotspot(&h); + data->roomNumber = 0x1A8; + + if (fields.getField(28) != 0) { + Hotspot *ratpouch = res.getActiveHotspot(RATPOUCH_ID); + assert(ratpouch); + ratpouch->converse(NOONE_ID, 0x854, false); + + uint16 dataId = res.getCharOffset(4); + CharacterScheduleEntry *entry = res.charSchedules().getEntry(dataId); + + ratpouch->currentActions().addFront(DISPATCH_ACTION, entry, ratpouch->roomNumber()); + ratpouch->setActionCtr(0); + } + } +} + +void HotspotTickHandlers::teaAnimHandler(Hotspot &h) { + if (h.frameCtr() > 0) { + h.decrFrameCtr(); + return; + } + + if (h.executeScript()) { + // Signal that the tea is done + h.setHotspotScript(0xB82); + Resources::getReference().fieldList().setField(27, 1); + } +} + void HotspotTickHandlers::goewinCaptiveAnimHandler(Hotspot &h) { if (h.actionCtr() > 0) { if (h.executeScript()) { @@ -2916,14 +3037,14 @@ void HotspotTickHandlers::prisonerAnimHandler(Hotspot &h) { if (h.actionCtr() != 0) { if (h.executeScript() == 0) { h.setActionCtr(0); - h.setScript(0x3E0); + h.setHotspotScript(0x3E0); } return; } if ((fields.getField(PRISONER_DEAD) == 0) && (rnd.getRandomNumber(65536) >= 6)) { h.setActionCtr(1); - h.setScript(0x3F6); + h.setHotspotScript(0x3F6); } } @@ -2947,7 +3068,7 @@ void HotspotTickHandlers::morkusAnimHandler(Hotspot &h) { if (h.executeScript()) { // Script is done - set new script to one of two alternates randomly Common::RandomSource rnd; - h.setScript(rnd.getRandomNumber(100) >= 50 ? 0x54 : 0); + h.setHotspotScript(rnd.getRandomNumber(100) >= 50 ? 0x54 : 0); h.setFrameCtr(20 + rnd.getRandomNumber(63)); } } @@ -3073,10 +3194,13 @@ void HotspotTickHandlers::talkAnimHandler(Hotspot &h) { selectedLine, descId); // Get the response the destination character will say - if (descId != TALK_MAGIC_ID) + if (descId != TALK_MAGIC_ID) { // Set up to display the question and response in talk dialogs h.converse(talkDestCharacter, descId, false); - res.setTalkState(TALK_RESPOND_2); + res.setTalkState(TALK_RESPOND_2); + } else { + res.setTalkState(TALK_RESPOND_3); + } break; case TALK_RESPOND_2: @@ -3088,6 +3212,8 @@ void HotspotTickHandlers::talkAnimHandler(Hotspot &h) { if (res.getTalkingCharacter() != 0) return; + case TALK_RESPOND_3: + // Respond selectedLine = res.getTalkSelection(); entry = talkSelections[selectedLine-1]; @@ -3165,21 +3291,25 @@ void HotspotTickHandlers::talkAnimHandler(Hotspot &h) { } } -void HotspotTickHandlers::headAnimHandler(Hotspot &h) { +void HotspotTickHandlers::grubAnimHandler(Hotspot &h) { Resources &res = Resources::getReference(); + h.handleTalkDialog(); + Hotspot *character = res.getActiveHotspot(PLAYER_ID); uint16 frameNumber = 0; if (character->y() < 79) { - // TODO: - //character = res.getActiveHotspot(RATPOUCH_ID); - frameNumber = 1; - } else { - if (character->x() < 72) frameNumber = 0; - else if (character->x() < 172) frameNumber = 1; - else frameNumber = 2; + // If player is behind Grub, use Ratpouch if possible + Hotspot *ratpouch = res.getActiveHotspot(RATPOUCH_ID); + if ((ratpouch != NULL) && (ratpouch->roomNumber() == h.roomNumber())) + character = ratpouch; } + if (character->x() < 72) frameNumber = 0; + else if (character->x() < 172) frameNumber = 1; + else frameNumber = 2; + + h.setActionCtr(frameNumber); h.setFrameNumber(frameNumber); } @@ -3221,7 +3351,7 @@ void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) { h.setFrameCtr(barEntry.currentCustomer->serveFlags); barEntry.currentCustomer->serveFlags &= 0xf8; - } else if (!h.useHotspotId() == 0) { + } else if (h.resource()->talkDestCharacterId == 0) { // Player is not currently talking // Clear entry from list barEntry.currentCustomer->hotspotId = 0; @@ -3244,7 +3374,6 @@ void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) { barEntry.currentCustomer = &barEntry.customers[index]; Hotspot *hotspot = res.getActiveHotspot(barEntry.customers[index].hotspotId); assert(hotspot); -//DEBUG/TODO: Reaching here too early, so servee's x can be outside the bar range h.setSupportValue(hotspot->x()); // Save the position to move to h.setFrameCtr(0x80); // Flag for movement return; @@ -3400,6 +3529,18 @@ void HotspotTickHandlers::skorlGaurdAnimHandler(Hotspot &h) { h.setFrameNumber(h.actionCtr()); } +void HotspotTickHandlers::gargoyleAnimHandler(Hotspot &h) { + h.handleTalkDialog(); +} + +void HotspotTickHandlers::skullAnimHandler(Hotspot &h) { + Resources &res = Resources::getReference(); + RoomExitJoinData *joinRec = res.getExitJoin( + (h.hotspotId() == 0x42f) ? 0x272A : 0x272C); + + h.setFrameNumber(joinRec->blocked ? 0 : 1); +} + void HotspotTickHandlers::rackSerfAnimHandler(Hotspot &h) { Resources &res = Resources::getReference(); @@ -3413,7 +3554,7 @@ void HotspotTickHandlers::rackSerfAnimHandler(Hotspot &h) { switch (h.actionCtr()) { case 1: - h.setScript(RACK_SERF_SCRIPT_ID_1); + h.setHotspotScript(RACK_SERF_SCRIPT_ID_1); h.setActionCtr(2); break; @@ -3423,7 +3564,7 @@ void HotspotTickHandlers::rackSerfAnimHandler(Hotspot &h) { break; case 3: - h.setScript(RACK_SERF_SCRIPT_ID_2); + h.setHotspotScript(RACK_SERF_SCRIPT_ID_2); h.setActionCtr(4); h.setLayer(2); @@ -3548,6 +3689,7 @@ int WalkingActionEntry::numSteps() { PathFinder::PathFinder(Hotspot *h) { _hotspot = h; + _inUse = false; _list.clear(); _stepCtr = 0; } @@ -3562,12 +3704,13 @@ void PathFinder::clear() { void PathFinder::reset(RoomPathsData &src) { clear(); src.decompress(_layer, _hotspot->widthCopy()); + _inUse = true; } // Does the next stage of processing to figure out a path to take to a given // destination. Returns true if the path finding has been completed -bool PathFinder::process() { +PathFinderResult PathFinder::process() { bool returnFlag = _inProgress; // Check whether the pathfinding can be broken by the countdown counter bool breakFlag = (PATHFIND_COUNTDOWN != 0); @@ -3580,6 +3723,7 @@ bool PathFinder::process() { uint16 numSteps = 0, savedSteps = 0; bool altFlag; uint16 *pCurrent; + PathFinderResult result = PF_UNFINISHED; if (!_inProgress) { // Following code only done during first call to method @@ -3596,6 +3740,7 @@ bool PathFinder::process() { add(LEFT, -_xDestPos); _inProgress = false; + result = PF_OK; goto final_step; } @@ -3609,7 +3754,7 @@ bool PathFinder::process() { // Flag starting/ending cells *_pSrc = 1; _destOccupied = *_pDest != 0; - _result = _destOccupied ? PF_DEST_OCCUPIED : PF_OK; + result = _destOccupied ? PF_DEST_OCCUPIED : PF_OK; *_pDest = 0; // Set up the current pointer, adjusting away from edges if necessary @@ -3644,7 +3789,7 @@ bool PathFinder::process() { if (!returnFlag) { processCell(&_layer[(_yChangeStart + _yCtr * _yChangeInc) * DECODED_PATHS_WIDTH + (_xChangeStart + _xCtr * _xChangeInc)]); - if (breakFlag && (_countdownCtr <= 0)) return false; + if (breakFlag && (_countdownCtr <= 0)) return PF_UNFINISHED; } else { returnFlag = false; } @@ -3660,7 +3805,7 @@ bool PathFinder::process() { // At least one cell populated, so go repeat loop _cellPopulated = false; } else { - _result = PF_NO_PATH; + result = PF_PART_PATH; scanFlag = true; break; } @@ -3685,9 +3830,8 @@ bool PathFinder::process() { scanLine(ROOM_PATHS_HEIGHT - _destY, DECODED_PATHS_WIDTH, pTemp, v); if (pTemp == _pDest) { - _result = PF_NO_WALK; clear(); - return true; + return PF_NO_WALK; } _pDest = pTemp; @@ -3703,6 +3847,9 @@ bool PathFinder::process() { // walking steps in reverse order until source is reached int stageCtr; for (stageCtr = 0; stageCtr < 3; ++stageCtr) { + // Clear out any previously determined directions + clear(); + altFlag = stageCtr == 1; pCurrent = _pDest; @@ -3764,14 +3911,11 @@ bool PathFinder::process() { if ((stageCtr == 1) && (numSteps <= savedSteps)) // Less steps were needed, so break out break; - - // Clear out any previously determined directions - clear(); } // Add a final move if necessary - if (_result == PF_OK) { + if (result == PF_OK) { if (_xDestPos < 0) addBack(LEFT, -_xDestPos); else if (_xDestPos > 0) @@ -3782,7 +3926,7 @@ final_step: if (_xPos < 0) add(RIGHT, -_xPos); else if (_xPos > 0) add(LEFT, _xPos); - return true; + return result; } void PathFinder::list(char *buffer) { @@ -3905,39 +4049,45 @@ void PathFinder::initVars() { if (_yDestCurrent >= (FULL_SCREEN_HEIGHT - MENUBAR_Y_SIZE)) _yDestCurrent = FULL_SCREEN_HEIGHT - MENUBAR_Y_SIZE - 1; - _result = PF_OK; - // Subtract an amount from the countdown counter to compensate for // the time spent decompressing the walkable areas set for the room _countdownCtr -= 700; } void PathFinder::saveToStream(Common::WriteStream *stream) { - // Note: current saving process only handles the PathFinder correctly - // if all pathfinding is done in one go (ie. multiple calls pathfinding - // isn't supported) - - ManagedList<WalkingActionEntry *>::iterator i; - for (i = _list.begin(); i != _list.end(); ++i) { - WalkingActionEntry *entry = *i; - stream->writeByte(entry->direction()); - stream->writeSint16LE(entry->rawSteps()); + stream->writeByte(_inUse); + + if (_inUse) { + // Save the path finding plane + stream->write(_layer, sizeof(RoomPathsDecompressedData)); + + // Save any active step sequence + ManagedList<WalkingActionEntry *>::iterator i; + for (i = _list.begin(); i != _list.end(); ++i) { + WalkingActionEntry *entry = *i; + stream->writeByte(entry->direction()); + stream->writeSint16LE(entry->rawSteps()); + } + stream->writeByte(0xff); + stream->writeSint16LE(_stepCtr); } - stream->writeByte(0xff); - stream->writeByte(_result); - stream->writeSint16LE(_stepCtr); } void PathFinder::loadFromStream(Common::ReadStream *stream) { _inProgress = false; - _list.clear(); - uint8 direction; - while ((direction = stream->readByte()) != 0xff) { - int steps = stream->readSint16LE(); - _list.push_back(new WalkingActionEntry((Direction) direction, steps)); + _inUse = stream->readByte() != 0; + + if (_inUse) { + stream->read(_layer, sizeof(RoomPathsDecompressedData)); + + _list.clear(); + uint8 direction; + while ((direction = stream->readByte()) != 0xff) { + int steps = stream->readSint16LE(); + _list.push_back(new WalkingActionEntry((Direction) direction, steps)); + } + _stepCtr = stream->readSint16LE(); } - _result = (PathFinderResult)stream->readByte(); - _stepCtr = stream->readSint16LE(); } // Current action entry class methods @@ -3986,6 +4136,7 @@ void CurrentActionEntry::saveToStream(WriteStream *stream) { if (_dynamicSupportData) { // Write out the dynamic data + stream->writeByte(supportData().action()); stream->writeSint16LE(supportData().numParams()); for (int index = 0; index < supportData().numParams(); ++index) stream->writeUint16LE(supportData().param(index)); diff --git a/engines/lure/hotspots.h b/engines/lure/hotspots.h index af0eaf9b92..5bf7f1e310 100644 --- a/engines/lure/hotspots.h +++ b/engines/lure/hotspots.h @@ -65,17 +65,22 @@ private: static void playerAnimHandler(Hotspot &h); static void followerAnimHandler(Hotspot &h); static void skorlAnimHandler(Hotspot &h); + static void sonicRatAnimHandler(Hotspot &h); static void droppingTorchAnimHandler(Hotspot &h); static void playerSewerExitAnimHandler(Hotspot &h); static void fireAnimHandler(Hotspot &h); + static void sparkleAnimHandler(Hotspot &h); + static void teaAnimHandler(Hotspot &h); static void goewinCaptiveAnimHandler(Hotspot &h); static void prisonerAnimHandler(Hotspot &h); static void catrionaAnimHandler(Hotspot &h); static void morkusAnimHandler(Hotspot &h); static void talkAnimHandler(Hotspot &h); - static void headAnimHandler(Hotspot &h); + static void grubAnimHandler(Hotspot &h); static void barmanAnimHandler(Hotspot &h); static void skorlGaurdAnimHandler(Hotspot &h); + static void gargoyleAnimHandler(Hotspot &h); + static void skullAnimHandler(Hotspot &h); static void rackSerfAnimHandler(Hotspot &h); public: @@ -161,17 +166,18 @@ private: Direction _direction; int _numSteps; public: - WalkingActionEntry(Direction dir, int steps): _direction(dir), _numSteps(steps) {}; + WalkingActionEntry(Direction dir, int steps): _direction(dir), _numSteps(steps) {} Direction direction() { return _direction; } int &rawSteps() { return _numSteps; } int numSteps(); }; -enum PathFinderResult {PF_OK, PF_DEST_OCCUPIED, PF_NO_PATH, PF_NO_WALK}; +enum PathFinderResult {PF_UNFINISHED, PF_OK, PF_DEST_OCCUPIED, PF_PART_PATH, PF_NO_WALK}; class PathFinder { private: Hotspot *_hotspot; + bool _inUse; ManagedList<WalkingActionEntry *> _list; RoomPathsDecompressedData _layer; int _stepCtr; @@ -184,7 +190,6 @@ private: int16 _xDestCurrent, _yDestCurrent; bool _destOccupied; bool _cellPopulated; - PathFinderResult _result; uint16 *_pSrc, *_pDest; int _xChangeInc, _xChangeStart; int _yChangeInc, _yChangeStart; @@ -204,7 +209,7 @@ public: PathFinder(Hotspot *h); void clear(); void reset(RoomPathsData &src); - bool process(); + PathFinderResult process(); void list(char *buffer); void list() { list(NULL); } @@ -212,7 +217,6 @@ public: WalkingActionEntry &top() { return **_list.begin(); } bool isEmpty() { return _list.empty(); } int &stepCtr() { return _stepCtr; } - PathFinderResult result() { return _result; } void saveToStream(Common::WriteStream *stream); void loadFromStream(Common::ReadStream *stream); @@ -244,9 +248,8 @@ private: uint16 _frameNumber; Direction _direction; uint8 _layer; - uint16 _sequenceOffset; + uint16 _hotspotScriptOffset; uint16 _tickCtr; - uint32 _actions; uint8 _colourOffset; bool _persistant; HotspotOverrideData *_override; @@ -312,7 +315,7 @@ private: void npcSetSupportOffset(HotspotData *hotspot); void npcSupportOffsetConditional(HotspotData *hotspot); void npcDispatchAction(HotspotData *hotspot); - void npcUnknown3(HotspotData *hotspot); + void npcTalkNpcToNpc(HotspotData *hotspot); void npcPause(HotspotData *hotspot); void npcStartTalking(HotspotData *hotspot); void npcJumpAddress(HotspotData *hotspot); @@ -355,7 +358,11 @@ public: uint16 yCorrection() { return _yCorrection; } uint16 charRectY() { return _charRectY; } uint16 roomNumber() { return _roomNumber; } - uint16 script() { return _sequenceOffset; } + uint16 talkScript() { + assert(_data); + return _data->talkScriptOffset; + } + uint16 hotspotScript() { return _hotspotScriptOffset; } uint8 layer() { return _layer; } uint16 tickCtr() { return _tickCtr; } bool skipFlag() { return _skipFlag; } @@ -400,17 +407,20 @@ public: void setHeight(uint16 newHeight) { _height = newHeight; } - void setScript(uint16 offset) { + void setHotspotScript(uint16 offset) { assert(_data != NULL); - _sequenceOffset = offset; - _data->sequenceOffset = offset; + _hotspotScriptOffset = offset; + _data->hotspotScriptOffset = offset; } void setLayer(uint8 newLayer) { assert(_data != NULL); _layer = newLayer; _data->layer = newLayer; } - void setActions(uint32 newActions) { _actions = newActions; } + void setActions(uint32 newActions) { + assert(_data); + _data->actions = newActions; + } void setCharRectY(uint16 value) { _charRectY = value; } void setSkipFlag(bool value) { _skipFlag = value; } CharacterMode characterMode() { @@ -453,13 +463,13 @@ public: assert(_data); _data->useHotspotId = value; } - uint16 v2b() { + uint16 talkGate() { assert(_data); - return _data->v2b; + return _data->talkGate; } - void setV2b(uint16 value) { + void setTalkGate(uint16 value) { assert(_data); - _data->v2b = value; + _data->talkGate = value; } uint16 supportValue() { return _supportValue; } void setSupportValue(uint16 value) { _supportValue = value; } diff --git a/engines/lure/intro.h b/engines/lure/intro.h index 848d0ca19e..1a14ae1ec1 100644 --- a/engines/lure/intro.h +++ b/engines/lure/intro.h @@ -35,7 +35,7 @@ private: bool showScreen(uint16 screenId, uint16 paletteId, uint16 delaySize); bool delay(uint32 milliseconds); public: - Introduction(Screen &screen, OSystem &system): _screen(screen), _system(system) {}; + Introduction(Screen &screen, OSystem &system): _screen(screen), _system(system) {} bool show(); }; diff --git a/engines/lure/lure.cpp b/engines/lure/lure.cpp index de95aecb8a..f28dc00954 100644 --- a/engines/lure/lure.cpp +++ b/engines/lure/lure.cpp @@ -22,20 +22,9 @@ #include "common/stdafx.h" -#include "base/plugins.h" - #include "common/config-manager.h" -#include "common/endian.h" -#include "common/file.h" -#include "common/fs.h" #include "common/system.h" -#include "common/md5.h" #include "common/savefile.h" -#include "common/stream.h" - -#include "sound/mixer.h" -#include "sound/mididrv.h" -#include "sound/audiostream.h" #include "lure/luredefs.h" #include "lure/surface.h" @@ -45,125 +34,6 @@ namespace Lure { -enum { - // We only compute MD5 of the first kilobyte of our data files. - kMD5FileSizeLimit = 1024 -}; - -struct GameSettings { - const char *gameid; - const char *description; - byte id; - uint32 features; - Common::Language language; - const char *md5sum; - const char *checkFile; -}; - -// -static const GameSettings lure_games[] = { - { "lure", "Lure of the Temptress", GI_LURE, GF_FLOPPY, Common::EN_ANY, - "b2a8aa6d7865813a17a3c636e063572e", "disk1.vga" }, -/* - { "lure", "Lure of the Temptress", GI_LURE, GF_FLOPPY, Common::DE_DEU, - "7aa19e444dab1ac7194d9f7a40ffe54a", "disk1.vga" }, - { "lure", "Lure of the Temptress", GI_LURE, GF_FLOPPY, Common::FR_FRA, - "1c94475c1bb7e0e88c1757d3b5377e94", "disk1.vga" }, -*/ - { 0, 0, 0, 0, Common::UNK_LANG, 0, 0 } -}; - -// Keep list of different supported games - -static const PlainGameDescriptor lure_list[] = { - { "lure", "Lure of the Temptress" }, - { 0, 0 } -}; - -} // End of namespace Lure - -using namespace Lure; - -GameList Engine_LURE_gameIDList() { - GameList games; - const PlainGameDescriptor *g = lure_list; - - while (g->gameid) { - games.push_back(*g); - g++; - } - return games; -} - -GameDescriptor Engine_LURE_findGameID(const char *gameid) { - const PlainGameDescriptor *g = lure_list; - while (g->gameid) { - if (0 == scumm_stricmp(gameid, g->gameid)) - break; - g++; - } - return GameDescriptor(g->gameid, g->description); -} - -GameList Engine_LURE_detectGames(const FSList &fslist) { - GameList detectedGames; - const GameSettings *g; - FSList::const_iterator file; - - // Iterate over all files in the given directory - bool isFound = false; - for (file = fslist.begin(); file != fslist.end(); file++) { - if (file->isDirectory()) - continue; - - for (g = lure_games; g->gameid; g++) { - if (scumm_stricmp(file->name().c_str(), g->checkFile) == 0) - isFound = true; - } - if (isFound) - break; - } - - if (file == fslist.end()) - return detectedGames; - - char md5str[32 + 1]; - - if (Common::md5_file_string(*file, md5str, kMD5FileSizeLimit)) { - for (g = lure_games; g->gameid; g++) { - if (strcmp(g->md5sum, (char *)md5str) == 0) { - GameDescriptor dg(g->gameid, g->description, g->language); - dg.updateDesc((g->features & GF_FLOPPY) ? "Floppy" : 0); - detectedGames.push_back(dg); - } - } - if (detectedGames.empty()) { - printf("Your game version appears to be unknown. Please, report the following\n"); - printf("data to the ScummVM team along with name of the game you tried to add\n"); - printf("and its version/language/etc.:\n"); - - printf(" LURE MD5 '%s'\n\n", md5str); - - const PlainGameDescriptor *g1 = lure_list; - while (g1->gameid) { - detectedGames.push_back(*g1); - g1++; - } - } - } - return detectedGames; -} - -PluginError Engine_LURE_create(OSystem *syst, Engine **engine) { - assert(engine); - *engine = new LureEngine(syst); - return kNoError; -} - -REGISTER_PLUGIN(LURE, "Lure of the Temptress Engine", "Lure of the Temptress (C) Revolution"); - -namespace Lure { - static LureEngine *int_engine = NULL; LureEngine::LureEngine(OSystem *system): Engine(system) { @@ -186,76 +56,6 @@ LureEngine::LureEngine(OSystem *system): Engine(system) { _game = 0; } -void LureEngine::detectGame() { - // Make sure all the needed files are present - - if (!Common::File::exists(SUPPORT_FILENAME)) - error("Missing %s - this is a custom file containing resources from the\n" - "Lure of the Temptress executable. See the documentation for creating it.", - SUPPORT_FILENAME); - - for (uint8 fileNum = 1; fileNum <= 4; ++fileNum) - { - char sFilename[10]; - sprintf(sFilename, "disk%d.vga", fileNum); - - if (!Common::File::exists(sFilename)) - error("Missing disk%d.vga", fileNum); - } - - // Check the version of the lure.dat file - Common::File f; - if (!f.open(SUPPORT_FILENAME)) { - error("Error opening %s for validation", SUPPORT_FILENAME); - } else { - f.seek(0xbf * 8); - VersionStructure version; - f.read(&version, sizeof(VersionStructure)); - f.close(); - - if (READ_LE_UINT16(&version.id) != 0xffff) - error("Error validating %s - file is invalid or out of date", SUPPORT_FILENAME); - else if ((version.vMajor != LURE_DAT_MAJOR) || (version.vMinor != LURE_DAT_MINOR)) - error("Incorrect version of %s file - expected %d.%d but got %d.%d", - SUPPORT_FILENAME, LURE_DAT_MAJOR, LURE_DAT_MINOR, - version.vMajor, version.vMinor); - } - - // Do an md5 check - - char md5str[32 + 1]; - const GameSettings *g; - bool found = false; - - *md5str = 0; - - for (g = lure_games; g->gameid; g++) { - if (!Common::File::exists(g->checkFile)) - continue; - - if (!Common::md5_file_string(g->checkFile, md5str, kMD5FileSizeLimit)) - continue; - - if (strcmp(g->md5sum, (char *)md5str) == 0) { - _features = g->features; - _game = g->id; - _language = g->language; - - if (g->description) - g_system->setWindowCaption(g->description); - - found = true; - break; - } - } - - if (!found) { - debug("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team", md5str); - _features = GF_LNGUNK || GF_FLOPPY; - _game = GI_LURE; - } -} - int LureEngine::init() { _system->beginGFXTransaction(); initCommonGFX(false); diff --git a/engines/lure/luredefs.h b/engines/lure/luredefs.h index 8c85ab46c8..1419c1b4cb 100644 --- a/engines/lure/luredefs.h +++ b/engines/lure/luredefs.h @@ -31,7 +31,7 @@ namespace Lure { #define SUPPORT_FILENAME "lure.dat" #define LURE_DAT_MAJOR 1 -#define LURE_DAT_MINOR 17 +#define LURE_DAT_MINOR 19 #define LURE_DEBUG 1 @@ -85,16 +85,16 @@ enum Action { BRIBE = 24, EXAMINE = 25, NPC_SET_ROOM_AND_OFFSET = 28, - NPC_UNKNOWN1 = 29, + NPC_TALK_TO_PLAYER = 29, NPC_EXEC_SCRIPT = 30, - NPC_UNKNOWN2 = 31, + NPC_RESET_PAUSED_LIST = 31, NPC_SET_RAND_DEST = 32, NPC_WALKING_CHECK = 33, NPC_SET_SUPPORT_OFFSET = 34, NPC_SUPPORT_OFFSET_COND = 35, NPC_DISPATCH_ACTION = 36, - NPC_UNKNOWN3 = 37, - NPC_UNKNOWN4 = 38, + NPC_TALK_NPC_TO_NPC = 37, + NPC_PAUSE = 38, NPC_START_TALKING = 39, NPC_JUMP_ADDRESS = 40 }; @@ -225,11 +225,13 @@ enum Action { #define PLAYER_ID 0x3E8 #define RATPOUCH_ID 0x3E9 #define SKORL_ID 0x3EA +#define BLACKSMITH_ID 0x3EB #define GOEWIN_ID 0x3EF #define FIRST_NONCHARACTER_ID 0x408 #define SACK_ID 0x40D #define PRISONER_ID 0x412 #define SID_ID 0x420 +#define OIL_BURNER_ID 0x424 #define TRANSFORM_ID 0x425 #define NELLIE_ID 0x429 #define EWAN_ID 0x436 @@ -244,10 +246,12 @@ enum Action { // Tick proc constants #define STANDARD_CHARACTER_TICK_PROC 0x4f82 -#define TALK_TICK_PROC_ID 0x8ABD #define PLAYER_TICK_PROC_ID 0x5E44 #define VOICE_TICK_PROC_ID 0x625E #define PUZZLED_TICK_PROC_ID 0x6571 +#define STANDARD_ANIM_2_TICK_PROC 0x7F37 +#define STANDARD_ANIM_TICK_PROC 0x7f3a +#define TALK_TICK_PROC_ID 0x8ABD // String constants #define STRANGER_ID 0x17A @@ -263,6 +267,8 @@ enum Action { #define BLACKSMITH_HAMMERING_ANIM_ID 0x9c11 #define EWAN_ANIM_ID 0x59E4 #define EWAN_ALT_ANIM_ID 0x59ED +#define PLAYER_ANIM_ID 0x5C80 +#define SELENA_ANIM_ID 0x5CAA #define CONVERSE_COUNTDOWN_SIZE 40 #define IDLE_COUNTDOWN_SIZE 15 diff --git a/engines/lure/menu.cpp b/engines/lure/menu.cpp index 84f07a7b31..739e475f48 100644 --- a/engines/lure/menu.cpp +++ b/engines/lure/menu.cpp @@ -111,10 +111,7 @@ uint8 Menu::execute() { // If necessary, remove prior menu if (_selectedMenu) { toggleHighlight(_selectedMenu); -// screen.updateArea(_selectedMenu->xstart(), MENUBAR_Y_SIZE, -// _surfaceMenu->width(), _surfaceMenu->height()); - screen.updateArea(0, MENUBAR_Y_SIZE, FULL_SCREEN_WIDTH, - _surfaceMenu->height()); + screen.updateArea(0, 0, FULL_SCREEN_WIDTH, _surfaceMenu->height() + 8); delete _surfaceMenu; _surfaceMenu = NULL; _selectedIndex = 0; diff --git a/engines/lure/module.mk b/engines/lure/module.mk index 546721573d..a54eddd4cd 100644 --- a/engines/lure/module.mk +++ b/engines/lure/module.mk @@ -4,6 +4,7 @@ MODULE_OBJS := \ animseq.o \ debugger.o \ decode.o \ + detection.o \ disk.o \ events.o \ game.o \ diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp index dc36e60f3e..5782ccdecb 100644 --- a/engines/lure/res.cpp +++ b/engines/lure/res.cpp @@ -445,6 +445,13 @@ void Resources::setTalkingCharacter(uint16 id) { HotspotData *charHotspot = res.getHotspot(_talkingCharacter); assert(charHotspot); charHotspot->talkCountdown = 0; + + if (charHotspot->talkDestCharacterId != 0) { + HotspotData *destHotspot = res.getHotspot(charHotspot->talkDestCharacterId); + if (destHotspot != NULL) + destHotspot->talkDestCharacterId = 0; + } + charHotspot->talkDestCharacterId = 0; } _talkingCharacter = id; @@ -642,6 +649,8 @@ void Resources::saveToStream(Common::WriteStream *stream) _fieldList.saveToStream(stream); _randomActions.saveToStream(stream); _barmanLists.saveToStream(stream); + _exitJoins.saveToStream(stream); + _roomData.saveToStream(stream); } void Resources::loadFromStream(Common::ReadStream *stream) { @@ -655,6 +664,10 @@ void Resources::loadFromStream(Common::ReadStream *stream) { _randomActions.loadFromStream(stream); debugC(ERROR_DETAILED, kLureDebugScripts, "Loading barman lists"); _barmanLists.loadFromStream(stream); + debugC(ERROR_DETAILED, kLureDebugScripts, "Loading room exit joins"); + _exitJoins.loadFromStream(stream); + debugC(ERROR_DETAILED, kLureDebugScripts, "Loading walkable paths"); + _roomData.loadFromStream(stream); debugC(ERROR_DETAILED, kLureDebugScripts, "Finished loading"); } diff --git a/engines/lure/res.h b/engines/lure/res.h index b2574a2c46..7ee89f57b9 100644 --- a/engines/lure/res.h +++ b/engines/lure/res.h @@ -34,7 +34,7 @@ namespace Lure { enum TalkState {TALK_NONE, TALK_START, TALK_SELECT, TALK_RESPOND, TALK_RESPONSE_WAIT, - TALK_RESPOND_2}; + TALK_RESPOND_2, TALK_RESPOND_3}; #define MAX_TALK_SELECTIONS 4 typedef TalkEntryData *TalkSelections[MAX_TALK_SELECTIONS]; diff --git a/engines/lure/res_struct.cpp b/engines/lure/res_struct.cpp index 654430c46b..8c68462bf6 100644 --- a/engines/lure/res_struct.cpp +++ b/engines/lure/res_struct.cpp @@ -158,6 +158,15 @@ bool RoomPathsData::isOccupied(int x, int y) { return (_data[y * 5 + (x >> 3)] & (0x80 >> (x % 8))) != 0; } +bool RoomPathsData::isOccupied(int x, int y, int width) { + for (int blockCtr = 0; blockCtr < width; ++blockCtr) { + if (isOccupied(x + 8 * blockCtr, y)) + return true; + } + + return false; +} + void RoomPathsData::setOccupied(int x, int y, int width) { if ((x < 0) || (y < 0) || (x >= ROOM_PATHS_WIDTH) || (y >= ROOM_PATHS_HEIGHT)) return; @@ -202,7 +211,7 @@ void RoomPathsData::decompress(RoomPathsDecompressedData &dataOut, int character uint16 *pOut = &dataOut[DECODED_PATHS_WIDTH * DECODED_PATHS_HEIGHT - 1]; byte v; int paddingCtr; - int charWidth = (characterWidth - 1) >> 3; + int charWidth = characterWidth >> 3; int charCtr = 0; bool charState = false; @@ -212,6 +221,8 @@ void RoomPathsData::decompress(RoomPathsDecompressedData &dataOut, int character *pOut-- = 0; for (int y = 0; y < ROOM_PATHS_HEIGHT; ++y) { + charState = false; + for (int x = 0; x < (ROOM_PATHS_WIDTH / 8); ++x) { // Get next byte, which containing bits for 8 blocks v = *pIn--; @@ -258,6 +269,29 @@ void RoomPathsData::decompress(RoomPathsDecompressedData &dataOut, int character *pOut-- = 0; } +// Room data class + +void RoomDataList::saveToStream(WriteStream *stream) { + RoomDataList::iterator i; + + for (i = begin(); i != end(); ++i) { + RoomData *rec = *i; + const byte *pathData = rec->paths.data(); + stream->write(pathData, ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH); + } +} + +void RoomDataList::loadFromStream(ReadStream *stream) { + RoomDataList::iterator i; + byte data[ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH]; + + for (i = begin(); i != end(); ++i) { + RoomData *rec = *i; + stream->read(data, ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH); + rec->paths.load(data); + } +} + // Room exit joins class RoomExitJoinData::RoomExitJoinData(RoomExitJoinResource *rec) { @@ -274,6 +308,44 @@ RoomExitJoinData::RoomExitJoinData(RoomExitJoinResource *rec) { blocked = rec->blocked; } +void RoomExitJoinList::saveToStream(WriteStream *stream) { + for (RoomExitJoinList::iterator i = begin(); i != end(); ++i) { + RoomExitJoinData *rec = *i; + stream->writeUint16LE(rec->hotspot1Id); + stream->writeUint16LE(rec->hotspot2Id); + stream->writeByte(rec->h1CurrentFrame); + stream->writeByte(rec->h1DestFrame); + stream->writeByte(rec->h2CurrentFrame); + stream->writeByte(rec->h2DestFrame); + stream->writeByte(rec->blocked); + } + + // Write end of list marker + stream->writeUint16LE(0xffff); +} + +void RoomExitJoinList::loadFromStream(ReadStream *stream) { + for (RoomExitJoinList::iterator i = begin(); i != end(); ++i) { + RoomExitJoinData *rec = *i; + + uint16 hotspot1Id = stream->readUint16LE(); + if (hotspot1Id == 0xffff) error("Invalid room exit join list"); + uint16 hotspot2Id = stream->readUint16LE(); + + if ((rec->hotspot1Id != hotspot1Id) || (rec->hotspot2Id != hotspot2Id)) + break; + + rec->h1CurrentFrame = stream->readByte(); + rec->h1DestFrame = stream->readByte(); + rec->h2CurrentFrame = stream->readByte(); + rec->h2DestFrame = stream->readByte(); + rec->blocked = stream->readByte(); + } + + // Read final end of list marker + stream->readUint16LE(); +} + // Hotspot action record HotspotActionData::HotspotActionData(HotspotActionResource *rec) { @@ -321,10 +393,11 @@ HotspotData::HotspotData(HotspotResource *rec) { talkY = rec->talkY; colourOffset = FROM_LE_16(rec->colourOffset); animRecordId = FROM_LE_16(rec->animRecordId); - sequenceOffset = FROM_LE_16(rec->sequenceOffset); + hotspotScriptOffset = FROM_LE_16(rec->hotspotScriptOffset); + talkScriptOffset = FROM_LE_16(rec->talkScriptOffset); tickProcOffset = FROM_LE_16(rec->tickProcOffset); tickTimeout = FROM_LE_16(rec->tickTimeout); - tickSequenceOffset = FROM_LE_16(rec->tickSequenceOffset); + tickScriptOffset = FROM_LE_16(rec->tickScriptOffset); npcSchedule = FROM_LE_16(rec->npcSchedule); characterMode = (CharacterMode) FROM_LE_16(rec->characterMode); delayCtr = FROM_LE_16(rec->delayCtr); @@ -339,15 +412,15 @@ HotspotData::HotspotData(HotspotResource *rec) { talkMessageId = 0; talkDestCharacterId = 0; talkCountdown = 0; - pauseCtr = 0; useHotspotId = 0; - v2b = 0; + pauseCtr = 0; actionHotspotId = 0; talkOverride = 0; } void HotspotData::saveToStream(WriteStream *stream) { // Write out the basic fields + stream->writeUint16LE(nameId); stream->writeUint16LE(descId); stream->writeUint16LE(descId2); stream->writeUint32LE(actions); @@ -363,10 +436,10 @@ void HotspotData::saveToStream(WriteStream *stream) { stream->writeUint16LE(widthCopy); stream->writeUint16LE(heightCopy); stream->writeUint16LE(yCorrection); - stream->writeUint16LE(sequenceOffset); + stream->writeUint16LE(hotspotScriptOffset); stream->writeUint16LE(tickProcOffset); stream->writeUint16LE(tickTimeout); - stream->writeUint16LE(tickSequenceOffset); + stream->writeUint16LE(tickScriptOffset); stream->writeUint16LE(characterMode); stream->writeUint16LE(delayCtr); @@ -381,13 +454,14 @@ void HotspotData::saveToStream(WriteStream *stream) { stream->writeUint16LE(pauseCtr); stream->writeUint16LE(useHotspotId); stream->writeUint16LE(use2HotspotId); - stream->writeUint16LE(v2b); + stream->writeUint16LE(talkGate); stream->writeUint16LE(actionHotspotId); stream->writeUint16LE(talkOverride); } void HotspotData::loadFromStream(ReadStream *stream) { // Read in the basic fields + nameId = stream->readUint16LE(); descId = stream->readUint16LE(); descId2 = stream->readUint16LE(); actions = stream->readUint32LE(); @@ -403,10 +477,10 @@ void HotspotData::loadFromStream(ReadStream *stream) { widthCopy = stream->readUint16LE(); heightCopy = stream->readUint16LE(); yCorrection = stream->readUint16LE(); - sequenceOffset = stream->readUint16LE(); + hotspotScriptOffset = stream->readUint16LE(); tickProcOffset = stream->readUint16LE(); tickTimeout = stream->readUint16LE(); - tickSequenceOffset = stream->readUint16LE(); + tickScriptOffset = stream->readUint16LE(); characterMode = (CharacterMode) stream->readUint16LE(); delayCtr = stream->readUint16LE(); @@ -421,7 +495,7 @@ void HotspotData::loadFromStream(ReadStream *stream) { pauseCtr = stream->readUint16LE(); useHotspotId = stream->readUint16LE(); use2HotspotId = stream->readUint16LE(); - v2b = stream->readUint16LE(); + talkGate = stream->readUint16LE(); actionHotspotId = stream->readUint16LE(); talkOverride = stream->readUint16LE(); } @@ -825,8 +899,8 @@ RandomActionSet::RandomActionSet(uint16 *&offset) { } RandomActionSet::~RandomActionSet() { - delete _types; - delete _ids; + delete [] _types; + delete [] _ids; } RandomActionSet *RandomActionList::getRoom(uint16 roomNumber) { @@ -1079,7 +1153,6 @@ ValueTableData::ValueTableData() { _playerPendingPos.isSet = false; _flags = GAMEFLAG_4 | GAMEFLAG_1; _hdrFlagMask = 1; - _wanderingCharsLoaded = false; for (uint16 index = 0; index < NUM_VALUE_FIELDS; ++index) _fieldList[index] = 0; @@ -1126,7 +1199,6 @@ void ValueTableData::saveToStream(Common::WriteStream *stream) stream->writeSint16LE(_playerPendingPos.pos.y); stream->writeByte(_flags); stream->writeByte(_hdrFlagMask); - stream->writeByte(_wanderingCharsLoaded); // Write out the special fields for (int index = 0; index < NUM_VALUE_FIELDS; ++index) @@ -1145,7 +1217,6 @@ void ValueTableData::loadFromStream(Common::ReadStream *stream) _playerPendingPos.pos.y = stream->readSint16LE(); _flags = stream->readByte(); _hdrFlagMask = stream->readByte(); - _wanderingCharsLoaded = stream->readByte() != 0; // Read in the field list for (int index = 0; index < NUM_VALUE_FIELDS; ++index) diff --git a/engines/lure/res_struct.h b/engines/lure/res_struct.h index 24ccea732e..f53f8dd9a0 100644 --- a/engines/lure/res_struct.h +++ b/engines/lure/res_struct.h @@ -78,10 +78,11 @@ struct HotspotResource { int8 talkY; uint16 colourOffset; uint16 animRecordId; - uint16 sequenceOffset; + uint16 hotspotScriptOffset; + uint16 talkScriptOffset; uint16 tickProcOffset; uint16 tickTimeout; - uint16 tickSequenceOffset; + uint16 tickScriptOffset; uint16 npcSchedule; uint16 characterMode; uint16 delayCtr; @@ -303,13 +304,15 @@ class RoomPathsData { private: byte _data[ROOM_PATHS_HEIGHT * ROOM_PATHS_WIDTH]; public: - RoomPathsData() {}; + RoomPathsData() {} RoomPathsData(byte *srcData) { load(srcData); } void load(byte *srcData) { memcpy(_data, srcData, ROOM_PATHS_SIZE); } + const byte *data() { return _data; } bool isOccupied(int x, int y); + bool isOccupied(int x, int y, int width); void setOccupied(int x, int y, int width); void clearOccupied(int x, int y, int width); void decompress(RoomPathsDecompressedData &dataOut, int characterWidth); @@ -337,7 +340,11 @@ public: RoomPathsData paths; }; -typedef ManagedList<RoomData *> RoomDataList; +class RoomDataList: public ManagedList<RoomData *> { +public: + void saveToStream(WriteStream *stream); + void loadFromStream(ReadStream *stream); +}; class RoomExitJoinData { public: @@ -357,7 +364,11 @@ public: uint32 unknown; }; -typedef ManagedList<RoomExitJoinData *> RoomExitJoinList; +class RoomExitJoinList: public ManagedList<RoomExitJoinData *> { +public: + void saveToStream(WriteStream *stream); + void loadFromStream(ReadStream *stream); +}; class HotspotActionData { public: @@ -416,10 +427,11 @@ public: int8 talkY; uint16 colourOffset; uint16 animRecordId; - uint16 sequenceOffset; + uint16 hotspotScriptOffset; + uint16 talkScriptOffset; uint16 tickProcOffset; uint16 tickTimeout; - uint16 tickSequenceOffset; + uint16 tickScriptOffset; uint16 npcSchedule; CharacterMode characterMode; uint16 delayCtr; @@ -435,12 +447,13 @@ public: uint16 talkDestCharacterId; uint16 talkCountdown; uint16 pauseCtr; - uint16 useHotspotId; - uint16 use2HotspotId; - uint16 v2b; + uint16 useHotspotId; + uint16 talkGate; uint16 actionHotspotId; uint16 talkOverride; + uint16 use2HotspotId; + void enable() { flags |= 0x80; } void disable() { flags &= 0x7F; } Direction nonVisualDirection() { return (Direction) scriptLoadFlag; } @@ -796,7 +809,6 @@ private: PlayerPendingPosition _playerPendingPos; uint8 _flags; uint8 _hdrFlagMask; - bool _wanderingCharsLoaded; uint16 _fieldList[NUM_VALUE_FIELDS]; bool isKnownField(uint16 fieldIndex); @@ -814,7 +826,6 @@ public: uint8 &hdrFlagMask() { return _hdrFlagMask; } PlayerNewPosition &playerNewPos() { return _playerNewPos; } PlayerPendingPosition &playerPendingPos() { return _playerPendingPos; } - bool &wanderingCharsLoaded() { return _wanderingCharsLoaded; } void saveToStream(Common::WriteStream *stream); void loadFromStream(Common::ReadStream *stream); diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp index 3542a00720..6e651fbc68 100644 --- a/engines/lure/scripts.cpp +++ b/engines/lure/scripts.cpp @@ -55,10 +55,17 @@ void Script::activateHotspot(uint16 hotspotId, uint16 v2, uint16 v3) { // Sets a hotspot's animation script offset from a master table of offsets void Script::setHotspotScript(uint16 hotspotId, uint16 scriptIndex, uint16 v3) { - Resources &r = Resources::getReference(); - uint16 offset = r.getHotspotScript(scriptIndex); - HotspotData *rsc = r.getHotspot(hotspotId); - rsc->sequenceOffset = offset; + Resources &res = Resources::getReference(); + uint16 offset = res.getHotspotScript(scriptIndex); + Hotspot *hotspot = res.getActiveHotspot(hotspotId); + + if (hotspot != NULL) { + hotspot->setHotspotScript(offset); + } else { + HotspotData *hs = res.getHotspot(hotspotId); + assert(hs); + hs->hotspotScriptOffset = offset; + } } void Script::method2(uint16 v1, uint16 v2, uint16 v3) { @@ -264,7 +271,7 @@ void Script::setBlockingHotspotScript(uint16 charId, uint16 scriptIndex, uint16 uint16 offset = r.getHotspotScript(scriptIndex); Hotspot *hs = r.getActiveHotspot(charId); - hs->setScript(offset); + hs->setHotspotScript(offset); hs->currentActions().top().setAction(EXEC_HOTSPOT_SCRIPT); hs->setOccupied(true); } @@ -330,6 +337,21 @@ void Script::enableHotspot(uint16 hotspotId, uint16 v2, uint16 v3) { hotspot->flags = (hotspot->flags & 0xdf) | 0x80; } +// Display a message + +void Script::displayMessage2(uint16 messageId, uint16 hotspotId, uint16 v3) { + Hotspot *hotspot = Resources::getReference().getActiveHotspot(hotspotId); + assert(hotspot); + hotspot->showMessage(messageId); +} + +void Script::startOilBurner(uint16 v1, uint16 v2, uint16 v3) { + Hotspot *hotspot = Resources::getReference().getActiveHotspot(OIL_BURNER_ID); + assert(hotspot); + hotspot->setPosition(152, hotspot->y()); + hotspot->setTickProc(STANDARD_ANIM_TICK_PROC); +} + // Transforms the player void Script::transformPlayer(uint16 v1, uint16 v2, uint16 v3) { @@ -342,8 +364,8 @@ void Script::transformPlayer(uint16 v1, uint16 v2, uint16 v3) { hotspot->startY = player->startY - 10; Hotspot *activeHotspot = res.addHotspot(TRANSFORM_ID); - activeHotspot->setFrameNumber(0); - activeHotspot->setScript(0x630); + activeHotspot->setActionCtr(0); + activeHotspot->setHotspotScript(0x630); } // Marks the jail door in room 14 for closing @@ -380,6 +402,15 @@ void Script::doorOpen(uint16 hotspotId, uint16 v2, uint16 v3) { joinRec->blocked = 0; } +// Makes the specified NPC wait for the player to walk to them + +void Script::npcWait(uint16 hotspotId, uint16 v2, uint16 v3) { + Hotspot *hotspot = Resources::getReference().getActiveHotspot(hotspotId); + assert(hotspot); + hotspot->setCharacterMode(CHARMODE_WAIT_FOR_INTERACT); + hotspot->setDelayCtr(130); +} + // Lookup the given message Id for the specified character and display in a dialog void Script::displayMessage(uint16 messageId, uint16 characterId, uint16 unknownVal) { @@ -439,6 +470,14 @@ void Script::setVillageSkorlTickProc(uint16 v1, uint16 v2, uint16 v3) { hotspot->tickProcOffset = 0x7efa; } +// Free Goewin from captivity + +void Script::freeGoewin(uint16 v1, uint16 v2, uint16 v3) { + HotspotData *goewin = Resources::getReference().getHotspot(GOEWIN_ID); + goewin->actions = 0x820C00; // Enable Talk To, Give, Bribe, and Ask for + goewin->actionCtr = 1; +} + // Barman serving the player void Script::barmanServe(uint16 v1, uint16 v2, uint16 v3) { @@ -461,6 +500,16 @@ void Script::getNumGroats(uint16 v1, uint16 v2, uint16 v3) { fields.setField(GENERAL, fields.numGroats()); } +// Enables the talk action on the two gargoyles + +void Script::enableGargoylesTalk(uint16 v1, uint16 v2, uint16 v3) { + Resources &res = Resources::getReference(); + HotspotData *g1 = res.getHotspot(0x42C); + HotspotData *g2 = res.getHotspot(0x42D); + g1->actions = 1 << (TALK_TO - 1); + g2->actions = 1 << (TALK_TO - 1); +} + // Loads the specified animation, completely bypassing the standard process // of checking for a load proc/sequence @@ -538,19 +587,24 @@ SequenceMethodRecord scriptMethods[] = { {33, Script::cutSack}, {34, Script::increaseNumGroats}, {35, Script::enableHotspot}, - {37, Script::transformPlayer}, + {36, Script::displayMessage2}, + {37, Script::startOilBurner}, + {38, Script::transformPlayer}, {39, Script::jailClose}, {40, Script::checkDroppedDesc}, {42, Script::doorClose}, {44, Script::doorOpen}, + {45, Script::npcWait}, {47, Script::displayMessage}, {48, Script::setNewSupportData}, {49, Script::setSupportData}, {50, Script::givePlayerItem}, {51, Script::decreaseNumGroats}, {54, Script::setVillageSkorlTickProc}, + {55, Script::freeGoewin}, {56, Script::barmanServe}, {57, Script::getNumGroats}, + {59, Script::enableGargoylesTalk}, {62, Script::animationLoad}, {63, Script::addActions}, {64, Script::randomToGeneral}, @@ -559,16 +613,16 @@ SequenceMethodRecord scriptMethods[] = { {0xff, NULL}}; const char *scriptOpcodes[] = { - "ABORT", "ADD", "SUBTRACT", "MULTIPLY", "DIVIDE", "NOT_EQUALS", "EQUALS", - "GT", "LT", "LT2", "GT2", "AND", "OR", "LOGICAL_AND", "LOGICAL_OR", + "ABORT", "ADD", "SUBTRACT", "MULTIPLY", "DIVIDE", "EQUALS", "NOT_EQUALS", + "LT", "GT", "LTE", "GTE", "AND", "OR", "LOGICAL_AND", "LOGICAL_OR", "GET_FIELD", "SET_FIELD", "PUSH", "SUBROUTINE", "EXEC", "END", "COND_JUMP", "JUMP", "ABORT2", "ABORT3", "RANDOM" }; const char *scriptMethodNames[67] = { - "ACTIVATE HOTSPOT", "SET HOTSPOT SCRIPT", NULL, NULL, "CLEAR SEQUENCE DELAY LIST", - "DEACTIVATE HOTSPOT SET", "DEACTIVATE HOTSPOT", "RESET PATHFINDER", - "ADD DELAYED SCRIPT", NULL, + "ACTIVATE HOTSPOT", "SET HOTSPOT SCRIPT", NULL, "SET HOTSPOT FLAG MASK", + "CLEAR SEQUENCE DELAY LIST", "DEACTIVATE HOTSPOT SET", "DEACTIVATE HOTSPOT", + "RESET PATHFINDER", "ADD DELAYED SCRIPT", NULL, "IS CHARACTER IN ROOM", "SET HOTSPOT DESC", "SET HOTSPOT NAME", "PLAY SOUND", NULL, NULL, "DISPLAY DIALOG", NULL, "REMOTE ROOM VIEW SETUP", @@ -579,14 +633,15 @@ const char *scriptMethodNames[67] = { "DECREMENT # INVENTORY ITEMS", "SET TALKING", "SET ACTION CTR", "START SPEAKING", "DISABLE HOTSPOT", "CUT SACK", - "INCREASE # GROATS", "ENABLE HOTSPOT", NULL, "TRANSFORM PLAYER", - NULL, "ROOM 14 CLOSE DOOR", + "INCREASE # GROATS", "ENABLE HOTSPOT", "DISPLAY MESSAGE 2", "START OIL BURNER" + "TRANSFORM PLAYER", "JAIL CLOSE", - "CHECK DROPPED DESC", NULL, "CLOSE DOOR", NULL, "OPEN DOOR", NULL, NULL, + "CHECK DROPPED DESC", NULL, "CLOSE DOOR", NULL, "OPEN DOOR", "NPC WAIT", NULL, "DISPLAY MESSAGE", "SET NEW ACTION SUPPORT DATA", "SET ACTION SUPPORT DATA", "GIVE PLAYER ITEM", "DECREASE # GROATS", NULL, NULL, - "SET VILLAGE SKORL TICK PROC", NULL, NULL, "GET # GROATS", NULL, NULL, + "SET VILLAGE SKORL TICK PROC", "FREE GOEWIN", "BARMAN SERVE", "GET # GROATS", + NULL, "ENABLE GARGOYLE TALK", NULL, "KILL PLAYER", "ANIMATION LOAD", "ADD ACTIONS", "RANDOM TO GENERAL", "CHECK CELL DOOR", "METHOD 66" @@ -660,12 +715,12 @@ uint16 Script::execute(uint16 startOffset) { case S_OPCODE_SUBTRACT: case S_OPCODE_MULTIPLY: case S_OPCODE_DIVIDE: - case S_OPCODE_NOT_EQUALS: case S_OPCODE_EQUALS: - case S_OPCODE_GT: + case S_OPCODE_NOT_EQUALS: case S_OPCODE_LT: - case S_OPCODE_LT2: - case S_OPCODE_GT2: + case S_OPCODE_GT: + case S_OPCODE_LTE: + case S_OPCODE_GTE: case S_OPCODE_AND: case S_OPCODE_OR: case S_OPCODE_LOGICAL_AND: @@ -713,28 +768,36 @@ uint16 Script::execute(uint16 startOffset) { param = v2 % v1; // remainder break; - case S_OPCODE_NOT_EQUALS: - stack.push((stack.pop() != stack.pop()) ? 0 : 1); - break; - case S_OPCODE_EQUALS: - stack.push((stack.pop() == stack.pop()) ? 0 : 1); + stack.push((stack.pop() == stack.pop()) ? 1 : 0); break; - case S_OPCODE_GT: - stack.push((stack.pop() > stack.pop()) ? 1 : 0); + case S_OPCODE_NOT_EQUALS: + stack.push((stack.pop() != stack.pop()) ? 1 : 0); break; case S_OPCODE_LT: - stack.push((stack.pop() < stack.pop()) ? 1 : 0); + v1 = stack.pop(); + v2 = stack.pop(); + stack.push(v2 < v1 ? 1 : 0); + break; + + case S_OPCODE_GT: + v1 = stack.pop(); + v2 = stack.pop(); + stack.push(v2 > v1 ? 1 : 0); break; - case S_OPCODE_LT2: - stack.push((stack.pop() < stack.pop()) ? 1 : 0); + case S_OPCODE_LTE: + v1 = stack.pop(); + v2 = stack.pop(); + stack.push(v2 <= v1 ? 1 : 0); break; - case S_OPCODE_GT2: - stack.push((stack.pop() > stack.pop()) ? 1 : 0); + case S_OPCODE_GTE: + v1 = stack.pop(); + v2 = stack.pop(); + stack.push(v2 >= v1 ? 1 : 0); break; case S_OPCODE_AND: @@ -746,22 +809,24 @@ uint16 Script::execute(uint16 startOffset) { break; case S_OPCODE_LOGICAL_AND: - stack.push(((stack.pop() != 0) && (stack.pop() != 0)) ? 1 : 0); + v1 = stack.pop(); + v2 = stack.pop(); + stack.push(((v1 != 0) && (v2 != 0)) ? 1 : 0); break; case S_OPCODE_LOGICAL_OR: - stack.push(((stack.pop() != 0) || (stack.pop() != 0)) ? 1 : 0); + v1 = stack.pop(); + v2 = stack.pop(); + stack.push(((v1 != 0) || (v2 != 0)) ? 1 : 0); break; case S_OPCODE_GET_FIELD: - // Opcode not yet fully implemented fieldNum = param >> 1; v1 = fields.getField(fieldNum); stack.push(v1); break; case S_OPCODE_SET_FIELD: - // Opcode not yet fully implemented fieldNum = param >> 1; v1 = stack.pop(); fields.setField(fieldNum, v1); @@ -854,8 +919,8 @@ uint16 Script::execute(uint16 startOffset) { case S_OPCODE_EQUALS: case S_OPCODE_GT: case S_OPCODE_LT: - case S_OPCODE_LT2: - case S_OPCODE_GT2: + case S_OPCODE_LTE: + case S_OPCODE_GTE: case S_OPCODE_AND: case S_OPCODE_OR: case S_OPCODE_LOGICAL_AND: @@ -898,7 +963,7 @@ bool HotspotScript::execute(Hotspot *h) { Resources &r = Resources::getReference(); MemoryBlock *scriptData = r.hotspotScriptData(); - uint16 offset = h->script(); + uint16 offset = h->hotspotScript(); int16 opcode = 0; int16 param1, param2; uint32 actions; @@ -911,12 +976,12 @@ bool HotspotScript::execute(Hotspot *h) opcode = nextVal(scriptData, offset); switch (opcode) { - case S2_OPCODE_TIMEOUT: + case S2_OPCODE_FRAME_CTR: param1 = nextVal(scriptData, offset); - debugC(ERROR_DETAILED, kLureDebugScripts, "SET TIMEOUT = %d", param1); + debugC(ERROR_DETAILED, kLureDebugScripts, "SET FRAME_CTR = %d", param1); h->setTickCtr(param1); - h->setScript(offset); + h->setHotspotScript(offset); breakFlag = true; break; @@ -964,22 +1029,21 @@ bool HotspotScript::execute(Hotspot *h) h->setAnimation(param1); break; - case S2_OPCODE_UNKNOWN_247: + case S2_OPCODE_PLAY_SOUND: param1 = nextVal(scriptData, offset); param2 = nextVal(scriptData, offset); - debugC(ERROR_DETAILED, kLureDebugScripts, "SUB_247(%d,%d)", param1, param2); - + debugC(ERROR_DETAILED, kLureDebugScripts, "PLAY_SOUND(%d,%d)", param1, param2); // warning("UNKNOWN_247 stub called"); break; - case S2_OPCODE_UNKNOWN_258: + case S2_OPCODE_STOP_SOUND: param1 = nextVal(scriptData, offset); - debugC(ERROR_DETAILED, kLureDebugScripts, "SUB_258()"); + debugC(ERROR_DETAILED, kLureDebugScripts, "STOP_SOUND()"); // warning("UNKNOWN_258 stub called"); break; case S2_OPCODE_ACTIONS: - param1 = nextVal(scriptData, offset) << 4; + param1 = nextVal(scriptData, offset); param2 = nextVal(scriptData, offset); actions = (uint32) param1 | ((uint32) param2 << 16); @@ -992,7 +1056,7 @@ bool HotspotScript::execute(Hotspot *h) debugC(ERROR_DETAILED, kLureDebugScripts, "SET FRAME NUMBER = %d", opcode); h->setFrameNumber(opcode); - h->setScript(offset); + h->setHotspotScript(offset); breakFlag = true; break; } diff --git a/engines/lure/scripts.h b/engines/lure/scripts.h index 1e985b955a..e964328130 100644 --- a/engines/lure/scripts.h +++ b/engines/lure/scripts.h @@ -35,12 +35,12 @@ namespace Lure { #define S_OPCODE_SUBTRACT 2 #define S_OPCODE_MULTIPLY 3 #define S_OPCODE_DIVIDE 4 -#define S_OPCODE_NOT_EQUALS 5 -#define S_OPCODE_EQUALS 6 -#define S_OPCODE_GT 7 -#define S_OPCODE_LT 8 -#define S_OPCODE_LT2 9 -#define S_OPCODE_GT2 10 +#define S_OPCODE_EQUALS 5 +#define S_OPCODE_NOT_EQUALS 6 +#define S_OPCODE_LT 7 +#define S_OPCODE_GT 8 +#define S_OPCODE_LTE 9 +#define S_OPCODE_GTE 10 #define S_OPCODE_AND 11 #define S_OPCODE_OR 12 #define S_OPCODE_LOGICAL_AND 13 @@ -57,15 +57,15 @@ namespace Lure { #define S_OPCODE_ABORT3 24 #define S_OPCODE_RANDOM 25 -#define S2_OPCODE_TIMEOUT -1 +#define S2_OPCODE_FRAME_CTR -1 #define S2_OPCODE_POSITION -2 #define S2_OPCODE_CHANGE_POS -3 #define S2_OPCODE_UNLOAD -4 #define S2_OPCODE_DIMENSIONS -5 #define S2_OPCODE_JUMP -6 #define S2_OPCODE_ANIMATION -7 -#define S2_OPCODE_UNKNOWN_247 -8 -#define S2_OPCODE_UNKNOWN_258 -9 +#define S2_OPCODE_PLAY_SOUND -8 +#define S2_OPCODE_STOP_SOUND -9 #define S2_OPCODE_ACTIONS -10 @@ -105,19 +105,24 @@ public: static void cutSack(uint16 hotspotId, uint16 v2, uint16 v3); static void increaseNumGroats(uint16 characterId, uint16 numGroats, uint16 v3); static void enableHotspot(uint16 hotspotId, uint16 v2, uint16 v3); + static void displayMessage2(uint16 messageId, uint16 hotspotId, uint16 v3); + static void startOilBurner(uint16 v1, uint16 v2, uint16 v3); static void transformPlayer(uint16 v1, uint16 v2, uint16 v3); static void jailClose(uint16 v1, uint16 v2, uint16 v3); static void checkDroppedDesc(uint16 hotspotId, uint16 v2, uint16 v3); static void doorClose(uint16 hotspotId, uint16 v2, uint16 v3); static void displayMessage(uint16 messageId, uint16 characterId, uint16 unknownVal); static void doorOpen(uint16 hotspotId, uint16 v2, uint16 v3); + static void npcWait(uint16 hotspotId, uint16 v2, uint16 v3); static void setNewSupportData(uint16 hotspotId, uint16 index, uint16 v3); static void setSupportData(uint16 hotspotId, uint16 index, uint16 v3); static void givePlayerItem(uint16 hotspotId, uint16 v2, uint16 v3); static void decreaseNumGroats(uint16 characterId, uint16 numGroats, uint16 v3); static void setVillageSkorlTickProc(uint16 v1, uint16 v2, uint16 v3); + static void freeGoewin(uint16 v1, uint16 v2, uint16 v3); static void barmanServe(uint16 v1, uint16 v2, uint16 v3); static void getNumGroats(uint16 v1, uint16 v2, uint16 v3); + static void enableGargoylesTalk(uint16 v1, uint16 v2, uint16 v3); static void animationLoad(uint16 hotspotId, uint16 v2, uint16 v3); static void addActions(uint16 hotspotId, uint16 actions, uint16 v3); static void randomToGeneral(uint16 maxVal, uint16 minVal, uint16 v3); diff --git a/engines/lure/strings.cpp b/engines/lure/strings.cpp index 39f1377206..77f1471379 100644 --- a/engines/lure/strings.cpp +++ b/engines/lure/strings.cpp @@ -180,7 +180,7 @@ byte StringData::readBit() { return result; } -void StringData::initPosition(uint16 stringId) { +bool StringData::initPosition(uint16 stringId) { uint16 roomNumber = Room::getReference().roomNumber(); byte *stringTable; @@ -234,7 +234,7 @@ void StringData::initPosition(uint16 stringId) { if (readBit() == 0) break; _srcPos += 2; } - readBit(); + return readBit() != 0; } // readCharatcer @@ -262,14 +262,15 @@ char StringData::readCharacter() { } void StringData::getString(uint16 stringId, char *dest, const char *hotspotName, - const char *characterName) { + const char *characterName, int hotspotArticle, int characterArticle) { + const char *articles[4] = {"the ", "a ", "an ", ""}; char ch; strcpy(dest, ""); char *destPos = dest; stringId &= 0x1fff; // Strip off any article identifier if (stringId == 0) return; - initPosition(stringId); + bool includeArticles = initPosition(stringId); ch = readCharacter(); while (ch != '\0') { @@ -277,9 +278,12 @@ void StringData::getString(uint16 stringId, char *dest, const char *hotspotName, // Copy over hotspot or action ch = readCharacter(); const char *p = (ch == '1') ? hotspotName : characterName; + int article = !includeArticles ? 3 : ((ch == 1) ? hotspotArticle : characterArticle); + if (p != NULL) { - strcpy(destPos, p); - destPos += strlen(p); + strcpy(destPos, articles[article]); + strcat(destPos, p); + destPos += strlen(destPos); } } else if ((uint8) ch >= 0xa0) { const char *p = getName((uint8) ch - 0xa0); @@ -307,13 +311,4 @@ char *StringData::getName(uint8 nameIndex) { return (char *) (_names->data() + nameStart); } -// getStringWithArticle -// Fills a buffer with the string specified by a given string Id with a definite article prefix - -void StringData::getStringWithArticle(uint16 stringId, char *dest) { - const char *articles[4] = {"the ", "a ", "an ", ""}; - strcpy(dest, articles[stringId >> 14]); - getString(stringId, dest + strlen(dest)); -} - } // namespace Lure diff --git a/engines/lure/strings.h b/engines/lure/strings.h index 8c89ae5419..1947a14b82 100644 --- a/engines/lure/strings.h +++ b/engines/lure/strings.h @@ -35,7 +35,7 @@ public: char _ascii; CharacterEntry(uint8 numBits, uint32 sequence, char ascii): _numBits(numBits), - _sequence(sequence), _ascii(ascii) {}; + _sequence(sequence), _ascii(ascii) {} }; #define MAX_NUM_CHARS 218 @@ -50,7 +50,7 @@ private: byte _bitMask; void add(const char *sequence, char ascii); - void initPosition(uint16 stringId); + bool initPosition(uint16 stringId); char readCharacter(); byte readBit(); public: @@ -58,11 +58,11 @@ public: ~StringData(); static StringData &getReference(); - void getString(uint16 stringId, char *dest, const char *hotspotName, const char *characterName); + void getString(uint16 stringId, char *dest, const char *hotspotName, const char *characterName, + int hotspotArticle = 3, int characterArticle = 3); void getString(uint16 stringId, char *dest) { getString(stringId, dest, NULL, NULL); } - void getStringWithArticle(uint16 stringId, char *dest); char *getName(uint8 nameIndex); }; diff --git a/engines/lure/surface.cpp b/engines/lure/surface.cpp index ef38854bee..d0444391d7 100644 --- a/engines/lure/surface.cpp +++ b/engines/lure/surface.cpp @@ -385,7 +385,7 @@ Surface *Surface::getScreen(uint16 resourceId) { return new Surface(decodedData, FULL_SCREEN_WIDTH, decodedData->size() / FULL_SCREEN_WIDTH); } -bool Surface::getString(Common::String &line, uint32 maxSize, bool isNumeric, bool varLength, int16 x, int16 y) { +bool Surface::getString(Common::String &line, int maxSize, bool isNumeric, bool varLength, int16 x, int16 y) { OSystem &system = *g_system; Mouse &mouse = Mouse::getReference(); Events &events = Events::getReference(); @@ -404,7 +404,7 @@ bool Surface::getString(Common::String &line, uint32 maxSize, bool isNumeric, bo // Display the string screen.screen().writeString(x, y, newLine, true, DIALOG_TEXT_COLOUR, varLength); screen.update(); - int stringSize = screen.screen().textWidth(newLine.c_str()); + int stringSize = textWidth(newLine.c_str()); // Loop until the input string changes refreshFlag = false; @@ -420,7 +420,7 @@ bool Surface::getString(Common::String &line, uint32 maxSize, bool isNumeric, bo if ((ch == 13) || (keycode == 0x10f)) { // Return character screen.screen().fillRect( - Rect(x, y, x + stringSize + 8, y + FONT_HEIGHT), bgColour); + Rect(x, y, x + maxSize - 1, y + FONT_HEIGHT), bgColour); screen.update(); newLine.deleteLastChar(); line = newLine; @@ -430,7 +430,7 @@ bool Surface::getString(Common::String &line, uint32 maxSize, bool isNumeric, bo else if (ch == 27) { // Escape character screen.screen().fillRect( - Rect(x, y, x + stringSize + 8, y + FONT_HEIGHT), bgColour); + Rect(x, y, x + maxSize - 1, y + FONT_HEIGHT), bgColour); screen.update(); abortFlag = true; } else if (ch == 8) { @@ -438,14 +438,14 @@ bool Surface::getString(Common::String &line, uint32 maxSize, bool isNumeric, bo if (newLine.size() == 1) continue; screen.screen().fillRect( - Rect(x, y, x + stringSize + 8, y + FONT_HEIGHT), bgColour); + Rect(x, y, x + maxSize - 1, y + FONT_HEIGHT), bgColour); newLine.deleteChar(newLine.size() - 2); refreshFlag = true; - } else if ((ch >= ' ') && (newLine.size() < maxSize)) { + } else if ((ch >= ' ') && (stringSize + 8 < maxSize)) { if (((ch >= '0') && (ch <= '9')) || !isNumeric) { screen.screen().fillRect( - Rect(x, y, x + stringSize + 8, y + FONT_HEIGHT), bgColour); + Rect(x, y, x + maxSize - 1, y + FONT_HEIGHT), bgColour); newLine.insertChar(ch, newLine.size() - 1); refreshFlag = true; } @@ -504,6 +504,7 @@ TalkDialog::TalkDialog(uint16 characterId, uint16 destCharacterId, uint16 active char srcCharName[MAX_DESC_SIZE]; char destCharName[MAX_DESC_SIZE]; char itemName[MAX_DESC_SIZE]; + int characterArticle, hotspotArticle = 3; HotspotData *talkingChar = res.getHotspot(characterId); HotspotData *destCharacter = (destCharacterId == 0) ? NULL : @@ -512,16 +513,19 @@ TalkDialog::TalkDialog(uint16 characterId, uint16 destCharacterId, uint16 active res.getHotspot(activeItemId); assert(talkingChar); - strings.getString(talkingChar->nameId, srcCharName); + strings.getString(talkingChar->nameId & 0x1fff, srcCharName); + characterArticle = talkingChar->nameId >> 14; strcpy(destCharName, ""); if (destCharacter != NULL) strings.getString(destCharacter->nameId, destCharName); strcpy(itemName, ""); - if (itemHotspot != NULL) - strings.getStringWithArticle(itemHotspot->nameId, itemName); + if (itemHotspot != NULL) { + strings.getString(itemHotspot->nameId & 0x1fff, itemName); + hotspotArticle = itemHotspot->nameId >> 14; + } - strings.getString(descId, _desc, itemName, destCharName); + strings.getString(descId, _desc, itemName, destCharName, hotspotArticle, characterArticle); // Apply word wrapping to figure out the needed size of the dialog Surface::wordWrap(_desc, TALK_DIALOG_WIDTH - (TALK_DIALOG_EDGE_SIZE + 3) * 2, @@ -666,7 +670,7 @@ bool SaveRestoreDialog::show(bool saveDialog) { // Write out any existing save names for (index = 0; index < numSaves; ++index) - s->writeString(DIALOG_EDGE_SIZE, SR_SAVEGAME_NAMES_Y, saveNames[index]->c_str(), true); + s->writeString(DIALOG_EDGE_SIZE, SR_SAVEGAME_NAMES_Y + (index * 8), saveNames[index]->c_str(), true); // Display the dialog s->copyTo(&screen.screen(), SAVE_DIALOG_X, SAVE_DIALOG_Y); @@ -737,7 +741,8 @@ bool SaveRestoreDialog::show(bool saveDialog) { // If in save mode, allow the entry of a new savename if (saveDialog) { - if (!screen.screen().getString(*saveNames[selectedLine], 40, + if (!screen.screen().getString(*saveNames[selectedLine], + INFO_DIALOG_WIDTH - (DIALOG_EDGE_SIZE * 2), false, true, SAVE_DIALOG_X + DIALOG_EDGE_SIZE, SAVE_DIALOG_Y + SR_SAVEGAME_NAMES_Y + selectedLine * FONT_HEIGHT)) { // Aborted out of name selection, so restore old name and diff --git a/engines/lure/surface.h b/engines/lure/surface.h index cc737fafd0..2155f1b820 100644 --- a/engines/lure/surface.h +++ b/engines/lure/surface.h @@ -70,7 +70,7 @@ public: static Surface *newDialog(uint16 width, uint8 numLines, const char **lines, bool varLength = true, uint8 colour = DIALOG_TEXT_COLOUR); static Surface *newDialog(uint16 width, const char *lines, uint8 colour = DIALOG_TEXT_COLOUR); static Surface *getScreen(uint16 resourceId); - bool getString(Common::String &line, uint32 maxSize, bool isNumeric, bool varLength, int16 x, int16 y); + bool getString(Common::String &line, int maxSize, bool isNumeric, bool varLength, int16 x, int16 y); }; class Dialog { diff --git a/engines/parallaction/animation.cpp b/engines/parallaction/animation.cpp index 3d7e0a6190..67dc25994e 100644 --- a/engines/parallaction/animation.cpp +++ b/engines/parallaction/animation.cpp @@ -20,13 +20,9 @@ * */ -#include "parallaction/disk.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/music.h" -#include "parallaction/parser.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" namespace Parallaction { @@ -175,7 +171,7 @@ void jobDisplayAnimations(void *parm, Job *j) { else _si = _vm->_gfx->queryMask(v18->_top + v18->height()); -// printf("jobDisplayAnimations %s, x: %i, y: %i, w: %i, h: %i\n", v18->_name, v18->_left, v18->_top, v14._width, v14._height); + debugC(9, kDebugLocation, "jobDisplayAnimations(%s, x:%i, y:%i, z:%i, w:%i, h:%i, %p)", v18->_label._text, v18->_left, v18->_top, _si, v14._width, v14._height, v14._data0); _vm->_gfx->blitCnv(&v14, v18->_left, v18->_top, _si, Gfx::kBitBack); } @@ -465,7 +461,7 @@ void jobRunScripts(void *parm, Job *j) { while (((*inst)->_index != INST_SHOW) && (a->_flags & kFlagsActing)) { - debugC(1, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _instructionNamesRes[(*inst)->_index - 1]); + debugC(9, kDebugJobs, "Animation: %s, instruction: %s", a->_label._text, (*inst)->_index == INST_END ? "end" : _instructionNamesRes[(*inst)->_index - 1]); switch ((*inst)->_index) { case INST_ENDLOOP: // endloop diff --git a/engines/parallaction/archive.cpp b/engines/parallaction/archive.cpp index ab913f5d54..3f9d0098cf 100644 --- a/engines/parallaction/archive.cpp +++ b/engines/parallaction/archive.cpp @@ -51,7 +51,7 @@ Archive::Archive() { } void Archive::open(const char *file) { - debugC(1, kDebugDisk, "open archive '%s'", file); + debugC(3, kDebugDisk, "Archive::open(%s)", file); if (_archive.isOpen()) close(); @@ -83,8 +83,6 @@ void Archive::open(const char *file) { void Archive::close() { - debugC(1, kDebugDisk, "close current archive"); - if (!_archive.isOpen()) return; resetArchivedFile(); @@ -96,6 +94,8 @@ void Archive::close() { bool Archive::openArchivedFile(const char *filename) { resetArchivedFile(); + debugC(3, kDebugDisk, "Archive::openArchivedFile(%s)", filename); + if (!_archive.isOpen()) error("Archive::openArchivedFile: the archive is not open"); @@ -105,7 +105,7 @@ bool Archive::openArchivedFile(const char *filename) { } if (i == _numFiles) return false; - debugC(1, kDebugDisk, "file '%s' found in slot %i", filename, i); + debugC(9, kDebugDisk, "Archive::openArchivedFile: '%s' found in slot %i", filename, i); _file = true; diff --git a/engines/parallaction/callables.cpp b/engines/parallaction/callables.cpp index 9117bbf686..ffd7a844e4 100644 --- a/engines/parallaction/callables.cpp +++ b/engines/parallaction/callables.cpp @@ -26,13 +26,10 @@ #include "common/file.h" -#include "parallaction/disk.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/inventory.h" #include "parallaction/menu.h" -#include "parallaction/music.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" + namespace Parallaction { @@ -55,7 +52,8 @@ void _c_play_boogie(void *parm) { return; flag = 0; - _vm->_midiPlayer->play("boogie2"); + _vm->_soundMan->setMusicFile("boogie2"); + _vm->_soundMan->playMusic(); return; } @@ -67,17 +65,18 @@ void _c_score(void *parm) { } void _c_fade(void *parm) { + _vm->_gfx->setBlackPalette(); - _vm->_gfx->swapBuffers(); - Gfx::Palette pal; + memset(pal, 0, sizeof(Gfx::Palette)); + for (uint16 _di = 0; _di < 64; _di++) { _vm->_gfx->fadePalette(pal); _vm->_gfx->setPalette(pal); - } - _vm->waitTime( 1 ); + _vm->waitTime( 1 ); + } return; } @@ -246,12 +245,13 @@ void _c_endComment(void *param) { _vm->_gfx->floodFill(Gfx::kBitFront, r, 0); r.setWidth(w+3); - r.setHeight(w+4); + r.setHeight(h+3); r.moveTo(7, 7); _vm->_gfx->floodFill(Gfx::kBitFront, r, 1); - _vm->_gfx->setFont("comic"); + _vm->_gfx->setFont(kFontDialogue); _vm->_gfx->displayWrappedString(_vm->_location._endComment, 3, 5, 130, 0); + _vm->_gfx->updateScreen(); uint32 di = 0; for (di = 0; di < PALETTE_COLORS; di++) { @@ -297,21 +297,24 @@ void _c_endComment(void *param) { } void _c_frankenstein(void *parm) { + Gfx::Palette pal0; + Gfx::Palette pal1; for (uint16 i = 0; i <= BASE_PALETTE_COLORS; i++) { pal0[(i+FIRST_BASE_COLOR)] = _vm->_gfx->_palette[i]; pal0[(i+FIRST_BASE_COLOR)*3+1] = 0; pal0[(i+FIRST_BASE_COLOR)*3+2] = 0; - pal0[(i+FIRST_EHB_COLOR)*3+1] = 0; - pal0[(i+FIRST_EHB_COLOR)*3+2] = 0; + + pal1[(i+FIRST_BASE_COLOR)*3+1] = 0; + pal1[(i+FIRST_BASE_COLOR)*3+2] = 0; } for (uint16 _di = 0; _di < 30; _di++) { g_system->delayMillis(20); _vm->_gfx->setPalette(pal0, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); g_system->delayMillis(20); - _vm->_gfx->setPalette(pal0, FIRST_EHB_COLOR, EHB_PALETTE_COLORS); + _vm->_gfx->setPalette(pal1, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); } _vm->_gfx->setPalette(_vm->_gfx->_palette); @@ -360,43 +363,30 @@ void _c_finito(void *parm) { streamDonna.close(); cleanInventory(); - refreshInventory(_vm->_characterName); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); if (gameCompleted) { - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; - uint16 _ax = _vm->_gfx->getStringWidth(v4C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 70, v4C[_language]); - _ax = _vm->_gfx->getStringWidth(v3C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 100, v3C[_language]); - _ax = _vm->_gfx->getStringWidth(v2C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 130, v2C[_language]); - _ax = _vm->_gfx->getStringWidth(v1C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 160, v1C[_language]); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); + _vm->_gfx->setFont(kFontMenu); + _vm->_gfx->displayCenteredString(70, v4C[_language]); + _vm->_gfx->displayCenteredString(100, v3C[_language]); + _vm->_gfx->displayCenteredString(130, v2C[_language]); + _vm->_gfx->displayCenteredString(160, v1C[_language]); + + _vm->_gfx->updateScreen(); waitUntilLeftClick(); strcpy(_vm->_location._name, "estgrotta.drki"); _engineFlags |= kEngineChangeLocation; } else { - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; - uint16 _ax = _vm->_gfx->getStringWidth(v8C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 70, v8C[_language]); - _ax = _vm->_gfx->getStringWidth(v7C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 100, v7C[_language]); - _ax = _vm->_gfx->getStringWidth(v6C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 130, v6C[_language]); - _ax = _vm->_gfx->getStringWidth(v5C[_language]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 160, v5C[_language]); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); + _vm->_gfx->setFont(kFontMenu); + _vm->_gfx->displayCenteredString(70, v8C[_language]); + _vm->_gfx->displayCenteredString(100, v7C[_language]); + _vm->_gfx->displayCenteredString(130, v6C[_language]); + _vm->_gfx->displayCenteredString(160, v5C[_language]); + + _vm->_gfx->updateScreen(); waitUntilLeftClick(); _vm->_menu->selectCharacter(); @@ -436,13 +426,10 @@ void _c_testResult(void *parm) { _vm->_gfx->swapBuffers(); _vm->parseLocation("common"); - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; + _vm->_gfx->setFont(kFontMenu); - uint16 _ax = _vm->_gfx->getStringWidth(_slideText[0]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 38, _slideText[0]); - _ax = _vm->_gfx->getStringWidth(_slideText[1]); - _vm->_gfx->displayString((SCREEN_WIDTH - _ax)/2, 58, _slideText[1]); + _vm->_gfx->displayCenteredString(38, _slideText[0]); + _vm->_gfx->displayCenteredString(58, _slideText[1]); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBit2); @@ -450,4 +437,19 @@ void _c_testResult(void *parm) { return; } +void _c_offSound(void*) { + _vm->_soundMan->stopSfx(0); + _vm->_soundMan->stopSfx(1); + _vm->_soundMan->stopSfx(2); + _vm->_soundMan->stopSfx(3); +} + +void _c_startMusic(void*) { + _vm->_soundMan->playMusic(); +} + +void _c_closeMusic(void*) { + _vm->_soundMan->stopMusic(); +} + } // namespace Parallaction diff --git a/engines/parallaction/commands.cpp b/engines/parallaction/commands.cpp index 087abed156..d53763dfa8 100644 --- a/engines/parallaction/commands.cpp +++ b/engines/parallaction/commands.cpp @@ -23,10 +23,7 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/parser.h" -#include "parallaction/commands.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" + namespace Parallaction { diff --git a/engines/parallaction/commands.h b/engines/parallaction/commands.h index 91410218b9..dee063de66 100644 --- a/engines/parallaction/commands.h +++ b/engines/parallaction/commands.h @@ -73,7 +73,6 @@ struct Command { ~Command(); }; -//typedef Common::List<Command*> CommandList; typedef ManagedList<Command*> CommandList; } // namespace Parallaction diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp index 9b4b0e8932..9b48a187cc 100644 --- a/engines/parallaction/debug.cpp +++ b/engines/parallaction/debug.cpp @@ -23,45 +23,157 @@ #include "common/stdafx.h" #include "common/system.h" + #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" +#include "parallaction/debug.h" namespace Parallaction { const char *_jobDescriptions[] = { - "0 - draw label", - "1 - draw mouse", - "2 - delay remove Job (erase label) || show inventory", - "3 - draw animations", - "4 - NONE", - "5 - NONE", - "6 - NONE", - "7 - NONE", - "8 - NONE", - "9 - NONE", - "10 - NONE", - "11 - NONE", - "12 - NONE", - "13 - NONE", - "14 - NONE", - "15 - delay remove Job (erase label) || run scripts || erase animations", - "16 - NONE", - "17 - job_12d4 (put item on screen) || jobRemovePickedItem (remove item from screen)", - "18 - toggle door", - "19 - walk", - "20 - erase label || hide inventory", - "21 - erase mouse" + "draw label", + "draw mouse", + "delayed label deletion || show inventory", + "draw animations", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "NONE", + "delayed label deletion || run scripts || erase animations", + "NONE", + "put item || pickup item", + "toggle door", + "walk", + "erase label || hide inventory", + "erase mouse" }; -void beep() { -// sound(1500); -// delay(100); -// nosound(); - return; +Debugger::Debugger(Parallaction *vm) + : GUI::Debugger() { + _vm = vm; + + DCmd_Register("continue", WRAP_METHOD(Debugger, Cmd_Exit)); + DCmd_Register("location", WRAP_METHOD(Debugger, Cmd_Location)); + DCmd_Register("give", WRAP_METHOD(Debugger, Cmd_Give)); + DCmd_Register("jobs", WRAP_METHOD(Debugger, Cmd_Jobs)); + DCmd_Register("zones", WRAP_METHOD(Debugger, Cmd_Zones)); + DCmd_Register("animations", WRAP_METHOD(Debugger, Cmd_Animations)); + + +} + + +void Debugger::preEnter() { +} + + +void Debugger::postEnter() { } +bool Debugger::Cmd_Location(int argc, const char **argv) { + char *character = _vm->_characterName; + char *location = _vm->_location._name; + switch (argc) { + case 3: + character = const_cast<char*>(argv[2]); + location = const_cast<char*>(argv[1]); + sprintf(_vm->_location._name, "%s.%s", location, character); + // TODO: check if location exists + _engineFlags |= kEngineChangeLocation; + break; + + case 2: + location = const_cast<char*>(argv[1]); + sprintf(_vm->_location._name, "%s", location); + // TODO: check if location exists + _engineFlags |= kEngineChangeLocation; + break; + + case 1: + DebugPrintf("location <location name> [character name]\n"); + + } + + return true; +} + + +bool Debugger::Cmd_Give(int argc, const char **argv) { + + if (argc == 1) { + DebugPrintf("give <item name>\n"); + } else { + int index = _vm->_objectsNames->lookup(argv[1]); + if (index != -1) + _vm->addInventoryItem(index + 4); + else + DebugPrintf("invalid item name '%s'\n", argv[1]); + } + + return true; +} + + +bool Debugger::Cmd_Jobs(int argc, const char **argv) { + + JobList::iterator b = _vm->_jobs.begin(); + JobList::iterator e = _vm->_jobs.end(); + + DebugPrintf("+---+-------------------------------------------------------------+\n" + "|tag| description |\n" + "+---+-------------------------------------------------------------+\n"); + for ( ; b != e; b++) { + DebugPrintf("|%3i| %-60s|\n", (*b)->_tag, _jobDescriptions[(*b)->_tag] ); + } + DebugPrintf("+---+-------------------------------------------------------------+\n"); + + + return true; +} + +bool Debugger::Cmd_Zones(int argc, const char **argv) { + + ZoneList::iterator b = _vm->_zones.begin(); + ZoneList::iterator e = _vm->_zones.end(); + + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n" + "| name | l | t | r | b | type | flag |\n" + "+--------------------+---+---+---+---+--------+--------+\n"); + for ( ; b != e; b++) { + Zone *z = *b; + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_label._text, z->_left, z->_top, z->_right, z->_bottom, z->_type, z->_flags ); + } + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); + + + return true; +} + +bool Debugger::Cmd_Animations(int argc, const char **argv) { + + AnimationList::iterator b = _vm->_animations.begin(); + AnimationList::iterator e = _vm->_animations.end(); + + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n" + "| name | x | y | z | f | type | flag | \n" + "+--------------------+---+---+---+---+--------+--------+\n"); + for ( ; b != e; b++) { + Animation *a = *b; + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", a->_label._text, a->_left, a->_top, a->_z, a->_frame, a->_type, a->_flags ); + } + DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); + + + return true; +} } // namespace Parallaction diff --git a/engines/parallaction/debug.h b/engines/parallaction/debug.h new file mode 100644 index 0000000000..17b3fbb14f --- /dev/null +++ b/engines/parallaction/debug.h @@ -0,0 +1,33 @@ + +#ifndef PARALLACTION_DEBUGGER_H +#define PARALLACTION_DEBUGGER_H + +#include "gui/debugger.h" + +namespace Parallaction { + +class Parallaction; + +class Debugger : public GUI::Debugger { +public: + Debugger(Parallaction *vm); + virtual ~Debugger() {} // we need this for __SYMBIAN32__ archaic gcc/UIQ + +protected: + Parallaction *_vm; + + virtual void preEnter(); + virtual void postEnter(); + + bool Cmd_DebugLevel(int argc, const char **argv); + bool Cmd_Location(int argc, const char **argv); + bool Cmd_Give(int argc, const char **argv); + bool Cmd_Jobs(int argc, const char **argv); + bool Cmd_Zones(int argc, const char **argv); + bool Cmd_Animations(int argc, const char **argv); + +}; + +} // End of namespace Parallaction + +#endif diff --git a/engines/parallaction/defs.h b/engines/parallaction/defs.h index 9e877db457..d2b8f049d9 100644 --- a/engines/parallaction/defs.h +++ b/engines/parallaction/defs.h @@ -28,6 +28,8 @@ namespace Parallaction { +#define PATH_LEN 200 + template <class T> class ManagedList : public Common::List<T> { diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 1206b25d4c..6d2e3cec51 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -22,15 +22,10 @@ #include "common/stdafx.h" -#include "parallaction/commands.h" +#include "common/events.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/disk.h" -#include "parallaction/inventory.h" -#include "parallaction/parser.h" -#include "parallaction/zone.h" -#include "common/events.h" + namespace Parallaction { @@ -184,7 +179,7 @@ char *Parallaction::parseDialogueString(Script &script) { } while (strlen(vD0) == 0); - vD0[strlen(vD0)-1] = '\0'; // deletes the trailing '0xA' inserted by parseNextLine + vD0[strlen(vD0)-1] = '\0'; // deletes the trailing '0xA' // this is critical for Gfx::displayBalloonString to work properly char *vCC = (char*)malloc(strlen(vD0)+1); @@ -217,7 +212,8 @@ uint16 Parallaction::askDialoguePassword(Dialogue *q, StaticCnv *face) { // FIXME: see comment for updateInput() if (!g_system->getEventManager()->pollEvent(e)) continue; if (e.type != Common::EVENT_KEYDOWN) continue; - if (e.type != Common::EVENT_QUIT) g_system->quit(); + if (e.type == Common::EVENT_QUIT) + g_system->quit(); if (!isdigit(e.kbd.ascii)) continue; password[passwordLen] = e.kbd.ascii; @@ -225,6 +221,7 @@ uint16 Parallaction::askDialoguePassword(Dialogue *q, StaticCnv *face) { password[passwordLen] = '\0'; _gfx->displayBalloonString(_answerBalloonX[0] + 5, _answerBalloonY[0] + _answerBalloonH[0] - 15, password, 0); + _gfx->updateScreen(); g_system->delayMillis(20); } @@ -286,6 +283,7 @@ bool Parallaction::displayAnswers(Dialogue *q) { } i++; } + _gfx->updateScreen(); return displayed; } @@ -310,6 +308,7 @@ void Parallaction::displayQuestion(Dialogue *q, Cnv *cnv) { _gfx->drawBalloon(r, q->_mood & 0x10); _gfx->displayWrappedString(q->_text, QUESTION_BALLOON_X, QUESTION_BALLOON_Y, MAX_BALLOON_WIDTH, 0); + _gfx->updateScreen(); waitUntilLeftClick(); @@ -348,7 +347,7 @@ void Parallaction::runDialogue(SpeakData *data) { enterDialogue(); - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); bool isNpc = scumm_stricmp(data->_name, "yourself") && data->_name[0] != '\0'; Cnv *face = isNpc ? _disk->loadTalk(data->_name) : _char._talk; @@ -412,6 +411,7 @@ int16 Parallaction::selectAnswer(Question *q, StaticCnv *cnv) { cnv->_data0 = _char._talk->getFramePtr(q->_answers[_di]->_mood & 0xF); // cnv->_data1 = _char._talk->field_8[q->_answers[_di]->_mood & 0xF]; _gfx->flatBlitCnv(cnv, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront); + _gfx->updateScreen(); waitUntilLeftClick(); return _di; } @@ -434,6 +434,7 @@ int16 Parallaction::selectAnswer(Question *q, StaticCnv *cnv) { _gfx->flatBlitCnv(cnv, ANSWER_CHARACTER_X, ANSWER_CHARACTER_Y, Gfx::kBitFront); } + _gfx->updateScreen(); g_system->delayMillis(30); v2 = _si; } diff --git a/engines/parallaction/disk.cpp b/engines/parallaction/disk.cpp index c224ac5801..35b97b64c7 100644 --- a/engines/parallaction/disk.cpp +++ b/engines/parallaction/disk.cpp @@ -22,101 +22,15 @@ #include "common/stdafx.h" -#include "parallaction/defs.h" -#include "parallaction/graphics.h" +#include "graphics/iff.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/walk.h" -#include "graphics/ilbm.h" -namespace Parallaction { - -class RLEStream : public Common::ReadStream { - - Common::ReadStream *_input; - - byte _rembuf[257]; - int32 _wpos; - int32 _rpos; - - int32 _toBeRead; - byte* _dst; - int32 _read; - - void store(byte b) { - if (_toBeRead > 0) { - *_dst++ = b; - _read++; - _wpos = 0; - _rpos = 0; - } else { - assert(_wpos < 257); - _rembuf[_wpos++] = b; - _rpos = 0; - } - - _toBeRead--; - } - - void feed() { - int32 len = MIN(_wpos - _rpos, _toBeRead); - if (len == 0) return; - - memcpy(_dst, _rembuf + _rpos, len); - - _rpos += len; - _read += len; - _toBeRead -= len; - } - - void unpack() { - byte byteRun; - byte idx; - - uint32 i, j; - - while (_toBeRead > 0 && !_input->eos()) { - byteRun = _input->readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++) { - idx = _input->readByte(); - store(idx); - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = _input->readByte(); - for (j = 0; j < i; j++) { - store(idx); - } - } - } - - } - -public: - RLEStream(Common::ReadStream *input) : _input(input), _wpos(0), _rpos(0) { - } - - ~RLEStream() { - } - - bool eos() const { - return _input->eos() & (_rpos == _wpos); - } - - uint32 read(void *dataPtr, uint32 dataSize) { - _toBeRead = (int32)dataSize; - _dst = (byte*)dataPtr; - _read = 0; - - feed(); - unpack(); - return _read; - } -}; +namespace Audio { + AudioStream *make8SVXStream(Common::ReadStream &input); +} +namespace Parallaction { /* This stream class is just a wrapper around Archive, so @@ -290,7 +204,7 @@ Cnv* DosDisk::loadCnv(const char *filename) { uint32 decsize = numFrames * width * height; byte *data = (byte*)malloc(decsize); - RLEStream decoder(&_resArchive); + Graphics::PackBitsReadStream decoder(_resArchive); decoder.read(data, decsize); return new Cnv(numFrames, width, height, data); @@ -328,16 +242,22 @@ Script* DosDisk::loadLocation(const char *name) { if (IS_MINI_CHARACTER(_vm->_characterName)) { sprintf(archivefile, "%s%s", _vm->_characterName+4, _languageDir); } else { - if (IS_DUMMY_CHARACTER(_vm->_characterName)) strcpy(archivefile, _languageDir); - else { + if (IS_DUMMY_CHARACTER(_vm->_characterName)) { + strcpy(archivefile, _languageDir); + } else { sprintf(archivefile, "%s%s", _vm->_characterName, _languageDir); } } + strcat(archivefile, name); strcat(archivefile, ".loc"); + debugC(3, kDebugDisk, "DosDisk::loadLocation(%s): trying '%s'", name, archivefile); + if (!_locArchive.openArchivedFile(archivefile)) { sprintf(archivefile, "%s%s.loc", _languageDir, name); + debugC(3, kDebugDisk, "DosDisk::loadLocation(%s): trying '%s'", name, archivefile); + if (!_locArchive.openArchivedFile(archivefile)) errorFileNotFound(name); } @@ -365,7 +285,7 @@ StaticCnv* DosDisk::loadHead(const char* name) { name += 4; } - snprintf(path, 8, "%shead", name); + sprintf(path, "%shead", name); path[8] = '\0'; return loadExternalStaticCnv(path); @@ -377,10 +297,10 @@ StaticCnv* DosDisk::loadPointer() { } -Cnv* DosDisk::loadFont(const char* name) { +Font* DosDisk::loadFont(const char* name) { char path[PATH_LEN]; sprintf(path, "%scnv", name); - return loadExternalCnv(path); + return createFont(name, loadExternalCnv(path)); } @@ -416,7 +336,7 @@ StaticCnv* DosDisk::loadStatic(const char* name) { uint16 size = cnv->_width*cnv->_height; cnv->_data0 = (byte*)malloc(size); - RLEStream decoder(&_resArchive); + Graphics::PackBitsReadStream decoder(_resArchive); decoder.read(cnv->_data0, size); return cnv; @@ -489,12 +409,12 @@ void DosDisk::loadBackground(const char *filename) { byte *path = (byte*)calloc(1, SCREENPATH_WIDTH*SCREEN_HEIGHT); - RLEStream stream(&_resArchive); + Graphics::PackBitsReadStream stream(_resArchive); unpackBackground(&stream, bg, mask, path); _vm->_gfx->setBackground(bg); _vm->_gfx->setMask(mask); - setPath(path); + _vm->setPath(path); free(bg); free(mask); @@ -525,7 +445,7 @@ void DosDisk::loadMaskAndPath(const char *name) { _resArchive.read(maskBuf, SCREENMASK_WIDTH*SCREEN_HEIGHT); _vm->_gfx->setMask(maskBuf); - setPath(pathBuf); + _vm->setPath(pathBuf); return; } @@ -569,6 +489,26 @@ Table* DosDisk::loadTable(const char* name) { return t; } +Common::ReadStream* DosDisk::loadMusic(const char* name) { + char path[PATH_LEN]; + sprintf(path, "%s.mid", name); + + Common::File *stream = new Common::File; + if (!stream->open(path)) + errorFileNotFound(path); + + return stream; +} + + +Common::ReadStream* DosDisk::loadSound(const char* name) { + return NULL; +} + + + + + #pragma mark - @@ -736,7 +676,6 @@ public: - AmigaDisk::AmigaDisk(Parallaction *vm) : Disk(vm) { } @@ -916,23 +855,16 @@ StaticCnv* AmigaDisk::loadHead(const char* name) { return cnv; } -Cnv* AmigaDisk::loadFont(const char* name) { +Font* AmigaDisk::loadFont(const char* name) { debugC(1, kDebugDisk, "AmigaDisk::loadFont '%s'", name); char path[PATH_LEN]; - if (scumm_stricmp(name, "topaz")) - sprintf(path, "%sfont", name); - else - strcpy(path, "introfont"); + sprintf(path, "%sfont", name); if (!_resArchive.openArchivedFile(path)) errorFileNotFound(path); - // FIXME: actually read data from font file and create - // real font instead of this dummy one - byte *data = (byte*)malloc(256*8*8); - memset(data, 0, 256*8*8); - return new Cnv(256, 8, 8, data); + return createFont(name, _resArchive); } StaticCnv* AmigaDisk::loadStatic(const char* name) { @@ -985,34 +917,15 @@ Cnv* AmigaDisk::loadFrames(const char* name) { void AmigaDisk::loadSlide(const char *name) { debugC(1, kDebugDisk, "AmigaDisk::loadSlide '%s'", name); - - Common::SeekableReadStream *s = openArchivedFile(name, true); - - Graphics::Surface surf; - byte *pal; - - // CRNG headers may be safely ignored for slides - Graphics::ILBMDecoder decoder(*s); - decoder.decode(surf, pal); - - for (uint32 i = 0; i < PALETTE_SIZE; i++) - _vm->_gfx->_palette[i] = pal[i] >> 2; - free(pal); - _vm->_gfx->setPalette(_vm->_gfx->_palette); - - _vm->_gfx->setBackground(static_cast<byte*>(surf.pixels)); - surf.free(); - - delete s; - + loadBackground(name); return; } // FIXME: mask values are not computed correctly for level 1 and 2 void buildMask(byte* buf) { - byte mask0[16] = { 0, 0x80, 0x20, 0xA0, 8, 0x84, 0x28, 0xA8, 2, 0x82, 0x22, 0xA2, 0xA, 0x8A, 0x2A, 0xAA }; - byte mask1[16] = { 0, 0x40, 0x10, 0x50, 4, 0x42, 0x14, 0x54, 1, 0x41, 0x11, 0x51, 0x5, 0x45, 0x15, 0x55 }; + byte mask1[16] = { 0, 0x80, 0x20, 0xA0, 8, 0x88, 0x28, 0xA8, 2, 0x82, 0x22, 0xA2, 0xA, 0x8A, 0x2A, 0xAA }; + byte mask0[16] = { 0, 0x40, 0x10, 0x50, 4, 0x44, 0x14, 0x54, 1, 0x41, 0x11, 0x51, 0x5, 0x45, 0x15, 0x55 }; byte plane0[40]; byte plane1[40]; @@ -1036,18 +949,42 @@ class BackgroundDecoder : public Graphics::ILBMDecoder { uint32 _i; protected: - void readCRNG() { - _range[_i]._timer = _chunk.readUint16(); - _range[_i]._step = _chunk.readUint16(); - _range[_i]._flags = _chunk.readUint16(); - _range[_i]._first = _chunk.readByte(); - _range[_i]._last = _chunk.readByte(); + void readCRNG(Common::IFFChunk &chunk) { + _range[_i]._timer = chunk.readUint16BE(); + _range[_i]._step = chunk.readUint16BE(); + _range[_i]._flags = chunk.readUint16BE(); + _range[_i]._first = chunk.readByte(); + _range[_i]._last = chunk.readByte(); _i++; } public: - BackgroundDecoder(Common::ReadStream &input, PaletteFxRange *range) : ILBMDecoder(input), _range(range), _i(0) { + BackgroundDecoder(Common::ReadStream &input, Graphics::Surface &surface, byte *&colors, PaletteFxRange *range) : + Graphics::ILBMDecoder(input, surface, colors), _range(range), _i(0) { + } + + void decode() { + Common::IFFChunk *chunk; + while ((chunk = nextChunk()) != 0) { + switch (chunk->id) { + case ID_BMHD: + readBMHD(*chunk); + break; + + case ID_CMAP: + readCMAP(*chunk); + break; + + case ID_BODY: + readBODY(*chunk); + break; + + case ID_CRNG: + readCRNG(*chunk); + break; + } + } } uint32 getNumRanges() { @@ -1055,18 +992,17 @@ public: } }; -void AmigaDisk::loadScenery(const char* background, const char* mask) { - debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask); + +void AmigaDisk::loadBackground(const char *name) { + + Common::SeekableReadStream *s = openArchivedFile(name, true); Graphics::Surface surf; byte *pal; - char path[PATH_LEN]; + BackgroundDecoder decoder(*s, surf, pal, _vm->_gfx->_palettefx); + decoder.decode(); - sprintf(path, "%s.bkgnd", background); - Common::SeekableReadStream *s = openArchivedFile(path, true); - BackgroundDecoder decoder(*s, _vm->_gfx->_palettefx); - decoder.decode(surf, pal); - for (uint32 i = 0; i < PALETTE_SIZE; i++) + for (uint32 i = 0; i < BASE_PALETTE_COLORS * 3; i++) _vm->_gfx->_palette[i] = pal[i] >> 2; free(pal); _vm->_gfx->setPalette(_vm->_gfx->_palette); @@ -1074,31 +1010,74 @@ void AmigaDisk::loadScenery(const char* background, const char* mask) { surf.free(); delete s; - sprintf(path, "%s.mask", background); - s = openArchivedFile(path, true); + return; + +} + +void AmigaDisk::loadMask(const char *name) { + + char path[PATH_LEN]; + sprintf(path, "%s.mask", name); + + Common::SeekableReadStream *s = openArchivedFile(path, true); + s->seek(0x30, SEEK_SET); + + byte r, g, b; + for (uint i = 0; i < 4; i++) { + r = s->readByte(); + g = s->readByte(); + b = s->readByte(); + + _vm->_gfx->_bgLayers[i] = (((r << 4) & 0xF00) | (g & 0xF0) | (b >> 4)) & 0xFF; + +// printf("rgb = (%x, %x, %x) -> %x\n", r, g, b, _vm->_gfx->_bgLayers[i]); + } + + s->seek(0x126, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic - RLEStream *stream2 = new RLEStream(s); + Graphics::PackBitsReadStream stream(*s); + byte *buf = (byte*)malloc(SCREENMASK_WIDTH*SCREEN_HEIGHT); - stream2->read(buf, SCREENMASK_WIDTH*SCREEN_HEIGHT); + stream.read(buf, SCREENMASK_WIDTH*SCREEN_HEIGHT); buildMask(buf); _vm->_gfx->setMask(buf); free(buf); delete s; - delete stream2; - sprintf(path, "%s.path", background); - s = openArchivedFile(path, false); + return; +} + +void AmigaDisk::loadPath(const char *name) { + + char path[PATH_LEN]; + sprintf(path, "%s.path", name); + + Common::SeekableReadStream *s = openArchivedFile(path, false); if (s == NULL) return; // no errors if missing path files: not every location has one + s->seek(0x120, SEEK_SET); // HACK: skipping IFF/ILBM header should be done by analysis, not magic - stream2 = new RLEStream(s); - buf = (byte*)malloc(SCREENPATH_WIDTH*SCREEN_HEIGHT); - stream2->read(buf, SCREENPATH_WIDTH*SCREEN_HEIGHT); - setPath(buf); + + Graphics::PackBitsReadStream stream(*s); + byte *buf = (byte*)malloc(SCREENPATH_WIDTH*SCREEN_HEIGHT); + stream.read(buf, SCREENPATH_WIDTH*SCREEN_HEIGHT); + _vm->setPath(buf); free(buf); delete s; - delete stream2; + + return; +} + +void AmigaDisk::loadScenery(const char* background, const char* mask) { + debugC(1, kDebugDisk, "AmigaDisk::loadScenery '%s', '%s'", background, mask); + + char path[PATH_LEN]; + sprintf(path, "%s.bkgnd", background); + + loadBackground(path); + loadMask(background); + loadPath(background); return; } @@ -1141,5 +1120,18 @@ Table* AmigaDisk::loadTable(const char* name) { return t; } +Common::ReadStream* AmigaDisk::loadMusic(const char* name) { + return openArchivedFile(name); +} + +Common::ReadStream* AmigaDisk::loadSound(const char* name) { + char path[PATH_LEN]; + sprintf(path, "%s.snd", name); + + openArchivedFile(path); + + return new DummyArchiveStream(_resArchive); +} + } // namespace Parallaction diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h index 5e6233f3af..14c671b02b 100644 --- a/engines/parallaction/disk.h +++ b/engines/parallaction/disk.h @@ -26,6 +26,10 @@ #include "parallaction/defs.h" #include "common/file.h" +namespace Audio { + class AudioStream; +} + namespace Parallaction { //------------------------------------------------------ @@ -39,6 +43,7 @@ class Table; class Parallaction; class Gfx; class Script; +class Font; struct Cnv; struct StaticCnv; @@ -104,13 +109,14 @@ public: virtual Cnv* loadObjects(const char *name) = 0; virtual StaticCnv* loadPointer() = 0; virtual StaticCnv* loadHead(const char* name) = 0; - virtual Cnv* loadFont(const char* name) = 0; + virtual Font* loadFont(const char* name) = 0; virtual StaticCnv* loadStatic(const char* name) = 0; virtual Cnv* loadFrames(const char* name) = 0; virtual void loadSlide(const char *filename) = 0; virtual void loadScenery(const char* background, const char* mask) = 0; virtual Table* loadTable(const char* name) = 0; - + virtual Common::ReadStream* loadMusic(const char* name) = 0; + virtual Common::ReadStream* loadSound(const char* name) = 0; }; class DosDisk : public Disk { @@ -124,6 +130,7 @@ private: void loadMaskAndPath(const char *name); void parseDepths(Common::SeekableReadStream &stream); void parseBackground(Common::SeekableReadStream &stream); + Font *createFont(const char *name, Cnv* cnv); protected: Gfx *_gfx; @@ -138,12 +145,14 @@ public: Cnv* loadObjects(const char *name); StaticCnv* loadPointer(); StaticCnv* loadHead(const char* name); - Cnv* loadFont(const char* name); + Font* loadFont(const char* name); StaticCnv* loadStatic(const char* name); Cnv* loadFrames(const char* name); void loadSlide(const char *filename); void loadScenery(const char* background, const char* mask); Table* loadTable(const char* name); + Common::ReadStream* loadMusic(const char* name); + Common::ReadStream* loadSound(const char* name); }; class AmigaDisk : public Disk { @@ -153,6 +162,10 @@ protected: StaticCnv* makeStaticCnv(Common::SeekableReadStream &stream); void unpackBitmap(byte *dst, byte *src, uint16 numFrames, uint16 planeSize); Common::SeekableReadStream *openArchivedFile(const char* name, bool errorOnFileNotFound = false); + Font *createFont(const char *name, Common::SeekableReadStream &stream); + void loadMask(const char *name); + void loadPath(const char *name); + void loadBackground(const char *name); public: AmigaDisk(Parallaction *vm); @@ -164,12 +177,14 @@ public: Cnv* loadObjects(const char *name); StaticCnv* loadPointer(); StaticCnv* loadHead(const char* name); - Cnv* loadFont(const char* name); + Font* loadFont(const char* name); StaticCnv* loadStatic(const char* name); Cnv* loadFrames(const char* name); void loadSlide(const char *filename); void loadScenery(const char* background, const char* mask); Table* loadTable(const char* name); + Common::ReadStream* loadMusic(const char* name); + Common::ReadStream* loadSound(const char* name); }; } // namespace Parallaction diff --git a/engines/parallaction/font.cpp b/engines/parallaction/font.cpp new file mode 100644 index 0000000000..ad06b2000b --- /dev/null +++ b/engines/parallaction/font.cpp @@ -0,0 +1,447 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" +#include "common/stream.h" + +#include "parallaction/parallaction.h" + +namespace Parallaction { + + +extern byte _amigaTopazFont[]; + +class DosFont : public Font { + +protected: + // drawing properties + byte *_cp; + + Cnv *_data; + byte _pitch; + uint32 _bufPitch; + +protected: + virtual uint16 drawChar(char c) = 0; + virtual uint16 width(byte c) = 0; + virtual uint16 height() = 0; + + byte mapChar(byte c) { + if (c == 0xA5) return 0x5F; + if (c == 0xDF) return 0x60; + + if (c > 0x7F) return c - 0x7F; + + return c - 0x20; + } + +public: + DosFont(Cnv *cnv) : _data(cnv), _pitch(cnv->_width) { + } + + ~DosFont() { + if (_data) + delete _data; + } + + void setData() { + + } + + uint32 getStringWidth(const char *s) { + uint32 len = 0; + + while (*s) { + byte c = mapChar(*s); + len += width(c); + s++; + } + + return len; + } + + void drawString(byte* buffer, uint32 pitch, const char *s) { + if (s == NULL) + return; + + _bufPitch = pitch; + + _cp = buffer; + while (*s) { + byte c = mapChar(*s); + _cp += drawChar(c); + s++; + } + } +}; + +class DosDialogueFont : public DosFont { + +private: + static const byte _glyphWidths[126]; + +protected: + uint16 width(byte c) { + return _glyphWidths[c]; + } + + uint16 height() { + return _data->_height; + } + +public: + DosDialogueFont(Cnv *cnv) : DosFont(cnv) { + } + +protected: + uint16 drawChar(char c) { + + byte *src = _data->getFramePtr(c); + byte *dst = _cp; + uint16 w = width(c); + + for (uint16 j = 0; j < height(); j++) { + for (uint16 k = 0; k < w; k++) { + + if (!*src) + *dst = _color; + + dst++; + src++; + } + + src += (_pitch - w); + dst += (_bufPitch - w); + } + + return w; + + } + +}; + +const byte DosDialogueFont::_glyphWidths[126] = { + 0x04, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, 0x06, 0x03, 0x05, 0x03, 0x05, + 0x06, 0x06, 0x06, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x05, 0x04, 0x05, 0x05, + 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x07, 0x05, 0x06, 0x05, 0x08, 0x07, + 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x04, 0x05, 0x05, 0x06, 0x06, 0x05, + 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x05, 0x05, 0x05, 0x05, 0x02, 0x05, 0x05, 0x07, + 0x08, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, + 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, 0x05, 0x05, 0x05, 0x05 +}; + + +class DosMonospacedFont : public DosFont { + +protected: + uint16 _width; + +protected: + uint16 width(byte c) { + return _width; + } + + uint16 height() { + return _data->_height; + } + + +public: + DosMonospacedFont(Cnv *cnv) : DosFont(cnv) { + _width = 8; + } + +}; + +class DosMenuFont : public DosMonospacedFont { + +public: + DosMenuFont(Cnv *cnv) : DosMonospacedFont(cnv) { + } + +protected: + uint16 drawChar(char c) { + + byte *src = _data->getFramePtr(c); + byte *dst = _cp; + + for (uint16 i = 0; i < height(); i++) { + for (uint16 j = 0; j < _width; j++) { + if (*src) + *dst = *src; + src++; + dst++; + } + + dst += (_bufPitch - _width); + src += (_pitch - _width); + } + + return _width; + } + +}; + + +class DosLabelFont : public DosMonospacedFont { + +public: + DosLabelFont(Cnv *cnv) : DosMonospacedFont(cnv) { + } + +protected: + uint16 drawChar(char c) { + + byte *src = _data->getFramePtr(c); + byte *dst = _cp; + + for (uint16 i = 0; i < height(); i++) { + memcpy(dst, src, _width); + dst += _bufPitch; + src += _pitch; + } + + return _width; + } + +}; + +class AmigaFont : public Font { + +#include "common/pack-start.h" + struct CharLoc { + uint16 _offset; + uint16 _length; + }; + + struct AmigaDiskFont { + uint16 _ySize; + byte _style; + byte _flags; + uint16 _xSize; + uint16 _baseline; + uint16 _boldSmear; + uint16 _accessors; // unused + byte _loChar; + byte _hiChar; + uint32 _charData; + uint16 _modulo; + uint32 _charLoc; + uint32 _charSpace; + uint32 _charKern; + }; +#include "common/pack-end.h" + + AmigaDiskFont *_font; + uint32 _dataSize; + byte *_data; + byte *_charData; + CharLoc *_charLoc; + uint16 *_charSpace; + uint16 *_charKern; + + byte *_cp; + uint32 _pitch; + +protected: + uint16 getSpacing(byte c); + void blitData(byte c); + uint16 getKerning(byte c); + uint16 getPixels(byte c); + uint16 getOffset(byte c); + uint16 width(byte c); + uint16 height(); + + byte mapChar(byte c); + +public: + AmigaFont(Common::SeekableReadStream &stream); + ~AmigaFont(); + + uint32 getStringWidth(const char *s); + void drawString(byte *buf, uint32 pitch, const char *s); + + + +}; + +AmigaFont::AmigaFont(Common::SeekableReadStream &stream) { + stream.seek(32); // skips dummy header + + _dataSize = stream.size() - stream.pos(); + _data = (byte*)malloc(_dataSize); + stream.read(_data, _dataSize); + + _font = (AmigaDiskFont*)(_data + 78); + _font->_ySize = FROM_BE_16(_font->_ySize); + _font->_xSize = FROM_BE_16(_font->_xSize); + _font->_baseline = FROM_BE_16(_font->_baseline); + _font->_modulo = FROM_BE_16(_font->_modulo); + + _charLoc = (CharLoc*)(_data + FROM_BE_32(_font->_charLoc)); + _charData = _data + FROM_BE_32(_font->_charData); + + _charSpace = 0; + _charKern = 0; + + if (_font->_charSpace != 0) + _charSpace = (uint16*)(_data + FROM_BE_32(_font->_charSpace)); + if (_font->_charKern != 0) + _charKern = (uint16*)(_data + FROM_BE_32(_font->_charKern)); + +} + +AmigaFont::~AmigaFont() { + if (_data) + free(_data); +} + +uint16 AmigaFont::getSpacing(byte c) { + return (_charSpace == 0) ? _font->_xSize : FROM_BE_16(_charSpace[c]); +} + +uint16 AmigaFont::getKerning(byte c) { + return (_charKern == 0) ? 0 : FROM_BE_16(_charKern[c]); +} + +uint16 AmigaFont::getPixels(byte c) { + return FROM_BE_16(_charLoc[c]._length); +} + +uint16 AmigaFont::getOffset(byte c) { + return FROM_BE_16(_charLoc[c]._offset); +} + +void AmigaFont::blitData(byte c) { + + int num = getPixels(c); + int bitOffset = getOffset(c); + + byte *d = _cp; + byte *s = _charData; + + for (int i = 0; i < _font->_ySize; i++) { + + for (int j = bitOffset; j < bitOffset + num; j++) { + byte *b = s + (j >> 3); + byte bit = *b & (0x80 >> (j & 7)); + + if (bit) + *d = _color; + + d++; + } + + s += _font->_modulo; + d += _pitch - num; + } + +} + +uint16 AmigaFont::width(byte c) { +// printf("kern(%i) = %i, space(%i) = %i\t", c, getKerning(c), c, getSpacing(c)); + return getKerning(c) + getSpacing(c); +} + +uint16 AmigaFont::height() { + return _font->_ySize; +} + +byte AmigaFont::mapChar(byte c) { + + if (c < _font->_loChar || c > _font->_hiChar) + error("character '%c (%x)' not supported by font", c, c); + + return c - _font->_loChar; +} + +uint32 AmigaFont::getStringWidth(const char *s) { + uint32 len = 0; + + while (*s) { + byte c = mapChar(*s); + len += width(c); + s++; + } + + return len; +} + +void AmigaFont::drawString(byte *buffer, uint32 pitch, const char *s) { + + _cp = buffer; + _pitch = pitch; + + byte c; + + while (*s) { + c = mapChar(*s); + _cp += getKerning(c); + blitData(c); + _cp += getSpacing(c); + s++; + } + +} + +Font *DosDisk::createFont(const char *name, Cnv* cnv) { + Font *f = 0; + + if (!scumm_stricmp(name, "comic")) + f = new DosDialogueFont(cnv); + else + if (!scumm_stricmp(name, "topaz")) + f = new DosLabelFont(cnv); + else + if (!scumm_stricmp(name, "slide")) + f = new DosMenuFont(cnv); + else + error("unknown dos font '%s'", name); + + return f; +} + +Font *AmigaDisk::createFont(const char *name, Common::SeekableReadStream &stream) { + // TODO: implement AmigaLabelFont for labels + return new AmigaFont(stream); +} + +void Gfx::initFonts() { + + if (_vm->getPlatform() == Common::kPlatformPC) { + _fonts[kFontDialogue] = _vm->_disk->loadFont("comic"); + _fonts[kFontLabel] = _vm->_disk->loadFont("topaz"); + _fonts[kFontMenu] = _vm->_disk->loadFont("slide"); + } else { + _fonts[kFontDialogue] = _vm->_disk->loadFont("comic"); + + Common::MemoryReadStream stream(_amigaTopazFont, 2600, false); + _fonts[kFontLabel] = new AmigaFont(stream); + + _fonts[kFontMenu] = _vm->_disk->loadFont("slide"); + } + +} + +} diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 7d21c81a5a..e11edf06c0 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -24,32 +24,14 @@ #include "common/system.h" #include "common/file.h" -#include "parallaction/graphics.h" -#include "parallaction/parser.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/zone.h" + extern OSystem *g_system; namespace Parallaction { -// -// proportional font glyphs width -// -const byte _glyphWidths[126] = { - 0x04, 0x03, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x04, 0x04, 0x06, 0x06, 0x03, 0x05, 0x03, 0x05, - 0x06, 0x06, 0x06, 0x06, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x03, 0x03, 0x05, 0x04, 0x05, 0x05, - 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x07, 0x07, 0x07, 0x05, 0x06, 0x05, 0x08, 0x07, - 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x03, 0x04, 0x05, 0x05, 0x06, 0x06, 0x05, - 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x06, 0x07, 0x05, 0x05, 0x05, 0x05, 0x02, 0x05, 0x05, 0x07, - 0x08, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, - 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x06, 0x05, 0x05, 0x05, 0x05 -}; - -bool Gfx::_proportionalFont = false; byte * Gfx::_buffers[]; #define BALLOON_WIDTH 12 @@ -119,19 +101,44 @@ void Gfx::drawBalloon(const Common::Rect& r, uint16 winding) { void Gfx::setPalette(Palette pal, uint32 first, uint32 num) { // printf("setPalette(%i, %i)\n", first, num); - if (first + num > PALETTE_COLORS) + if (first + num > BASE_PALETTE_COLORS) error("wrong parameters for setPalette()"); - byte syspal[PALETTE_COLORS*4]; + byte sysBasePal[EHB_PALETTE_COLORS*4]; + byte sysExtraPal[BASE_PALETTE_COLORS*4]; + byte r, g, b; + uint32 j = 0; for (uint32 i = first; i < first+num; i++) { - syspal[i*4] = (pal[i*3] << 2) | (pal[i*3] >> 4); - syspal[i*4+1] = (pal[i*3+1] << 2) | (pal[i*3+1] >> 4); - syspal[i*4+2] = (pal[i*3+2] << 2) | (pal[i*3+2] >> 4); - syspal[i*4+3] = 0; + r = (pal[i*3] << 2) | (pal[i*3] >> 4); + g = (pal[i*3+1] << 2) | (pal[i*3+1] >> 4); + b = (pal[i*3+2] << 2) | (pal[i*3+2] >> 4); + + sysBasePal[j*4] = r; + sysBasePal[j*4+1] = g; + sysBasePal[j*4+2] = b; + sysBasePal[j*4+3] = 0; + + if (_vm->getPlatform() == Common::kPlatformAmiga) { + sysExtraPal[j*4] = r >> 1; + sysExtraPal[j*4+1] = g >> 1; + sysExtraPal[j*4+2] = b >> 1; + sysExtraPal[j*4+3] = 0; + } else { + sysExtraPal[j*4] = 0; + sysExtraPal[j*4+1] = 0; + sysExtraPal[j*4+2] = 0; + sysExtraPal[j*4+3] = 0; + } + + j++; } - g_system->setPalette(syspal, first, num); + g_system->setPalette(sysBasePal, first, num); + + if (_vm->getPlatform() == Common::kPlatformAmiga) + g_system->setPalette(sysExtraPal, first+FIRST_EHB_COLOR, num); + g_system->updateScreen(); return; @@ -197,7 +204,7 @@ void Gfx::animatePalette() { } void Gfx::fadePalette(Palette pal) { - for (uint16 i = 0; i < PALETTE_SIZE; i++) + for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) if (pal[i] < _palette[i]) pal[i]++; return; @@ -221,7 +228,7 @@ void Gfx::buildBWPalette(Palette pal) { void Gfx::quickFadePalette(Palette pal) { - for (uint16 i = 0; i < PALETTE_SIZE; i++) { + for (uint16 i = 0; i < BASE_PALETTE_COLORS * 3; i++) { if (pal[i] == _palette[i]) continue; pal[i] += (pal[i] < _palette[i] ? 4 : -4); } @@ -229,18 +236,22 @@ void Gfx::quickFadePalette(Palette pal) { return; } -void Gfx::extendPalette(Palette pal) { +void Gfx::setHalfbriteMode(bool enable) { +#ifdef HALFBRITE + if (_vm->getPlatform() != Common::kPlatformAmiga) return; + if (enable == _halfbrite) return; - for (uint16 i = 0; i < BASE_PALETTE_COLORS; i++) { - pal[(i+FIRST_EHB_COLOR)*3] = pal[i*3] / 2; - pal[(i+FIRST_EHB_COLOR)*3+1] = pal[i*3+1] / 2; - pal[(i+FIRST_EHB_COLOR)*3+2] = pal[i*3+2] / 2; - } - - setPalette(pal); -} + byte *buf = _buffers[kBitBack]; + for (uint32 i = 0; i < SCREEN_SIZE; i++) + *buf++ ^= 0x20; + buf = _buffers[kBitFront]; + for (uint32 i = 0; i < SCREEN_SIZE; i++) + *buf++ ^= 0x20; + _halfbrite = !_halfbrite; +#endif +} void Gfx::updateScreen() { // printf("Gfx::updateScreen()\n"); @@ -385,7 +396,7 @@ void Gfx::blit(const Common::Rect& r, uint16 z, byte *data, Gfx::Buffers buffer) void jobDisplayLabel(void *parm, Job *j) { Label *label = (Label*)parm; - debugC(1, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label); + debugC(9, kDebugJobs, "jobDisplayLabel (%p)", (const void*) label); if (label->_cnv._width == 0) return; @@ -397,7 +408,7 @@ void jobDisplayLabel(void *parm, Job *j) { void jobEraseLabel(void *parm, Job *j) { Label *label = (Label*)parm; - debugC(1, kDebugJobs, "jobEraseLabel (%p)", (const void*) label); + debugC(9, kDebugJobs, "jobEraseLabel (%p)", (const void*) label); int16 _si, _di; @@ -537,69 +548,54 @@ void Gfx::restoreZoneBackground(const Common::Rect& r, byte *data) { return; } +void Gfx::makeCnvFromString(StaticCnv *cnv, char *text) { + assert(_font == _fonts[kFontLabel]); + + if (_vm->getPlatform() == Common::kPlatformAmiga) { + cnv->_width = _font->getStringWidth(text) + 16; + cnv->_height = 10; + cnv->_data0 = (byte*)malloc(cnv->_width * cnv->_height); + memset(cnv->_data0, 0, cnv->_width * cnv->_height); + + _font->setColor(7); + _font->drawString(cnv->_data0 + 1, cnv->_width, text); + _font->drawString(cnv->_data0 + 1 + cnv->_width * 2, cnv->_width, text); + _font->drawString(cnv->_data0 + cnv->_width, cnv->_width, text); + _font->drawString(cnv->_data0 + 2 + cnv->_width, cnv->_width, text); + _font->setColor(1); + _font->drawString(cnv->_data0 + 1 + cnv->_width, cnv->_width, text); + } else { + cnv->_width = _font->getStringWidth(text); + cnv->_height = _font->height(); + cnv->_data0 = (byte*)malloc(cnv->_width * cnv->_height); + memset(cnv->_data0, 0, cnv->_width * cnv->_height); + _font->drawString(cnv->_data0, cnv->_width, text); + } +} -// -// strings -// void Gfx::displayString(uint16 x, uint16 y, const char *text) { - if (text == NULL) - return; - - uint16 len = strlen(text); - StaticCnv tmp; - - for (uint16 i = 0; i < len; i++) { - byte c = mapChar(text[i]); - - tmp._width = _font->_width; - tmp._height = _font->_height; - tmp._data0 = _font->getFramePtr(c); - - flatBlitCnv(&tmp, x, y, kBitFront); - - x += (_proportionalFont ? _glyphWidths[(int)c] : 8); + assert(_font == _fonts[kFontMenu]); - } - - return; + byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH; + _font->setColor(1); + _font->drawString(dst, SCREEN_WIDTH, text); } +void Gfx::displayCenteredString(uint16 y, const char *text) { + uint16 x = (SCREEN_WIDTH - getStringWidth(text)) / 2; + displayString(x, y, text); +} void Gfx::displayBalloonString(uint16 x, uint16 y, const char *text, byte color) { + assert(_font == _fonts[kFontDialogue]); - uint16 len = strlen(text); - - for (uint16 i = 0; i < len; i++) { - - byte c = mapChar(text[i]); - uint16 w = _proportionalFont ? _glyphWidths[(int)c] : 8; - byte *s = _font->getFramePtr(c); - byte *d = _buffers[kBitFront] + x + y*SCREEN_WIDTH; - -// printf("%i\n", text[i]); - - for (uint16 j = 0; j < _font->_height; j++) { - for (uint16 k = 0; k < w; k++) { - *d = (*s) ? 1 : color; - d++; - s++; - } - - s += (8 - w); - d += (SCREEN_WIDTH - w); - } - - x += w; - } - - updateScreen(); + byte *dst = _buffers[kBitFront] + x + y*SCREEN_WIDTH; - return; + _font->setColor(color); + _font->drawString(dst, SCREEN_WIDTH, text); } - - bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, byte color) { // printf("Gfx::displayWrappedString(%s, %i, %i, %i, %i)...", text, x, y, maxwidth, color); @@ -607,7 +603,6 @@ bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, bool rv = false; uint16 linewidth = 0; - _proportionalFont = true; uint16 rx = x + 10; uint16 ry = y + 4; @@ -646,37 +641,16 @@ bool Gfx::displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, } - - uint16 Gfx::getStringWidth(const char *text) { - if (text == NULL) return 0; - - uint16 len = strlen(text); - - if (_proportionalFont == 0) { - // fixed font - return len*8; - } - - // proportional font - uint16 w = 0; - for (uint16 i = 0; i < len; i++) { - byte c = mapChar(text[i]); - w += _glyphWidths[(int)c]; - } - - return w; + return _font->getStringWidth(text); } - void Gfx::getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height) { uint16 lines = 0; uint16 w = 0; *width = 0; - _proportionalFont = true; - char token[40]; while (strlen(text) != 0) { @@ -706,10 +680,9 @@ void Gfx::getStringExtent(char *text, uint16 maxwidth, int16* width, int16* heig } -void Gfx::setFont(const char* name) { - if (_font) delete _font; - - _font = _vm->_disk->loadFont(name); +void Gfx::setFont(Fonts name) { + assert(name < 3); + _font = _fonts[name]; } @@ -742,50 +715,6 @@ void Gfx::restoreBackground(const Common::Rect& r) { return; } - -void Gfx::makeCnvFromString(StaticCnv *cnv, char *text) { -// printf("makeCnvFromString('%s')\n", text); - - uint16 len = strlen(text); - - cnv->_width = _font->_width * len; - cnv->_height = _font->_height; - -// printf("%i x %i\n", cnv->_width, cnv->_height); - - cnv->_data0 = (byte*)malloc(cnv->_width * cnv->_height); - - for (uint16 i = 0; i < len; i++) { - byte c = mapChar(text[i]); - - byte *s = _font->getFramePtr(c); - byte *d = cnv->_data0 + _font->_width * i; - - for (uint16 j = 0; j < _font->_height; j++) { - memcpy(d, s, 8); - - s += 8; - d += cnv->_width; - } - } - - return; -} - -// -// internal character mapping -// -byte Gfx::mapChar(byte c) { - - if (c == 0xA5) return 0x5F; - if (c == 0xDF) return 0x60; - - if (c > 0x7F) return c - 0x7F; - - return c - 0x20; -} - - void Gfx::freeStaticCnv(StaticCnv *cnv) { // printf("free_static_cnv()\n"); @@ -842,7 +771,7 @@ void Gfx::grabRect(byte *dst, const Common::Rect& r, Gfx::Buffers srcbuffer, uin } -void Gfx::maskOpNot(uint16 x, uint16 y, uint16 unused) { +void Gfx::plotMaskPixel(uint16 x, uint16 y, byte color) { uint16 _ax = x + y * SCREEN_WIDTH; _buffers[kMask0][_ax >> 2] &= ~(3 << ((_ax & 3) << 1)); @@ -852,12 +781,12 @@ void Gfx::maskOpNot(uint16 x, uint16 y, uint16 unused) { -void Gfx::maskClearRectangle(const Common::Rect& r) { +void Gfx::fillMaskRect(const Common::Rect& r, byte color) { uint16 _di = r.left/4 + r.top*80; for (uint16 _si = r.top; _si < r.bottom; _si++) { - memset(&_buffers[kMask0][_di], 0, r.width()/4+1); + memset(&_buffers[kMask0][_di], color, r.width()/4+1); _di += 80; } @@ -897,9 +826,15 @@ Gfx::Gfx(Parallaction* vm) : setBlackPalette(); + _bgLayers[0] = _bgLayers[1] = _bgLayers[2] = _bgLayers[3] = 0; + + memset(_palette, 0, sizeof(_palette)); memset(_palettefx, 0, sizeof(_palettefx)); initMouse( 0 ); + initFonts(); + + _halfbrite = false; _font = NULL; @@ -913,8 +848,13 @@ Gfx::~Gfx() { free(_buffers[kBitBack]); free(_buffers[kBit2]); - if (_font) delete _font; + delete _fonts[kFontDialogue]; + delete _fonts[kFontLabel]; + delete _fonts[kFontMenu]; + freeStaticCnv(_mouseComposedArrow); + delete _mouseComposedArrow; + return; } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 893946ecc2..ff9fed4b32 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -68,6 +68,27 @@ struct PaletteFxRange { #include "common/pack-end.h" // END STRUCT PACKING +class Font { + +protected: + byte _color; + + +public: + Font() {} + virtual ~Font() {} + + virtual void setColor(byte color) { + _color = color; + } + virtual uint32 getStringWidth(const char *s) = 0; + virtual uint16 height() = 0; + + virtual void drawString(byte* buffer, uint32 pitch, const char *s) = 0; + + +}; + struct StaticCnv { uint16 _width; // uint16 _height; // @@ -117,6 +138,12 @@ class Parallaction; struct DoorData; struct GetData; +enum Fonts { + kFontDialogue = 0, + kFontLabel = 1, + kFontMenu = 2 +}; + class Gfx { public: @@ -137,6 +164,7 @@ public: void drawBalloon(const Common::Rect& r, uint16 arg_8); void displayBalloonString(uint16 x, uint16 y, const char *text, byte color); void displayString(uint16 x, uint16 y, const char *text); + void displayCenteredString(uint16 y, const char *text); bool displayWrappedString(char *text, uint16 x, uint16 y, uint16 maxwidth, byte color); uint16 getStringWidth(const char *text); void getStringExtent(char *text, uint16 maxwidth, int16* width, int16* height); @@ -156,8 +184,8 @@ public: void restoreBackground(const Common::Rect& r); // intro - void maskClearRectangle(const Common::Rect& r); - void maskOpNot(uint16 x, uint16 y, uint16 unused); + void fillMaskRect(const Common::Rect& r, byte color); + void plotMaskPixel(uint16 x, uint16 y, byte color); // low level void swapBuffers(); @@ -175,13 +203,15 @@ public: void blitCnv(StaticCnv *cnv, int16 x, int16 y, uint16 z, Gfx::Buffers buffer); // palette - void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = PALETTE_COLORS); + void setPalette(Palette palette, uint32 first = FIRST_BASE_COLOR, uint32 num = BASE_PALETTE_COLORS); void setBlackPalette(); void animatePalette(); void fadePalette(Palette palette); void buildBWPalette(Palette palette); void quickFadePalette(Palette palette); - void extendPalette(Palette palette); + + // amiga specific + void setHalfbriteMode(bool enable); // init Gfx(Parallaction* vm); @@ -189,11 +219,11 @@ public: void setMousePointer(int16 index); - void setFont(const char* name); + void initFonts(); + void setFont(Fonts name); public: Common::Point _labelPosition[2]; - static bool _proportionalFont; uint16 _bgLayers[4]; PaletteFxRange _palettefx[6]; Palette _palette; @@ -203,7 +233,9 @@ protected: static byte * _buffers[NUM_BUFFERS]; static byte _mouseArrow[256]; StaticCnv *_mouseComposedArrow; - Cnv *_font; + Font *_font; + Font *_fonts[3]; + bool _halfbrite; protected: byte mapChar(byte c); diff --git a/engines/parallaction/intro.cpp b/engines/parallaction/intro.cpp index 6995b41644..059555e862 100644 --- a/engines/parallaction/intro.cpp +++ b/engines/parallaction/intro.cpp @@ -24,9 +24,9 @@ #include "parallaction/parallaction.h" #include "parallaction/menu.h" -#include "parallaction/music.h" -#include "parallaction/graphics.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" + +#include "graphics/primitives.h" namespace Parallaction { @@ -123,10 +123,14 @@ static uint16 _rightHandPositions[684] = { extern Credit _credits[]; - void _c_startIntro(void *parm) { _rightHandAnim = _vm->findAnimation("righthand"); - _vm->_midiPlayer->play("intro"); + + if (_vm->getPlatform() == Common::kPlatformPC) { + _vm->_soundMan->setMusicFile("intro"); + _vm->_soundMan->playMusic(); + } + _engineFlags |= kEngineMouse; return; @@ -134,30 +138,40 @@ void _c_startIntro(void *parm) { void _c_endIntro(void *parm) { - _vm->_gfx->setFont("slide"); - _vm->_gfx->_proportionalFont = false; + _vm->_gfx->setFont(kFontMenu); + + debugC(1, kDebugLocation, "endIntro()"); - uint16 _di; - for (uint16 _si = 0; _si < 7; _si++) { - _di = _vm->_gfx->getStringWidth(_credits[_si]._role); - _vm->_gfx->displayString((SCREEN_WIDTH - _di)/2, 80, _credits[_si]._role); + for (uint16 _si = 0; _si < 6; _si++) { + _vm->_gfx->displayCenteredString(80, _credits[_si]._role); + _vm->_gfx->displayCenteredString(100, _credits[_si]._name); - _di = _vm->_gfx->getStringWidth(_credits[_si]._name); - _vm->_gfx->displayString((SCREEN_WIDTH - _di)/2, 100, _credits[_si]._name); + _vm->_gfx->updateScreen(); for (uint16 v2 = 0; v2 < 100; v2++) { + _mouseButtons = kMouseNone; _vm->updateInput(); - if (_mouseButtons != kMouseLeftUp) - _vm->waitTime( 1 ); + if (_mouseButtons == kMouseLeftUp) + break; + + _vm->waitTime( 1 ); } _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); } + debugC(1, kDebugLocation, "endIntro(): done showing credits"); - waitUntilLeftClick(); + if ((_vm->getFeatures() & GF_DEMO) == 0) { + _vm->_gfx->displayCenteredString(80, "CLICK MOUSE BUTTON TO START"); + _vm->_gfx->updateScreen(); - _engineFlags &= ~kEngineMouse; - _vm->_menu->selectCharacter(); + waitUntilLeftClick(); + + _engineFlags &= ~kEngineMouse; + _vm->_menu->selectCharacter(); + } else { + waitUntilLeftClick(); + } return; } @@ -190,133 +204,24 @@ void _c_moveSheet(void *parm) { return; } - -void introFunc1(uint16 oldX, uint16 oldY, uint16 newX, uint16 newY) { - - uint16 unused = 0; - int16 dx = newX - oldX; - int16 dy = newY - oldY; - - _vm->_gfx->maskOpNot(oldX, oldY, unused); - _vm->_gfx->maskOpNot(newX, newY, unused); - - if (abs(dx) >= abs(dy)) { - - int16 v4 = abs(dy); - if (dx >= 0 && dy >= 0) { - for (uint16 i = 1; i < dx; i++) { - v4 += dy; - if (abs(dx) < v4) { - oldY++; - v4 -= dx; - } - _vm->_gfx->maskOpNot(i + oldX, oldY, unused); - } - } - - if (dx < 0 && dy >= 0) { - for (uint16 i = 1; i > abs(dx); i++) { - v4 += dy; - if (abs(dx) < v4) { - oldY++; - v4 -= abs(dx); - } - _vm->_gfx->maskOpNot(oldX - i, oldY, unused); - } - } - - if (dx < 0 && dy < 0) { - for (uint16 i = 1; i > abs(dx); i++) { - v4 += dy; - if (abs(v4) > abs(dx)) { - oldY--; - v4 -= abs(dx); - } - _vm->_gfx->maskOpNot(oldX - i, oldY, unused); - } - } - - if (dx >= 0 && dy < 0) { - for (uint16 i = 1; i < dx; i++) { - v4 -= dy; - if (v4 > dx) { - oldY--; - v4 -= dx; - } - _vm->_gfx->maskOpNot(i + oldX, oldY, unused); - } - } - - } - - if (abs(dy) < abs(dx)) { - - int16 v4 = abs(dx); - - if (dx >= 0 && dy >= 0) { - for (uint16 i = 1; i < dy; i++) { - v4 += dx; - if (v4 > dy) { - oldX++; - v4 -= dy; - } - _vm->_gfx->maskOpNot(oldX, i + oldY, unused); - } - } - - if (dx < 0 && dy >= 0) { - for (uint16 i = 1; i < dy; i++) { - v4 -= dx; - if (v4 > dy) { - oldX--; - v4 -= dy; - } - _vm->_gfx->maskOpNot(oldX, i + oldY, unused); - } - } - - if (dx < 0 && dy < 0) { - for (uint16 i = 1; i < abs(dy); i++) { - v4 -= abs(dx); - if (v4 > abs(dy)) { - oldX--; - v4 -= abs(dy); - } - _vm->_gfx->maskOpNot(oldX, oldY - i, unused); - } - } - - if (dx >= 0 && dy < 0) { - for (uint16 i = 1; i < abs(dy); i++) { - v4 += abs(dx); - if (v4 > abs(dy)) { - oldX++; - v4 -= abs(dy); - } - _vm->_gfx->maskOpNot(oldX, oldY - i, unused); - } - } - - } - - - return; +void plotPixel(int x, int y, int color, void *data) { + _vm->_gfx->plotMaskPixel(x, y, color); } - void _c_sketch(void *parm) { static uint16 index = 1; - uint16 _4 = _rightHandPositions[2*index+1]; - uint16 _3 = _rightHandPositions[2*index]; - uint16 _2 = _rightHandPositions[2*(index-1)+1]; - uint16 _1 = _rightHandPositions[2*(index-1)]; + uint16 newy = _rightHandPositions[2*index+1]; + uint16 newx = _rightHandPositions[2*index]; - introFunc1(_1, _2, _3, _4); + uint16 oldy = _rightHandPositions[2*(index-1)+1]; + uint16 oldx = _rightHandPositions[2*(index-1)]; - _rightHandAnim->_left = _rightHandPositions[index*2]; - _rightHandAnim->_top = _rightHandPositions[index*2+1] - 20; + Graphics::drawLine(oldx, oldy, newx, newy, 0, plotPixel, NULL); + + _rightHandAnim->_left = newx; + _rightHandAnim->_top = newy - 20; index++; @@ -335,10 +240,78 @@ void _c_shade(void *parm) { _rightHandAnim->_top ); - _vm->_gfx->maskClearRectangle(r); + _vm->_gfx->fillMaskRect(r, 0); return; } +void _c_projector(void*) { +#ifdef HALFBRITE + static int dword_16032 = 0; + +// Bitmap bm; +// InitBitMap(&bm); + + if (dword_16032 != 0) { +/* // keep drawing spotlight in its final place + _vm->_gfx->flatBlitCnv(&scnv, 110, 25, Gfx::kBitFront); + BltBitMap(&bm, 0, 0, &_screen._bitMap, 110, 25, a3->??, a3->??, 0x20, 0x20); +*/ return; + } + + _vm->_gfx->setHalfbriteMode(true); +/* + // move spot light around the stage + int d7, d6; + for (d7 = 0; d7 < 150; d7++) { + + if (d7 < 100) { + int d1 = d7; + if (d1 < 0) + d1++; + + d1 >>= 1; + d6 = 50 - d1; + } else { + int d1 = d7 / 100; + if (d1 < 0) + d1++; + + d1 >>= 1; + d6 = d1; + } + + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0x20, 0x20); + sub_1590C(d6 + a3->??); + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+20, d6, a3->??, a3->??, 0xFA, 0x20); + } + + for (d7 = 50; d7 > -10; d7--) { + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); + sub_1590C(d6 + a3->??); + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0xFA, 0x20); + } + + BltBitMap(&bm, 0, 0, &_screen._bitMap, d7+120, d6, a3->??, a3->??, 0x20, 0x20); + _vm->_gfx->flatBlitCnv(&scnv, d7+120, d6, Gfx::kBitFront); +*/ + + dword_16032 = 1; + return; +#endif +} + +void _c_HBOff(void*) { +#ifdef HALFBRITE + _vm->_gfx->setHalfbriteMode(false); +#endif +} + +void _c_HBOn(void*) { +#ifdef HALFBRITE + _vm->_gfx->setHalfbriteMode(true); +#endif +} + } // namespace Parallaction diff --git a/engines/parallaction/inventory.cpp b/engines/parallaction/inventory.cpp index 0e6a003b23..52dbd50db0 100644 --- a/engines/parallaction/inventory.cpp +++ b/engines/parallaction/inventory.cpp @@ -23,10 +23,7 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/zone.h" -#include "parallaction/graphics.h" -#include "parallaction/inventory.h" + namespace Parallaction { @@ -40,6 +37,7 @@ namespace Parallaction { // #define INVENTORY_MAX_ITEMS 30 +#define INVENTORY_FIRST_ITEM 4 // first four entries are used up by verbs #define INVENTORYITEM_PITCH 32 #define INVENTORYITEM_WIDTH 24 @@ -96,72 +94,67 @@ void drawInventoryItem(uint16 pos, InventoryItem *item); // int16 Parallaction::getHoverInventoryItem(int16 x, int16 y) { - int16 _di = x; - - int16 _si = -1; + int16 slot = -1; do { - _si++; - } while (_inventory[_si]._id != 0); + slot++; + } while (_inventory[slot]._id != 0); - _si = (_si + 4) / INVENTORY_ITEMS_PER_LINE; + slot = (slot + 4) / INVENTORY_ITEMS_PER_LINE; - if (_invPosition.x >= _di) return -1; - if ((_invPosition.x + INVENTORY_WIDTH) <= _di) return -1; + if (_invPosition.x >= x) return -1; + if ((_invPosition.x + INVENTORY_WIDTH) <= x) return -1; if (_invPosition.y >= y) return -1; - if ((_si * INVENTORYITEM_HEIGHT + _invPosition.y) <= y) return -1; + if ((slot * INVENTORYITEM_HEIGHT + _invPosition.y) <= y) return -1; - return ((_di - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT)); + return ((x - _invPosition.x) / INVENTORYITEM_WIDTH) + (INVENTORY_ITEMS_PER_LINE * ((y - _invPosition.y) / INVENTORYITEM_HEIGHT)); } -int16 Parallaction::pickupItem(Zone *z) { - - uint16 _si; - for (_si = 0; _inventory[_si]._id != 0; _si++) ; - if (_si == INVENTORY_MAX_ITEMS) - return -1; - - _inventory[_si]._id = MAKE_INVENTORY_ID(z->u.get->_icon); - _inventory[_si]._index = z->u.get->_icon; - - addJob(&jobRemovePickedItem, z, kPriority17 ); - - if (_inventory[_si]._id == 0) return 0; +void refreshInventory(const char *character) { + for (uint16 i = 0; i < INVENTORY_MAX_ITEMS; i++) { + drawInventoryItem(i, &_inventory[i]); + } + return; +} - refreshInventoryItem(_characterName, _si); - return 0; +void refreshInventoryItem(const char *character, uint16 index) { + drawInventoryItem(index, &_inventory[index]); + return; } +int Parallaction::addInventoryItem(uint16 item) { -void Parallaction::addInventoryItem(uint16 item) { + uint16 slot = 0; + while (_inventory[slot]._id != 0) + slot++; - uint16 _si = 0; - while (_inventory[_si]._id != 0) _si++; + if (slot == INVENTORY_MAX_ITEMS) + return -1; - _inventory[_si]._id = MAKE_INVENTORY_ID(item); - _inventory[_si]._index = item; + _inventory[slot]._id = MAKE_INVENTORY_ID(item); + _inventory[slot]._index = item; - refreshInventoryItem(_characterName, _si); + refreshInventoryItem(_characterName, slot); - return; + return 0; } void Parallaction::dropItem(uint16 v) { - uint16 _di = 0; - for (uint16 _si = 0; _si < INVENTORY_MAX_ITEMS - 1; _si++) { + bool found = false; + for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS - 1; slot++) { - if (v + 4 == _inventory[_si]._index) { - _di = 1; + if (v + INVENTORY_FIRST_ITEM == _inventory[slot]._index) { + found = true; } - if (_di == 0) continue; + if (!found) continue; - memcpy(&_inventory[_si], &_inventory[_si+1], sizeof(InventoryItem)); + memcpy(&_inventory[slot], &_inventory[slot+1], sizeof(InventoryItem)); } refreshInventory(_characterName); @@ -172,8 +165,8 @@ void Parallaction::dropItem(uint16 v) { int16 Parallaction::isItemInInventory(int32 v) { - for (uint16 _si = 0; _si < INVENTORY_MAX_ITEMS; _si++) { - if (_inventory[_si]._id == (uint)v) + for (uint16 slot = 0; slot < INVENTORY_MAX_ITEMS; slot++) { + if (_inventory[slot]._id == (uint)v) return 1; } @@ -182,6 +175,9 @@ int16 Parallaction::isItemInInventory(int32 v) { + + + void drawInventoryItem(uint16 pos, InventoryItem *item) { uint16 line = pos / INVENTORY_ITEMS_PER_LINE; @@ -263,12 +259,11 @@ void jobShowInventory(void *parm, Job *j) { // printf("job_showInventory()..."); _numInvLines = 0; - while (_inventory[_numInvLines]._id != 0) _numInvLines++; - _numInvLines = (_numInvLines + 4) / INVENTORY_ITEMS_PER_LINE; Common::Rect r(INVENTORY_WIDTH, _numInvLines * INVENTORYITEM_HEIGHT); + r.moveTo(_invPosition); _vm->_gfx->copyRect( @@ -308,14 +303,13 @@ void jobHideInventory(void *parm, Job *j) { void openInventory() { -// printf("openInventory()\n"); - - uint16 _si = 0; _engineFlags |= kEngineInventory; - while (_inventory[_si]._id != 0) _si++; + uint16 slot = 0; + while (_inventory[slot]._id != 0) + slot++; - uint16 _LOCALinventory_lines = (_si + 4) / INVENTORY_ITEMS_PER_LINE; + uint16 lines = (slot + 4) / INVENTORY_ITEMS_PER_LINE; _invPosition.x = _vm->_mousePos.x - (INVENTORY_WIDTH / 2); if (_invPosition.x < 0) @@ -324,12 +318,12 @@ void openInventory() { if ((_invPosition.x + INVENTORY_WIDTH) > SCREEN_WIDTH) _invPosition.x = SCREEN_WIDTH - INVENTORY_WIDTH; - _invPosition.y = _vm->_mousePos.y - 2 - (_LOCALinventory_lines * INVENTORYITEM_HEIGHT); + _invPosition.y = _vm->_mousePos.y - 2 - (lines * INVENTORYITEM_HEIGHT); if (_invPosition.y < 0) _invPosition.y = 0; - if (_invPosition.y > SCREEN_HEIGHT - _LOCALinventory_lines * INVENTORYITEM_HEIGHT) - _invPosition.y = SCREEN_HEIGHT - _LOCALinventory_lines * INVENTORYITEM_HEIGHT; + if (_invPosition.y > SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT) + _invPosition.y = SCREEN_HEIGHT - lines * INVENTORYITEM_HEIGHT; return; @@ -338,53 +332,28 @@ void openInventory() { void closeInventory() { -// printf("closeInventory()\n"); - _engineFlags &= ~kEngineInventory; } - - -// refreshes inventory view -// -void redrawInventory() { - - - for (uint16 _si = 0; _si < INVENTORY_MAX_ITEMS; _si++) { - drawInventoryItem(_si, &_inventory[_si]); - } - -} - void initInventory() { - _buffer = (byte*)malloc(INVENTORY_WIDTH * INVENTORY_HEIGHT); // this buffer is also used by menu so it must stay this size + _buffer = (byte*)malloc(INVENTORY_WIDTH * INVENTORY_HEIGHT); +} +void destroyInventory() { + if (_buffer) + free(_buffer); + _buffer = 0; } void cleanInventory() { - for (uint16 _si = 4; _si < 30; _si++) { - _inventory[_si]._id = 0; - _inventory[_si]._index = 0; + for (uint16 slot = INVENTORY_FIRST_ITEM; slot < INVENTORY_MAX_ITEMS; slot++) { + _inventory[slot]._id = 0; + _inventory[slot]._index = 0; } return; } - - -void refreshInventory(const char *character) { - redrawInventory(); - - return; -} - - -void refreshInventoryItem(const char *character, uint16 index) { - drawInventoryItem(index, &_inventory[index]); - - return; -} - } // namespace Parallaction diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h index 8adf546529..36ea39ed03 100644 --- a/engines/parallaction/inventory.h +++ b/engines/parallaction/inventory.h @@ -41,15 +41,14 @@ struct InventoryItem { extern InventoryItem _inventory[]; void initInventory(); +void destroyInventory(); void openInventory(); void closeInventory(); int16 isItemInInventory(int32 v); void cleanInventory(); void addInventoryItem(uint16 item); -void redrawInventory(); void highlightInventoryItem(int16 pos, byte color); -void refreshInventoryItem(const char *character, uint16 index); void refreshInventory(const char *character); void extractInventoryGraphics(int16 pos, byte *dst); diff --git a/engines/parallaction/location.cpp b/engines/parallaction/location.cpp index 8066c65afd..012e351ab5 100644 --- a/engines/parallaction/location.cpp +++ b/engines/parallaction/location.cpp @@ -23,34 +23,21 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/disk.h" -#include "parallaction/parser.h" -#include "parallaction/music.h" -#include "parallaction/commands.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" namespace Parallaction { -void resolveLocationForwards(); -void switchBackground(const char* background, const char* mask); - - void Parallaction::parseLocation(const char *filename) { -// printf("parseLocation(%s)", filename); debugC(1, kDebugLocation, "parseLocation('%s')", filename); uint16 _si = 1; - _gfx->_proportionalFont = false; - _gfx->setFont("topaz"); + _gfx->setFont(kFontLabel); Script *_locationScript = _disk->loadLocation(filename); fillBuffers(*_locationScript, true); while (scumm_stricmp(_tokens[0], "ENDLOCATION")) { -// printf("token[0] = %s", _tokens[0]); if (!scumm_stricmp(_tokens[0], "LOCATION")) { // The parameter for location is 'location.mask'. @@ -135,6 +122,7 @@ void Parallaction::parseLocation(const char *filename) { } if (!scumm_stricmp(_tokens[0], "COMMENT")) { _location._comment = parseComment(*_locationScript); + debugC(3, kDebugLocation, "Location comment: '%s'", _location._comment); } if (!scumm_stricmp(_tokens[0], "ENDCOMMENT")) { _location._endComment = parseComment(*_locationScript); @@ -151,6 +139,14 @@ void Parallaction::parseLocation(const char *filename) { if (!scumm_stricmp(_tokens[0], "SOUND")) { strcpy(_soundFile, _tokens[1]); } + if (!scumm_stricmp(_tokens[0], "MUSIC")) { + if (getPlatform() == Common::kPlatformAmiga) + _soundMan->setMusicFile(_tokens[1]); + } + if (!scumm_stricmp(_tokens[0], "SOUND")) { +// if (getPlatform() == Common::kPlatformAmiga) +// _soundMan->loadSfx(_tokens[1], atoi(_tokens[2])); + } fillBuffers(*_locationScript, true); } @@ -162,8 +158,6 @@ void Parallaction::parseLocation(const char *filename) { } void Parallaction::resolveLocationForwards() { -// printf("resolveLocationForwards()"); -// printf("# forwards: %i", _numForwards); for (uint16 _si = 0; _forwardedCommands[_si]; _si++) { _forwardedCommands[_si]->u._animation = findAnimation(_forwardedAnimationNames[_si]); @@ -178,36 +172,36 @@ void Parallaction::resolveLocationForwards() { void Parallaction::freeLocation() { debugC(7, kDebugLocation, "freeLocation"); + _soundMan->stopSfx(0); + _soundMan->stopSfx(1); + _soundMan->stopSfx(2); + _soundMan->stopSfx(3); + if (_localFlagNames) delete _localFlagNames; - _localFlagNames = new Table(120); - _localFlagNames->addData("visited"); - - debugC(7, kDebugLocation, "freeLocation: localflags names freed"); - + + // HACK: prevents leakage. A routine like this + // should allocate memory at all, though. + if ((_engineFlags & kEngineQuit) == 0) { + _localFlagNames = new Table(120); + _localFlagNames->addData("visited"); + } + _location._walkNodes.clear(); - debugC(7, kDebugLocation, "freeLocation: walk nodes freed"); // TODO (LIST): helperNode should be rendered useless by the use of a Common::List<> // to store Zones and Animations. Right now, it holds a list of Zones to be preserved // but that'll pretty meaningless with a single list approach. freeZones(); - debugC(7, kDebugLocation, "freeLocation: zones freed"); - freeAnimations(); - debugC(7, kDebugLocation, "freeLocation: animations freed"); if (_location._comment) { free(_location._comment); } _location._comment = NULL; - debugC(7, kDebugLocation, "freeLocation: comments freed"); _location._commands.clear(); - debugC(7, kDebugLocation, "freeLocation: commands freed"); - _location._aCommands.clear(); - debugC(7, kDebugLocation, "freeLocation: acommands freed"); return; } @@ -252,7 +246,7 @@ void Parallaction::switchBackground(const char* background, const char* mask) { _si += 3; } - _gfx->extendPalette(pal); + _gfx->setPalette(pal); } _disk->loadScenery(background, mask); @@ -267,18 +261,15 @@ extern Job *_jEraseLabel; void Parallaction::showSlide(const char *name) { _disk->loadSlide(name); - _gfx->extendPalette(_gfx->_palette); + _gfx->setPalette(_gfx->_palette); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); debugC(1, kDebugLocation, "changeLocation: new background set"); - _gfx->_proportionalFont = false; - _gfx->setFont("slide"); + _gfx->setFont(kFontMenu); - uint16 _ax = strlen(_slideText[0]); - _ax <<= 3; // text width - uint16 _dx = (SCREEN_WIDTH - _ax) >> 1; // center text - _gfx->displayString(_dx, 14, _slideText[0]); // displays text on screen + _gfx->displayCenteredString(14, _slideText[0]); // displays text on screen + _gfx->updateScreen(); waitUntilLeftClick(); @@ -306,9 +297,9 @@ void Parallaction::showSlide(const char *name) { is commented out, and would definitely crash the current implementation. */ void Parallaction::changeLocation(char *location) { - debugC(1, kDebugLocation, "changeLocation to '%s'", location); + debugC(1, kDebugLocation, "changeLocation(%s)", location); - pickMusic(location); + _soundMan->playLocationMusic(location); // WORKAROUND: this if-statement has been added to avoid crashes caused by // execution of label jobs after a location switch. The other workaround in @@ -324,15 +315,11 @@ void Parallaction::changeLocation(char *location) { _hoverZone = NULL; if (_engineFlags & kEngineMouse) { changeCursor( kCursorArrow ); - debugC(2, kDebugLocation, "changeLocation: changed cursor"); } _animations.remove(&_char._ani); - debugC(2, kDebugLocation, "changeLocation: removed character from the animation list"); freeLocation(); - debugC(1, kDebugLocation, "changeLocation: old location free'd"); - char buf[100]; strcpy(buf, location); @@ -361,14 +348,10 @@ void Parallaction::changeLocation(char *location) { } _animations.push_front(&_char._ani); - debugC(2, kDebugLocation, "changeLocation: new character added to the animation list"); strcpy(_saveData1, list[0].c_str()); parseLocation(list[0].c_str()); - _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); - debugC(1, kDebugLocation, "changeLocation: new location '%s' parsed", _saveData1); - _char._ani._oldPos.x = -1000; _char._ani._oldPos.y = -1000; @@ -379,14 +362,12 @@ void Parallaction::changeLocation(char *location) { _char._ani._frame = _location._startFrame; _location._startPosition.y = -1000; _location._startPosition.x = -1000; - - debugC(2, kDebugLocation, "changeLocation: initial position set to x: %i, y: %i, f: %i", _location._startPosition.x, _location._startPosition.y, _location._startFrame); } - byte palette[PALETTE_SIZE]; - for (uint16 _si = 0; _si < PALETTE_SIZE; _si++) palette[_si] = 0; - _gfx->extendPalette(palette); + _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + _gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); + _gfx->setBlackPalette(); if (_location._commands.size() > 0) { runCommands(_location._commands); @@ -395,22 +376,22 @@ void Parallaction::changeLocation(char *location) { runJobs(); _gfx->swapBuffers(); } - + if (_location._comment) { doLocationEnterTransition(); - debugC(2, kDebugLocation, "changeLocation: shown location comment"); } - + runJobs(); _gfx->swapBuffers(); - _gfx->extendPalette(_gfx->_palette); + _gfx->setPalette(_gfx->_palette); if (_location._aCommands.size() > 0) { runCommands(_location._aCommands); - debugC(1, kDebugLocation, "changeLocation: location acommands run"); } - debugC(1, kDebugLocation, "changeLocation completed"); +// _soundMan->playSfx(0); + + debugC(1, kDebugLocation, "changeLocation() done"); return; @@ -428,46 +409,43 @@ void Parallaction::changeLocation(char *location) { void Parallaction::doLocationEnterTransition() { debugC(1, kDebugLocation, "doLocationEnterTransition"); - if (_localFlags[_currentLocationIndex] & kFlagsVisited) return; // visited - + if (_localFlags[_currentLocationIndex] & kFlagsVisited) { + debugC(3, kDebugLocation, "skipping location transition"); + return; // visited + } + byte pal[PALETTE_SIZE]; _gfx->buildBWPalette(pal); - _gfx->setPalette(pal, FIRST_BASE_COLOR, BASE_PALETTE_COLORS); + _gfx->setPalette(pal); jobRunScripts(NULL, NULL); jobEraseAnimations(NULL, NULL); jobDisplayAnimations(NULL, NULL); - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); _gfx->swapBuffers(); _gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - int16 v7C, v7A; - _gfx->getStringExtent(_location._comment, 130, &v7C, &v7A); + int16 w, h; + _gfx->getStringExtent(_location._comment, 130, &w, &h); - Common::Rect r(10 + v7C, 5 + v7A); + Common::Rect r(10 + w, 5 + h); r.moveTo(5, 5); _gfx->floodFill(Gfx::kBitFront, r, 0); r.grow(-1); _gfx->floodFill(Gfx::kBitFront, r, 1); _gfx->displayWrappedString(_location._comment, 3, 5, 130, 0); - // FIXME: ??? -#if 0 - do { - mouseFunc1(); - } while (_mouseButtons != kMouseLeftUp); -#endif - + _gfx->updateScreen(); waitUntilLeftClick(); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront ); // fades maximum intensity palette towards approximation of main palette for (uint16 _si = 0; _si<6; _si++) { - waitTime( 1 ); _gfx->quickFadePalette(pal); _gfx->setPalette(pal); + waitTime( 1 ); } debugC(1, kDebugLocation, "doLocationEnterTransition completed"); @@ -475,8 +453,4 @@ void Parallaction::doLocationEnterTransition() { return; } -void mouseFunc1() { - // FIXME: implement this -} - } // namespace Parallaction diff --git a/engines/parallaction/menu.cpp b/engines/parallaction/menu.cpp index 6ae01a2774..ecd5f0157e 100644 --- a/engines/parallaction/menu.cpp +++ b/engines/parallaction/menu.cpp @@ -23,11 +23,9 @@ #include "common/stdafx.h" #include "common/system.h" -#include "parallaction/menu.h" -#include "parallaction/disk.h" -#include "parallaction/music.h" -#include "parallaction/graphics.h" #include "parallaction/parallaction.h" +#include "parallaction/menu.h" +#include "parallaction/sound.h" namespace Parallaction { @@ -94,6 +92,7 @@ static uint16 _doughKey[] = { 1, 7 ,7, 2, 2, 6 }; Menu::Menu(Parallaction *vm) { _vm = vm; + } Menu::~Menu() { @@ -105,68 +104,55 @@ void Menu::start() { _vm->_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0"); - _vm->_gfx->_proportionalFont = false; - _vm->_gfx->setFont("slide"); + splash(); + + _language = chooseLanguage(); + _vm->_disk->setLanguage(_language); + + int game = selectGame(); + if (game == 0) + newGame(); + + return; +} + +void Menu::splash() { _vm->_disk->loadSlide("intro"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - g_system->delayMillis(2000); _vm->_disk->loadSlide("minintro"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - g_system->delayMillis(2000); - if (_vm->getPlatform() == Common::kPlatformPC) { - - _vm->_disk->loadSlide("lingua"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); - - _vm->_gfx->displayString(60, 30, "SELECT LANGUAGE"); - - _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); - _language = chooseLanguage(); - - _vm->_disk->setLanguage(_language); - - if (selectGame() == 0) { - newGame(); - } - } else { - _vm->_disk->setLanguage(1); - } - - return; } void Menu::newGame() { + if (_vm->getFeatures() & GF_DEMO) { + // character screen is not shown on demo + // so user warps to the playable intro + strcpy(_vm->_location._name, "fognedemo"); + return; + } + const char **v14 = introMsg3; _vm->_disk->loadScenery("test", NULL); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->swapBuffers(); - uint16 _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[0])) / 2; - _vm->_gfx->displayString(_ax, 50, v14[0]); - - _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[1])) / 2; - _vm->_gfx->displayString(_ax, 70, v14[1]); - - _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[2])) / 2; - _vm->_gfx->displayString(_ax, 100, v14[2]); - - _ax = (SCREEN_WIDTH - _vm->_gfx->getStringWidth(v14[3])) / 2; - _vm->_gfx->displayString(_ax, 120, v14[3]); + _vm->_gfx->displayCenteredString(50, v14[0]); + _vm->_gfx->displayCenteredString(70, v14[1]); + _vm->_gfx->displayCenteredString(100, v14[2]); + _vm->_gfx->displayCenteredString(120, v14[3]); + _vm->_gfx->updateScreen(); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); - _mouseButtons = kMouseNone; for (; _mouseButtons != kMouseLeftUp; ) { @@ -174,8 +160,10 @@ void Menu::newGame() { if (_mouseButtons == kMouseRightUp) break; } - if (_mouseButtons != kMouseRightUp) + if (_mouseButtons != kMouseRightUp) { + strcpy(_vm->_location._name, "fogne"); return; // show intro + } selectCharacter(); @@ -187,6 +175,25 @@ void Menu::newGame() { uint16 Menu::chooseLanguage() { + if (_vm->getPlatform() == Common::kPlatformAmiga) { + // TODO: should return the language ID supported by this version + // this can be done with some flags in the detection structures + return 1; + } + + // user can choose language in dos version + + _vm->_gfx->setFont(kFontMenu); + + _vm->_disk->loadSlide("lingua"); + _vm->_gfx->setPalette(_vm->_gfx->_palette); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); + + _vm->_gfx->displayString(60, 30, "SELECT LANGUAGE"); + + _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); + _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); + _vm->changeCursor(kCursorArrow); do { @@ -220,9 +227,12 @@ uint16 Menu::chooseLanguage() { uint16 Menu::selectGame() { // printf("selectGame()\n"); + if (_vm->getFeatures() & GF_DEMO) { + return 0; // can't load a savegame in demo versions + } _vm->_disk->loadSlide("restore"); - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); @@ -255,6 +265,7 @@ uint16 Menu::selectGame() { _vm->_gfx->displayString(60, 30, newGameMsg[_language]); } + _vm->_gfx->updateScreen(); _vm->_gfx->copyScreen(Gfx::kBitFront, Gfx::kBitBack); } @@ -263,6 +274,11 @@ uint16 Menu::selectGame() { // load game + // TODO: allow the user to change her mind in this screen, that is + // don't force her to start at the intro when she closes her load + // game window without picking a savegame. + // The 2 strcpy's below act as workaround to prevent crashes for + // time being. strcpy(_vm->_location._name, "fogne"); strcpy(_vm->_characterName, "dough"); @@ -276,6 +292,7 @@ uint16 Menu::selectGame() { // character selection and protection // void Menu::selectCharacter() { + debugC(1, kDebugMenu, "Menu::selectCharacter()"); uint16 _di = 0; bool askPassword = true; @@ -291,10 +308,9 @@ void Menu::selectCharacter() { v14._height = BLOCK_HEIGHT; _vm->changeCursor(kCursorArrow); - _vm->_midiPlayer->stop(); + _vm->_soundMan->stopMusic(); - _vm->_gfx->_proportionalFont = false; - _vm->_gfx->setFont("slide"); + _vm->_gfx->setFont(kFontMenu); _vm->_disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0"); @@ -302,7 +318,7 @@ void Menu::selectCharacter() { _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); // _vm->_gfx->copyScreen(Gfx::kBitBack, Gfx::kBit2); // - _vm->_gfx->extendPalette(_vm->_gfx->_palette); + _vm->_gfx->setPalette(_vm->_gfx->_palette); while (askPassword == true) { @@ -359,6 +375,7 @@ void Menu::selectCharacter() { _vm->_gfx->copyScreen(Gfx::kBit2, Gfx::kBitFront); _vm->_gfx->displayString(60, 30, introMsg2[_language]); + _vm->_gfx->updateScreen(); g_system->delayMillis(2000); diff --git a/engines/parallaction/menu.h b/engines/parallaction/menu.h index 666305e693..8f9c870a84 100644 --- a/engines/parallaction/menu.h +++ b/engines/parallaction/menu.h @@ -41,6 +41,7 @@ public: void selectCharacter(); protected: + void splash(); void newGame(); uint16 chooseLanguage(); uint16 selectGame(); diff --git a/engines/parallaction/module.mk b/engines/parallaction/module.mk index b95cfb7c30..592c0cb6a3 100644 --- a/engines/parallaction/module.mk +++ b/engines/parallaction/module.mk @@ -9,15 +9,16 @@ MODULE_OBJS := \ detection.o \ dialogue.o \ disk.o \ + font.o \ graphics.o \ intro.o \ inventory.o \ location.o \ menu.o \ - music.o \ parser.o \ parallaction.o \ saveload.o \ + sound.o \ staticres.o \ walk.o \ zone.o diff --git a/engines/parallaction/music.cpp b/engines/parallaction/music.cpp deleted file mode 100644 index b203b453be..0000000000 --- a/engines/parallaction/music.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/file.h" -#include "parallaction/parallaction.h" - -#include "common/stream.h" - -#include "sound/midiparser.h" - -#include "parallaction/music.h" - - -namespace Parallaction { - -MidiPlayer::MidiPlayer(MidiDriver *driver) - : _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) { - assert(_driver); - memset(_channelsTable, 0, sizeof(_channelsTable)); - memset(_channelsVolume, 0, sizeof(_channelsVolume)); - - open(); -} - -MidiPlayer::~MidiPlayer() { - close(); -} - -void MidiPlayer::play(const char *filename) { - stop(); - - if (!scumm_strnicmp(_vm->_location._name, "museo", 5)) return; - if (!scumm_strnicmp(_vm->_location._name, "intgrottadopo", 13)) return; - if (!scumm_strnicmp(_vm->_location._name, "caveau", 6)) return; - if (!scumm_strnicmp(_vm->_location._name, "estgrotta", 9)) return; - if (!scumm_strnicmp(_vm->_location._name, "plaza1", 6)) return; - if (!scumm_strnicmp(_vm->_location._name, "endtgz", 6)) return; - - char path[PATH_LEN]; - sprintf(path, "%s.mid", filename); - - Common::File stream; - - if (!stream.open(path)) - return; - - int size = stream.size(); - - _midiData = (uint8 *)malloc(size); - if (_midiData) { - stream.read(_midiData, size); - _mutex.lock(); - _parser->loadMusic(_midiData, size); - _parser->setTrack(0); - _isLooping = true; - _isPlaying = true; - _mutex.unlock(); - } -} - -void MidiPlayer::stop() { - _mutex.lock(); - if (_isPlaying) { - _isPlaying = false; - _parser->unloadMusic(); - free(_midiData); - _midiData = 0; - } - _mutex.unlock(); -} - -void MidiPlayer::updateTimer() { - _mutex.lock(); - if (_isPlaying) { - _parser->onTimer(); - } - _mutex.unlock(); -} - -void MidiPlayer::adjustVolume(int diff) { - setVolume(_masterVolume + diff); -} - -void MidiPlayer::setVolume(int volume) { - _masterVolume = CLIP(volume, 0, 255); - _mutex.lock(); - for (int i = 0; i < NUM_CHANNELS; ++i) { - if (_channelsTable[i]) { - _channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255); - } - } - _mutex.unlock(); -} - -int MidiPlayer::open() { - int ret = _driver->open(); - if (ret == 0) { - _parser = MidiParser::createParser_SMF(); - _parser->setMidiDriver(this); - _parser->setTimerRate(_driver->getBaseTempo()); - _driver->setTimerCallback(this, &timerCallback); - } - return ret; -} - -void MidiPlayer::close() { - stop(); - _mutex.lock(); - _driver->setTimerCallback(NULL, NULL); - _driver->close(); - _driver = 0; - _parser->setMidiDriver(NULL); - delete _parser; - _mutex.unlock(); -} - -void MidiPlayer::send(uint32 b) { - byte volume, ch = (byte)(b & 0xF); - switch (b & 0xFFF0) { - case 0x07B0: // volume change - volume = (byte)((b >> 16) & 0x7F); - _channelsVolume[ch] = volume; - volume = volume * _masterVolume / 255; - b = (b & 0xFF00FFFF) | (volume << 16); - break; - case 0x7BB0: // all notes off - if (!_channelsTable[ch]) { - // channel not yet allocated, no need to send the event - return; - } - break; - } - - if (!_channelsTable[ch]) { - _channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); - } - if (_channelsTable[ch]) { - _channelsTable[ch]->send(b); - } -} - -void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) { - switch (type) { - case 0x2F: // end of Track - if (_isLooping) { - _parser->jumpToTick(0); - } else { - stop(); - } - break; - default: -// warning("Unhandled meta event: %02x", type); - break; - } -} - -void MidiPlayer::timerCallback(void *p) { - MidiPlayer *player = (MidiPlayer *)p; - - player->updateTimer(); -} - -} // namespace Parallaction diff --git a/engines/parallaction/music.h b/engines/parallaction/music.h deleted file mode 100644 index eef249a7d4..0000000000 --- a/engines/parallaction/music.h +++ /dev/null @@ -1,80 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef PARALLACTION_MUSIC_H -#define PARALLACTION_MUSIC_H - -#include "common/util.h" -#include "common/mutex.h" - -#include "sound/mididrv.h" - -class MidiParser; - -namespace Parallaction { - -class MidiPlayer : public MidiDriver { -public: - - enum { - NUM_CHANNELS = 16 - }; - - MidiPlayer(MidiDriver *driver); - ~MidiPlayer(); - - void play(const char *filename); - void stop(); - void updateTimer(); - void adjustVolume(int diff); - void setVolume(int volume); - int getVolume() const { return _masterVolume; } - void setLooping(bool loop) { _isLooping = loop; } - - // MidiDriver interface - int open(); - void close(); - void send(uint32 b); - void metaEvent(byte type, byte *data, uint16 length); - void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } - uint32 getBaseTempo() { return _driver ? _driver->getBaseTempo() : 0; } - MidiChannel *allocateChannel() { return 0; } - MidiChannel *getPercussionChannel() { return 0; } - -private: - - static void timerCallback(void *p); - - MidiDriver *_driver; - MidiParser *_parser; - uint8 *_midiData; - bool _isLooping; - bool _isPlaying; - int _masterVolume; - MidiChannel *_channelsTable[NUM_CHANNELS]; - uint8 _channelsVolume[NUM_CHANNELS]; - Common::Mutex _mutex; -}; - -} // namespace Parallaction - -#endif diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 490ca38e31..1cf285ba57 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -31,14 +31,10 @@ #include "sound/mixer.h" #include "parallaction/parallaction.h" +#include "parallaction/debug.h" #include "parallaction/menu.h" -#include "parallaction/parser.h" -#include "parallaction/disk.h" -#include "parallaction/music.h" -#include "parallaction/inventory.h" -#include "parallaction/graphics.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" + namespace Parallaction { @@ -119,12 +115,15 @@ Parallaction::Parallaction(OSystem *syst) : Common::addSpecialDebugLevel(kDebugGraphics, "gfx", "Gfx debug level"); Common::addSpecialDebugLevel(kDebugJobs, "jobs", "Jobs debug level"); Common::addSpecialDebugLevel(kDebugInput, "input", "Input debug level"); - + Common::addSpecialDebugLevel(kDebugAudio, "audio", "Audio debug level"); + Common::addSpecialDebugLevel(kDebugMenu, "menu", "Menu debug level"); } Parallaction::~Parallaction() { - delete _midiPlayer; + delete _debugger; + + delete _soundMan; delete _disk; delete _globalTable; @@ -139,6 +138,12 @@ Parallaction::~Parallaction() { if (_localFlagNames) delete _localFlagNames; + + delete _gfx; + + freeLocation(); + freeCharacter(); + destroyInventory(); } @@ -163,17 +168,19 @@ int Parallaction::init() { _activeItem._id = 0; _procCurrentHoverItem = -1; - _musicData1 = 0; +// _musicData1 = 0; strcpy(_characterName1, "null"); - _midiPlayer = 0; + _soundMan = 0; _baseTime = 0; if (getPlatform() == Common::kPlatformPC) _disk = new DosDisk(this); - else + else { _disk = new AmigaDisk(this); + _disk->selectArchive("disk0"); + } _engineFlags = 0; @@ -186,11 +193,6 @@ int Parallaction::init() { _location._startPosition.y = -1000; _location._startFrame = 0; - if (getFeatures() & GF_DEMO) - strcpy(_location._name, "fognedemo"); - else - strcpy(_location._name, "fogne"); - _location._comment = NULL; _location._endComment = NULL; @@ -201,11 +203,16 @@ int Parallaction::init() { _animations.push_front(&_vm->_char._ani); _gfx = new Gfx(this); - int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); - MidiDriver *driver = MidiDriver::createMidi(midiDriver); - _midiPlayer = new MidiPlayer(driver); + if (getPlatform() == Common::kPlatformPC) { + int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); + MidiDriver *driver = MidiDriver::createMidi(midiDriver); + _soundMan = new DosSoundMan(this, driver); + _soundMan->setMusicVolume(ConfMan.getInt("music_volume")); + } else { + _soundMan = new AmigaSoundMan(this); + } - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + _debugger = new Debugger(this); return 0; } @@ -276,6 +283,8 @@ uint16 Parallaction::updateInput() { case Common::EVENT_KEYDOWN: if (e.kbd.ascii == 'l') KeyDown = kEvLoadGame; if (e.kbd.ascii == 's') KeyDown = kEvSaveGame; + if (e.kbd.flags == Common::KBD_CTRL && e.kbd.keycode == 'd') + _debugger->attach(); break; case Common::EVENT_LBUTTONDOWN: @@ -299,7 +308,7 @@ uint16 Parallaction::updateInput() { break; case Common::EVENT_QUIT: - _system->quit(); + _engineFlags |= kEngineQuit; break; default: @@ -309,6 +318,9 @@ uint16 Parallaction::updateInput() { } + if (_debugger->isAttached()) + _debugger->onFrame(); + return KeyDown; } @@ -326,7 +338,7 @@ void waitUntilLeftClick() { break; if (e.type == Common::EVENT_QUIT) { - g_system->quit(); + _engineFlags |= kEngineQuit; break; } @@ -349,8 +361,6 @@ void Parallaction::runGame() { if (_location._commands.size() > 0) runCommands(_location._commands); - runJobs(); - _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); if (_location._comment) @@ -694,6 +704,7 @@ void Parallaction::changeCursor(int32 index) { void Parallaction::freeCharacter() { + debugC(3, kDebugLocation, "freeCharacter()"); if (!IS_DUMMY_CHARACTER(_vm->_characterName)) { if (_objectsNames) @@ -702,66 +713,27 @@ void Parallaction::freeCharacter() { if (_vm->_char._ani._cnv) delete _vm->_char._ani._cnv; + _vm->_char._ani._cnv = NULL; if (_vm->_char._talk) delete _vm->_char._talk; + _vm->_char._talk = NULL; _vm->_gfx->freeStaticCnv(_vm->_char._head); if (_vm->_char._head) delete _vm->_char._head; + _vm->_char._head = NULL; if (_vm->_char._objs) delete _vm->_char._objs; + _vm->_char._objs = NULL; } return; } -void Parallaction::selectCharacterMusic(const char *name) { - if (IS_MINI_CHARACTER(name)) - name+=4; - - if (!scumm_stricmp(name, _dinoName)) { - _midiPlayer->play("dino"); - } else if (!scumm_stricmp(name, _donnaName)) { - _midiPlayer->play("donna"); - } else { - _midiPlayer->play("nuts"); - } - - return; -} - -void Parallaction::pickMusic(const char *location) { - if (_musicData1 != 0) { - selectCharacterMusic(_vm->_characterName); - _musicData1 = 0; - debugC(2, kDebugLocation, "changeLocation: started character specific music"); - } - - if (!scumm_stricmp(location, "night") || !scumm_stricmp(location, "intsushi")) { - _vm->_midiPlayer->play("soft"); - - debugC(2, kDebugLocation, "changeLocation: started music 'soft'"); - } - - if (!scumm_stricmp(location, "museo") || - !scumm_stricmp(location, "caveau") || - !scumm_strnicmp(location, "plaza1", 6) || - !scumm_stricmp(location, "estgrotta") || - !scumm_stricmp(location, "intgrottadopo") || - !scumm_stricmp(location, "endtgz") || - !scumm_stricmp(location, "common")) { - - _vm->_midiPlayer->stop(); - _musicData1 = 1; - - debugC(2, kDebugLocation, "changeLocation: music stopped"); - } -} - - void Parallaction::changeCharacter(const char *name) { + debugC(1, kDebugLocation, "changeCharacter(%s)", name); char baseName[20]; if (IS_MINI_CHARACTER(name)) { @@ -782,6 +754,7 @@ void Parallaction::changeCharacter(const char *name) { freeCharacter(); _disk->selectArchive((_vm->getPlatform() == Common::kPlatformPC) ? "disk1" : "disk0"); + _vm->_char._ani._cnv = _disk->loadFrames(fullName); if (!IS_DUMMY_CHARACTER(name)) { _vm->_char._head = _disk->loadHead(baseName); @@ -790,18 +763,17 @@ void Parallaction::changeCharacter(const char *name) { _objectsNames = _disk->loadTable(baseName); refreshInventory(baseName); - _vm->_char._ani._cnv = _disk->loadFrames(fullName); + _soundMan->playCharacterMusic(name); - if (scumm_stricmp(name, "night") && scumm_stricmp(name, "intsushi")) - selectCharacterMusic(name); + if ((getFeatures() & GF_DEMO) == 0) + parseLocation("common"); } } - if (!(getFeatures() & GF_DEMO)) - parseLocation("common"); - strcpy(_characterName1, fullName); + debugC(1, kDebugLocation, "changeCharacter() done"); + return; } @@ -810,11 +782,11 @@ void Parallaction::changeCharacter(const char *name) { (higher priorities values comes first in the list) */ int compareJobPriority(const JobPointer &j1, const JobPointer &j2) { - if (j1->_tag == j2->_tag) return 0; return (j1->_tag >= j2->_tag ? -1 : 1); } Job *Parallaction::addJob(JobFn fn, void *parm, uint16 tag) { + debugC(3, kDebugJobs, "addJob(%i)", tag); Job *v8 = new Job; @@ -830,16 +802,22 @@ Job *Parallaction::addJob(JobFn fn, void *parm, uint16 tag) { } void Parallaction::removeJob(Job *j) { + debugC(3, kDebugJobs, "addJob(%i)", j->_tag); + j->_finished = 1; return; } void Parallaction::pauseJobs() { + debugC(3, kDebugJobs, "pausing jobs execution"); + _engineFlags |= kEnginePauseJobs; return; } void Parallaction::resumeJobs() { + debugC(3, kDebugJobs, "resuming jobs execution"); + _engineFlags &= ~kEnginePauseJobs; return; } @@ -858,7 +836,7 @@ void Parallaction::runJobs() { it = _jobs.begin(); while (it != _jobs.end()) { - debugC(3, kDebugJobs, "runJobs: %i", (*it)->_tag); + debugC(9, kDebugJobs, "runJobs: %i", (*it)->_tag); (*(*it)->_fn)((*it)->_parm, (*it)); it++; } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 0a63ee9380..6a64ced769 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -51,7 +51,9 @@ enum { kDebugDialogue = 1 << 3, kDebugGraphics = 1 << 4, kDebugJobs = 1 << 5, - kDebugInput = 1 << 6 + kDebugInput = 1 << 6, + kDebugAudio = 1 << 7, + kDebugMenu = 1 << 8 }; enum { @@ -196,8 +198,6 @@ extern const char *_minidrkiName; #define IS_MINI_CHARACTER(s) (((s)[0] == 'm')) #define IS_DUMMY_CHARACTER(s) (((s)[0] == 'D')) -#define PATH_LEN 200 - void waitUntilLeftClick(); @@ -216,9 +216,10 @@ void jobEraseLabel(void *parm, Job *j); +class Debugger; class Gfx; class Menu; -class MidiPlayer; +class SoundMan; @@ -283,6 +284,7 @@ public: class Parallaction : public Engine { + friend class Debugger; public: @@ -313,6 +315,11 @@ public: void resumeJobs(); void runJobs(); + void setPath(byte *path); + void finalizeWalk(WalkNodeList *list); + int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from); + void clipMove(Common::Point& pos, const WalkNode* from); + Zone *findZone(const char *name); Zone *hitZone(uint32 type, uint16 x, uint16 y); uint16 runZone(Zone*); @@ -347,8 +354,7 @@ private: const PARALLACTIONGameDescription *_gameDescription; public: - - MidiPlayer *_midiPlayer; + SoundMan *_soundMan; Gfx* _gfx; Menu* _menu; @@ -371,6 +377,8 @@ public: protected: // data + Debugger *_debugger; + struct InputData { uint16 _event; Common::Point _mousePos; @@ -391,35 +399,32 @@ protected: // data int16 _transCurrentHoverItem; uint32 _baseTime; - - uint16 _musicData1; // only used in changeLocation char _characterName1[50]; // only used in changeCharacter int16 _keyDown; JobList _jobs; + Common::String _saveFileName; + + protected: // members bool detectGame(void); void initGame(); void initGlobals(); - - Common::String _saveFileName; - int buildSaveFileList(Common::StringList& l); - int selectSaveFile(uint16 arg_0, const char* caption, const char* button); - void doLoadGame(uint16 slot); - void doSaveGame(uint16 slot, const char* name); - + void initResources(); void runGame(); + uint32 getElapsedTime(); + void resetTimer(); InputData *translateInput(); void processInput(InputData*); - int16 getHoverInventoryItem(int16 x, int16 y); - - uint32 getElapsedTime(); - void resetTimer(); + int buildSaveFileList(Common::StringList& l); + int selectSaveFile(uint16 arg_0, const char* caption, const char* button); + void doLoadGame(uint16 slot); + void doSaveGame(uint16 slot, const char* name); void doLocationEnterTransition(); void changeLocation(char *location); @@ -430,10 +435,13 @@ protected: // members void parseZone(Script &script, ZoneList &list, char *name); void parseZoneTypeBlock(Script &script, Zone *z); - void parseWalkNodes(Script& script, WalkNodeList &list); void displayCharacterComment(ExamineData *data); void displayItemComment(ExamineData *data); + void parseWalkNodes(Script& script, WalkNodeList &list); + void initWalk(); + uint16 checkDoor(); + Animation * parseAnimation(Script &script, AnimationList &list, char *name); void parseScriptLine(Instruction *inst, Animation *a, LocalVariable *locals); void loadProgram(Animation *a, char *filename); @@ -441,13 +449,8 @@ protected: // members void parseCommands(Script &script, CommandList&); - void pickMusic(const char *location); - void selectCharacterMusic(const char *name); - void freeCharacter(); - void initResources(); - uint16 askDialoguePassword(Dialogue *q, StaticCnv *face); bool displayAnswer(Dialogue *q, uint16 i); bool displayAnswers(Dialogue *q); @@ -457,10 +460,11 @@ protected: // members void enterDialogue(); void exitDialogue(); - void addInventoryItem(uint16 item); + int addInventoryItem(uint16 item); void dropItem(uint16 item); int16 pickupItem(Zone *z); int16 isItemInInventory(int32 v); + int16 getHoverInventoryItem(int16 x, int16 y); }; // FIXME: remove global diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp index 45b19544a3..f913e4abd0 100644 --- a/engines/parallaction/parser.cpp +++ b/engines/parallaction/parser.cpp @@ -20,10 +20,10 @@ * */ -#include "parallaction/defs.h" -#include "parallaction/parser.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/disk.h" + namespace Parallaction { diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index a6a2019743..e5a2577ca2 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -29,7 +29,6 @@ namespace Parallaction { -char *parseNextLine(char *s, uint16 count); uint16 fillBuffers(Common::SeekableReadStream &stream, bool errorOnEOF = false); char *parseNextToken(char *s, char *tok, uint16 count, const char *brk); diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index db1cd636b0..251f35a24e 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -28,9 +28,7 @@ #include "gui/message.h" #include "parallaction/parallaction.h" -#include "parallaction/disk.h" -#include "parallaction/graphics.h" -#include "parallaction/zone.h" + /* Nippon Safes savefiles are called 'game.0' to 'game.9'. The game conventiently allows users to * give meanigful name to savegames, and it uses an extra file 'savegame' to keep track of these diff --git a/engines/parallaction/sound.cpp b/engines/parallaction/sound.cpp new file mode 100644 index 0000000000..fec03e9291 --- /dev/null +++ b/engines/parallaction/sound.cpp @@ -0,0 +1,418 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/file.h" + +#include "common/stream.h" + +#include "sound/mixer.h" +#include "sound/midiparser.h" +#include "sound/mods/protracker.h" + +#include "parallaction/sound.h" +#include "parallaction/parallaction.h" + + +namespace Parallaction { + +class MidiPlayer : public MidiDriver { +public: + + enum { + NUM_CHANNELS = 16 + }; + + MidiPlayer(MidiDriver *driver); + ~MidiPlayer(); + + void play(const char *filename); + void stop(); + void updateTimer(); + void adjustVolume(int diff); + void setVolume(int volume); + int getVolume() const { return _masterVolume; } + void setLooping(bool loop) { _isLooping = loop; } + + // MidiDriver interface + int open(); + void close(); + void send(uint32 b); + void metaEvent(byte type, byte *data, uint16 length); + void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { } + uint32 getBaseTempo() { return _driver ? _driver->getBaseTempo() : 0; } + MidiChannel *allocateChannel() { return 0; } + MidiChannel *getPercussionChannel() { return 0; } + +private: + + static void timerCallback(void *p); + + MidiDriver *_driver; + MidiParser *_parser; + uint8 *_midiData; + bool _isLooping; + bool _isPlaying; + int _masterVolume; + MidiChannel *_channelsTable[NUM_CHANNELS]; + uint8 _channelsVolume[NUM_CHANNELS]; + Common::Mutex _mutex; +}; + +MidiPlayer::MidiPlayer(MidiDriver *driver) + : _driver(driver), _parser(0), _midiData(0), _isLooping(false), _isPlaying(false), _masterVolume(0) { + assert(_driver); + memset(_channelsTable, 0, sizeof(_channelsTable)); + memset(_channelsVolume, 0, sizeof(_channelsVolume)); + + open(); +} + +MidiPlayer::~MidiPlayer() { + close(); +} + +void MidiPlayer::play(const char *filename) { + stop(); + + if (!scumm_strnicmp(_vm->_location._name, "museo", 5)) return; + if (!scumm_strnicmp(_vm->_location._name, "intgrottadopo", 13)) return; + if (!scumm_strnicmp(_vm->_location._name, "caveau", 6)) return; + if (!scumm_strnicmp(_vm->_location._name, "estgrotta", 9)) return; + if (!scumm_strnicmp(_vm->_location._name, "plaza1", 6)) return; + if (!scumm_strnicmp(_vm->_location._name, "endtgz", 6)) return; + + char path[PATH_LEN]; + sprintf(path, "%s.mid", filename); + + Common::File stream; + + if (!stream.open(path)) + return; + + int size = stream.size(); + + _midiData = (uint8 *)malloc(size); + if (_midiData) { + stream.read(_midiData, size); + _mutex.lock(); + _parser->loadMusic(_midiData, size); + _parser->setTrack(0); + _isLooping = true; + _isPlaying = true; + _mutex.unlock(); + } +} + +void MidiPlayer::stop() { + _mutex.lock(); + if (_isPlaying) { + _isPlaying = false; + _parser->unloadMusic(); + free(_midiData); + _midiData = 0; + } + _mutex.unlock(); +} + +void MidiPlayer::updateTimer() { + _mutex.lock(); + if (_isPlaying) { + _parser->onTimer(); + } + _mutex.unlock(); +} + +void MidiPlayer::adjustVolume(int diff) { + setVolume(_masterVolume + diff); +} + +void MidiPlayer::setVolume(int volume) { + _masterVolume = CLIP(volume, 0, 255); + _mutex.lock(); + for (int i = 0; i < NUM_CHANNELS; ++i) { + if (_channelsTable[i]) { + _channelsTable[i]->volume(_channelsVolume[i] * _masterVolume / 255); + } + } + _mutex.unlock(); +} + +int MidiPlayer::open() { + int ret = _driver->open(); + if (ret == 0) { + _parser = MidiParser::createParser_SMF(); + _parser->setMidiDriver(this); + _parser->setTimerRate(_driver->getBaseTempo()); + _driver->setTimerCallback(this, &timerCallback); + } + return ret; +} + +void MidiPlayer::close() { + stop(); + _mutex.lock(); + _driver->setTimerCallback(NULL, NULL); + _driver->close(); + _driver = 0; + _parser->setMidiDriver(NULL); + delete _parser; + _mutex.unlock(); +} + +void MidiPlayer::send(uint32 b) { + byte volume, ch = (byte)(b & 0xF); + switch (b & 0xFFF0) { + case 0x07B0: // volume change + volume = (byte)((b >> 16) & 0x7F); + _channelsVolume[ch] = volume; + volume = volume * _masterVolume / 255; + b = (b & 0xFF00FFFF) | (volume << 16); + break; + case 0x7BB0: // all notes off + if (!_channelsTable[ch]) { + // channel not yet allocated, no need to send the event + return; + } + break; + } + + if (!_channelsTable[ch]) { + _channelsTable[ch] = (ch == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel(); + } + if (_channelsTable[ch]) { + _channelsTable[ch]->send(b); + } +} + +void MidiPlayer::metaEvent(byte type, byte *data, uint16 length) { + switch (type) { + case 0x2F: // end of Track + if (_isLooping) { + _parser->jumpToTick(0); + } else { + stop(); + } + break; + default: +// warning("Unhandled meta event: %02x", type); + break; + } +} + +void MidiPlayer::timerCallback(void *p) { + MidiPlayer *player = (MidiPlayer *)p; + + player->updateTimer(); +} + + +DosSoundMan::DosSoundMan(Parallaction *vm, MidiDriver *midiDriver) : SoundMan(vm), _musicData1(0) { + _midiPlayer = new MidiPlayer(midiDriver); +} + +DosSoundMan::~DosSoundMan() { + debugC(1, kDebugAudio, "DosSoundMan::playMusic()"); + + delete _midiPlayer; +} + +void DosSoundMan::playMusic() { + debugC(1, kDebugAudio, "DosSoundMan::playMusic()"); + + _midiPlayer->play(_musicFile); +} + +void DosSoundMan::stopMusic() { + _midiPlayer->stop(); +} + +void DosSoundMan::playCharacterMusic(const char *character) { + + if (!scumm_stricmp(_vm->_location._name, "night") || + !scumm_stricmp(_vm->_location._name, "intsushi")) { + return; + } + + char *name = const_cast<char*>(character); + + if (IS_MINI_CHARACTER(name)) + name+=4; + + if (!scumm_stricmp(name, _dinoName)) { + setMusicFile("dino"); + } else + if (!scumm_stricmp(name, _donnaName)) { + setMusicFile("dough"); + } else + if (!scumm_stricmp(name, _doughName)) { + setMusicFile("nuts"); + } else { + warning("unknown character '%s' in DosSoundMan::playCharacterMusic", character); + return; + } + + playMusic(); +} + +void DosSoundMan::playLocationMusic(const char *location) { + if (_musicData1 != 0) { + playCharacterMusic(_vm->_characterName); + _musicData1 = 0; + debugC(2, kDebugLocation, "changeLocation: started character specific music"); + } + + if (!scumm_stricmp(location, "night") || !scumm_stricmp(location, "intsushi")) { + setMusicFile("nuts"); + playMusic(); + + debugC(2, kDebugLocation, "changeLocation: started music 'soft'"); + } + + if (!scumm_stricmp(location, "museo") || + !scumm_stricmp(location, "caveau") || + !scumm_strnicmp(location, "plaza1", 6) || + !scumm_stricmp(location, "estgrotta") || + !scumm_stricmp(location, "intgrottadopo") || + !scumm_stricmp(location, "endtgz") || + !scumm_stricmp(location, "common")) { + + stopMusic(); + _musicData1 = 1; + + debugC(2, kDebugLocation, "changeLocation: music stopped"); + } +} + +AmigaSoundMan::AmigaSoundMan(Parallaction *vm) : SoundMan(vm) { + _musicStream = 0; + _channels[0].data = 0; + _channels[1].data = 0; + _channels[2].data = 0; + _channels[3].data = 0; +} + +AmigaSoundMan::~AmigaSoundMan() { + stopMusic(); + stopSfx(0); + stopSfx(1); + stopSfx(2); + stopSfx(3); +} + +void AmigaSoundMan::playSfx(const char *filename, uint channel, bool looping, int volume, int rate) { + if (channel >= NUM_AMIGA_CHANNELS) { + warning("unknown sfx channel"); + return; + } + + debugC(1, kDebugAudio, "AmigaSoundMan::playSfx(%s, %i)", filename, channel); + + Channel *ch = &_channels[channel]; + Common::ReadStream *stream = _vm->_disk->loadSound(filename); + Audio::A8SVXDecoder decoder(*stream, ch->header, ch->data, ch->dataSize); + decoder.decode(); + delete stream; + + uint32 loopStart, loopEnd, flags; + if (looping) { + // the standard way to loop 8SVX audio implies use of the oneShotHiSamples and + // repeatHiSamples fields, but Nippon Safes handles loops according to flags + // set in its location scripts and always operates on the whole data. + loopStart = 0; + loopEnd = ch->header.oneShotHiSamples + ch->header.repeatHiSamples; + flags = Audio::Mixer::FLAG_LOOP; + } else { + loopStart = loopEnd = 0; + flags = 0; + } + + if (volume == -1) { + volume = ch->header.volume; + } + + if (rate == -1) { + rate = ch->header.samplesPerSec; + } + + _mixer->playRaw(Audio::Mixer::kSFXSoundType, &ch->handle, ch->data, ch->dataSize, rate, flags, -1, volume, 0, loopStart, loopEnd); +} + +void AmigaSoundMan::stopSfx(uint channel) { + if (channel >= NUM_AMIGA_CHANNELS) { + warning("unknown sfx channel"); + return; + } + + if (_channels[channel].data) { + debugC(1, kDebugAudio, "AmigaSoundMan::stopSfx(%i)", channel); + _mixer->stopHandle(_channels[channel].handle); + free(_channels[channel].data); + _channels[channel].data = 0; + } +} + +void AmigaSoundMan::playMusic() { + stopMusic(); + + debugC(1, kDebugAudio, "AmigaSoundMan::playMusic()"); + + Common::ReadStream *stream = _vm->_disk->loadMusic(_musicFile); + _musicStream = Audio::makeProtrackerStream(stream); + delete stream; + + debugC(3, kDebugAudio, "AmigaSoundMan::playMusic(): created new music stream"); + + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, _musicStream, -1, 255, 0, false, false); +} + +void AmigaSoundMan::stopMusic() { + debugC(1, kDebugAudio, "AmigaSoundMan::stopMusic()"); + + if (_mixer->isSoundHandleActive(_musicHandle)) { + _mixer->stopHandle(_musicHandle); + delete _musicStream; + _musicStream = 0; + } +} + +void AmigaSoundMan::playCharacterMusic(const char *character) { +} + +void AmigaSoundMan::playLocationMusic(const char *location) { +} + + +SoundMan::SoundMan(Parallaction *vm) : _vm(vm) { + _mixer = _vm->_mixer; +} + +void SoundMan::setMusicVolume(int value) { + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, value); +} + +void SoundMan::setMusicFile(const char *filename) { + strcpy(_musicFile, filename); +} + + +} // namespace Parallaction diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h new file mode 100644 index 0000000000..ae2f9c8716 --- /dev/null +++ b/engines/parallaction/sound.h @@ -0,0 +1,110 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef PARALLACTION_MUSIC_H +#define PARALLACTION_MUSIC_H + +#include "common/util.h" +#include "common/mutex.h" + +#include "sound/audiostream.h" +#include "sound/iff.h" +#include "sound/mixer.h" +#include "sound/mididrv.h" + +#include "parallaction/defs.h" + +class MidiParser; + +namespace Parallaction { + +class Parallaction; +class MidiPlayer; + +class SoundMan { + +protected: + Parallaction *_vm; + Audio::Mixer *_mixer; + char _musicFile[PATH_LEN]; + +public: + SoundMan(Parallaction *vm); + virtual ~SoundMan() {} + + virtual void playSfx(const char *filename, uint channel, bool looping, int volume = -1, int rate = -1) { } + virtual void stopSfx(uint channel) { } + + void setMusicFile(const char *filename); + virtual void playMusic() = 0; + virtual void stopMusic() = 0; + virtual void playCharacterMusic(const char *character) = 0; + virtual void playLocationMusic(const char *location) = 0; + void setMusicVolume(int value); +}; + +class DosSoundMan : public SoundMan { + + MidiPlayer *_midiPlayer; + int _musicData1; + +public: + DosSoundMan(Parallaction *vm, MidiDriver *midiDriver); + ~DosSoundMan(); + void playMusic(); + void stopMusic(); + + void playCharacterMusic(const char *character); + void playLocationMusic(const char *location); +}; + +#define NUM_AMIGA_CHANNELS 4 + +class AmigaSoundMan : public SoundMan { + + Audio::AudioStream *_musicStream; + Audio::SoundHandle _musicHandle; + + struct Channel { + Audio::Voice8Header header; + byte *data; + uint32 dataSize; + Audio::SoundHandle handle; + uint32 flags; + } _channels[NUM_AMIGA_CHANNELS]; + +public: + AmigaSoundMan(Parallaction *vm); + ~AmigaSoundMan(); + void playMusic(); + void stopMusic(); + + void playSfx(const char *filename, uint channel, bool looping, int volume, int rate); + void stopSfx(uint channel); + + void playCharacterMusic(const char *character); + void playLocationMusic(const char *location); +}; + +} // namespace Parallaction + +#endif diff --git a/engines/parallaction/staticres.cpp b/engines/parallaction/staticres.cpp index 9c3bc47b60..00317521a2 100644 --- a/engines/parallaction/staticres.cpp +++ b/engines/parallaction/staticres.cpp @@ -23,7 +23,6 @@ #include "common/stdafx.h" #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" namespace Parallaction { @@ -48,6 +47,174 @@ byte Gfx::_mouseArrow[256] = { }; +byte _amigaTopazFont[2600] = +{ + 0x00, 0x00, 0x03, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x79, 0x00, 0x00, 0x03, 0xe9, 0x00, 0x00, 0x02, 0x79, + 0x70, 0xff, 0x4e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x1a, 0x0f, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x45, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x09, 0x74, 0x00, 0x08, + 0x00, 0x40, 0x00, 0x08, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x20, 0xff, 0x00, 0x00, 0x00, 0x6e, + 0x00, 0xbe, 0x00, 0x00, 0x06, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x6c, 0x6c, 0x18, 0x00, 0x38, 0x18, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3c, 0x18, + 0x3c, 0x3c, 0x1c, 0x7e, 0x1c, 0x7e, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7c, 0x3c, + 0x7c, 0x1e, 0x78, 0x7e, 0x7e, 0x3c, 0x66, 0x3c, 0x06, 0xc6, 0x60, 0xc6, 0xc6, 0x3c, 0x7c, 0x78, + 0x7c, 0x3c, 0x7e, 0x66, 0x66, 0xc6, 0xc3, 0xc3, 0xfe, 0x3c, 0xc0, 0x3c, 0x10, 0x00, 0x18, 0x00, + 0x60, 0x00, 0x06, 0x00, 0x1c, 0x00, 0x60, 0x18, 0x0c, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x70, 0x72, 0x0f, 0x00, 0x18, + 0x00, 0x1c, 0x42, 0xc3, 0x18, 0x3c, 0x66, 0x7e, 0x1c, 0x00, 0x3e, 0x7e, 0x7e, 0x3c, 0x18, 0x78, + 0x78, 0x18, 0x00, 0x3e, 0x00, 0x00, 0x30, 0x38, 0x00, 0x40, 0x40, 0xc0, 0x18, 0x3c, 0x3c, 0x7e, + 0x06, 0x66, 0x18, 0x7e, 0x7e, 0x36, 0x0c, 0x0c, 0x18, 0x3c, 0xc6, 0x3c, 0x60, 0x76, 0x18, 0x00, + 0x0c, 0x7e, 0x71, 0x66, 0x00, 0x66, 0x60, 0x0e, 0x7e, 0x66, 0x18, 0x6e, 0x3c, 0x00, 0x18, 0x7e, + 0x06, 0x66, 0x18, 0x00, 0x7e, 0x34, 0x0c, 0x0c, 0x18, 0x0c, 0x60, 0x00, 0x18, 0x3c, 0x0c, 0x00, + 0x0c, 0x00, 0x71, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x7e, 0x00, 0x18, 0x3c, 0x00, 0x18, 0x6c, 0x6c, + 0x3e, 0x66, 0x6c, 0x18, 0x18, 0x18, 0x66, 0x18, 0x00, 0x00, 0x00, 0x06, 0x66, 0x38, 0x66, 0x66, + 0x3c, 0x60, 0x30, 0x06, 0x66, 0x66, 0x18, 0x18, 0x06, 0x00, 0x60, 0x66, 0xc6, 0x66, 0x66, 0x30, + 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x06, 0xcc, 0x60, 0xee, 0xe6, 0x66, 0x66, 0xcc, 0x66, 0x66, + 0x18, 0x66, 0x66, 0xc6, 0x66, 0x66, 0x0c, 0x30, 0x60, 0x0c, 0x38, 0x00, 0x18, 0x00, 0x60, 0x00, + 0x06, 0x00, 0x30, 0x00, 0x60, 0x00, 0x00, 0x60, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x9c, 0x3c, 0x7e, 0x00, 0x0c, 0x36, + 0x3c, 0x66, 0x18, 0x60, 0x66, 0x81, 0x24, 0x33, 0x06, 0x81, 0x00, 0x66, 0x18, 0x0c, 0x0c, 0x30, + 0x00, 0x7a, 0x00, 0x00, 0x70, 0x44, 0xcc, 0xc6, 0xc6, 0x23, 0x00, 0x66, 0x18, 0x00, 0x1c, 0x00, + 0x24, 0x60, 0x00, 0x1c, 0x18, 0x18, 0x00, 0x66, 0xcc, 0x00, 0x60, 0x3c, 0x30, 0xc6, 0x18, 0x00, + 0x8e, 0x00, 0xc6, 0x66, 0x60, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x00, + 0x24, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x7e, + 0x8e, 0x66, 0x18, 0x00, 0x18, 0x18, 0x00, 0x66, 0x00, 0x18, 0x00, 0x18, 0x00, 0xfe, 0x60, 0xac, + 0x68, 0x30, 0x30, 0x0c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x0c, 0x6e, 0x78, 0x06, 0x06, 0x6c, 0x7c, + 0x60, 0x06, 0x66, 0x66, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x06, 0xde, 0x66, 0x66, 0x60, 0x66, 0x60, + 0x60, 0x60, 0x66, 0x18, 0x06, 0xd8, 0x60, 0xfe, 0xf6, 0x66, 0x66, 0xcc, 0x66, 0x70, 0x18, 0x66, + 0x66, 0xc6, 0x3c, 0x3c, 0x18, 0x30, 0x30, 0x0c, 0x6c, 0x00, 0x0c, 0x3c, 0x7c, 0x3c, 0x3e, 0x3c, + 0x7c, 0x3e, 0x7c, 0x18, 0x0c, 0x66, 0x18, 0xec, 0x7c, 0x3c, 0x7c, 0x3e, 0x7c, 0x3c, 0x7c, 0x66, + 0x66, 0xc6, 0xc6, 0x66, 0x7e, 0x18, 0x18, 0x18, 0x00, 0xf0, 0x66, 0x18, 0x3e, 0x30, 0x66, 0x3c, + 0x18, 0x3c, 0x00, 0x9d, 0x44, 0x66, 0x00, 0xb9, 0x00, 0x3c, 0x7e, 0x18, 0x18, 0x60, 0x66, 0x7a, + 0x18, 0x00, 0x30, 0x44, 0x66, 0x4c, 0x4c, 0x66, 0x18, 0x66, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x60, + 0x7e, 0x3c, 0x7e, 0x7e, 0x7e, 0x60, 0xd8, 0x3c, 0x60, 0x66, 0xc6, 0xe6, 0x3c, 0x3c, 0x3c, 0x3c, + 0x6c, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x7e, 0x7e, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0x3c, 0x3c, 0x3c, + 0x3c, 0x18, 0x3c, 0x7e, 0x3c, 0x3e, 0x6c, 0x00, 0x18, 0x3c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x1e, 0x3c, 0x66, 0x00, 0x7e, 0x7e, 0x00, 0x18, 0x00, 0x6c, 0x3c, 0xd8, 0x76, 0x00, + 0x30, 0x0c, 0xff, 0x7e, 0x00, 0x7e, 0x00, 0x18, 0x7e, 0x18, 0x0c, 0x1c, 0xcc, 0x06, 0x7c, 0x0c, + 0x3c, 0x3e, 0x00, 0x00, 0x60, 0x00, 0x06, 0x0c, 0xd6, 0x7e, 0x7c, 0x60, 0x66, 0x78, 0x78, 0x6e, + 0x7e, 0x18, 0x06, 0xf0, 0x60, 0xd6, 0xde, 0x66, 0x7c, 0xcc, 0x7c, 0x3c, 0x18, 0x66, 0x66, 0xd6, + 0x18, 0x18, 0x30, 0x30, 0x18, 0x0c, 0xc6, 0x00, 0x00, 0x06, 0x66, 0x60, 0x66, 0x66, 0x30, 0x66, + 0x66, 0x18, 0x0c, 0x6c, 0x18, 0xfe, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x30, 0x66, 0x66, 0xc6, + 0x6c, 0x66, 0x0c, 0x70, 0x18, 0x0e, 0x00, 0xc3, 0x66, 0x18, 0x6c, 0x78, 0x3c, 0x18, 0x00, 0x66, + 0x00, 0xb1, 0x3c, 0xcc, 0x00, 0xa5, 0x00, 0x00, 0x18, 0x30, 0x0c, 0x00, 0x66, 0x3a, 0x18, 0x00, + 0x30, 0x38, 0x33, 0x58, 0x58, 0x2c, 0x30, 0x7e, 0x18, 0x66, 0x66, 0x66, 0x66, 0x78, 0x60, 0x66, + 0x60, 0x4c, 0x60, 0x6e, 0xf0, 0x18, 0x60, 0x30, 0xe6, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x38, 0x66, + 0x70, 0x30, 0x66, 0x66, 0x4c, 0x4c, 0x6c, 0x06, 0x18, 0x06, 0x3c, 0x06, 0x06, 0x66, 0x66, 0x3c, + 0x66, 0x0c, 0x66, 0x66, 0x78, 0x18, 0x18, 0x60, 0x7c, 0x66, 0x3c, 0x3c, 0x3c, 0x3c, 0x7e, 0x66, + 0x78, 0x60, 0x66, 0x66, 0x0c, 0x0c, 0x00, 0x18, 0x00, 0xfe, 0x06, 0x36, 0xdc, 0x00, 0x30, 0x0c, + 0x3c, 0x18, 0x00, 0x00, 0x00, 0x30, 0x76, 0x18, 0x18, 0x06, 0xfe, 0x06, 0x66, 0x18, 0x66, 0x06, + 0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xde, 0x66, 0x66, 0x60, 0x66, 0x60, 0x60, 0x66, 0x66, 0x18, + 0x06, 0xd8, 0x60, 0xc6, 0xce, 0x66, 0x60, 0xcc, 0x6c, 0x0e, 0x18, 0x66, 0x3c, 0xfe, 0x3c, 0x18, + 0x60, 0x30, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x60, 0x66, 0x7e, 0x30, 0x66, 0x66, 0x18, + 0x0c, 0x78, 0x18, 0xd6, 0x66, 0x66, 0x66, 0x66, 0x60, 0x3c, 0x30, 0x66, 0x66, 0xd6, 0x38, 0x66, + 0x18, 0x18, 0x18, 0x18, 0x00, 0x0f, 0x66, 0x18, 0x3e, 0x30, 0x42, 0x3c, 0x18, 0x3c, 0x00, 0x9d, + 0x00, 0x66, 0x00, 0xb9, 0x00, 0x00, 0x18, 0x7c, 0x78, 0x00, 0x66, 0x0a, 0x00, 0x00, 0x30, 0x00, + 0x66, 0x32, 0x3e, 0xd9, 0x60, 0x66, 0x18, 0x7e, 0x40, 0x7e, 0x7e, 0x60, 0x78, 0x40, 0x78, 0x18, + 0x78, 0x66, 0xd8, 0x18, 0x60, 0x0c, 0xf6, 0xde, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x66, 0xe0, 0x0c, + 0x66, 0x66, 0x18, 0x18, 0x66, 0x3e, 0x18, 0x3e, 0x60, 0x3e, 0x3e, 0x7e, 0x7e, 0x60, 0x7e, 0x18, + 0x7e, 0x66, 0x6c, 0x18, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x18, 0x3c, + 0x66, 0x66, 0x18, 0x18, 0x00, 0x00, 0x00, 0x6c, 0x7c, 0x6a, 0xce, 0x00, 0x18, 0x18, 0x66, 0x18, + 0x18, 0x00, 0x18, 0x60, 0x66, 0x18, 0x30, 0x66, 0x0c, 0x66, 0x66, 0x18, 0x66, 0x0c, 0x18, 0x18, + 0x06, 0x00, 0x60, 0x00, 0xc0, 0x66, 0x66, 0x30, 0x6c, 0x60, 0x60, 0x66, 0x66, 0x18, 0x66, 0xcc, + 0x60, 0xc6, 0xc6, 0x66, 0x60, 0xdc, 0x66, 0x66, 0x18, 0x66, 0x3c, 0xee, 0x66, 0x18, 0xc0, 0x30, + 0x06, 0x0c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x60, 0x66, 0x60, 0x30, 0x3e, 0x66, 0x18, 0x0c, 0x6c, + 0x18, 0xc6, 0x66, 0x66, 0x7c, 0x3e, 0x60, 0x06, 0x30, 0x66, 0x3c, 0xfe, 0x6c, 0x3c, 0x30, 0x18, + 0x18, 0x18, 0x00, 0x3c, 0x66, 0x18, 0x0c, 0x30, 0x00, 0x18, 0x18, 0x06, 0x00, 0x81, 0x7e, 0x33, + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x0a, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0x66, + 0x62, 0x33, 0x66, 0x66, 0x18, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x66, 0x60, 0x32, 0x60, 0x3e, + 0xcc, 0x18, 0x7e, 0x66, 0xde, 0xce, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x66, 0x60, 0x66, 0x66, 0x66, + 0x32, 0x32, 0x66, 0x66, 0x18, 0x66, 0x60, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x30, 0x60, 0x3e, + 0x66, 0x18, 0x18, 0x06, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x18, 0x66, 0x18, 0x06, 0x66, 0x66, + 0x30, 0x30, 0x00, 0x18, 0x00, 0x6c, 0x18, 0xcc, 0x7b, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x18, 0x00, + 0x18, 0xc0, 0x3c, 0x18, 0x7e, 0x3c, 0x0c, 0x3c, 0x3c, 0x18, 0x3c, 0x38, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x18, 0x78, 0x66, 0x7c, 0x1e, 0x78, 0x7e, 0x60, 0x3e, 0x66, 0x3c, 0x3c, 0xc6, 0x7e, 0xc6, + 0xc6, 0x3c, 0x60, 0x7e, 0x66, 0x3c, 0x18, 0x3c, 0x18, 0xc6, 0xc3, 0x18, 0xfe, 0x3c, 0x03, 0x3c, + 0x00, 0x00, 0x00, 0x3e, 0x7c, 0x3c, 0x3e, 0x3c, 0x30, 0x06, 0x66, 0x0c, 0x0c, 0x66, 0x0c, 0xc6, + 0x66, 0x3c, 0x60, 0x06, 0x60, 0x7c, 0x1c, 0x3e, 0x18, 0x6c, 0xc6, 0x18, 0x7e, 0x0e, 0x18, 0x70, + 0x00, 0xf0, 0x7e, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x81, + 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x7f, 0x0a, 0x00, 0x18, 0x00, 0x00, 0x00, 0xcf, 0xc4, 0x67, + 0x3c, 0x67, 0x3e, 0x66, 0x3c, 0x66, 0x66, 0x7f, 0x7e, 0x3c, 0x7e, 0x7e, 0x7e, 0x18, 0x30, 0x3c, + 0x18, 0x3c, 0xce, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x3f, 0x7e, 0x3c, 0x3c, 0x3c, 0x7e, 0x7e, + 0x6c, 0x3f, 0x1e, 0x3e, 0x3c, 0x3e, 0x3e, 0x3c, 0x3c, 0x3c, 0x3c, 0x7e, 0x3c, 0x06, 0x18, 0x0c, + 0x0c, 0x7c, 0x66, 0x18, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x3f, 0x0c, 0x7c, 0x3e, 0x3e, 0x7e, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x60, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x01, 0x00, 0x03, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00, 0x30, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x03, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x00, 0x18, 0x00, + 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x10, 0x00, 0x08, 0x00, 0x18, 0x00, 0x08, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x28, 0x00, 0x08, 0x00, 0x30, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, 0x00, 0x40, + 0x00, 0x08, 0x00, 0x48, 0x00, 0x08, 0x00, 0x50, 0x00, 0x08, 0x00, 0x58, 0x00, 0x08, 0x00, 0x60, + 0x00, 0x08, 0x00, 0x68, 0x00, 0x08, 0x00, 0x70, 0x00, 0x08, 0x00, 0x78, 0x00, 0x08, 0x00, 0x80, + 0x00, 0x08, 0x00, 0x88, 0x00, 0x08, 0x00, 0x90, 0x00, 0x08, 0x00, 0x98, 0x00, 0x08, 0x00, 0xa0, + 0x00, 0x08, 0x00, 0xa8, 0x00, 0x08, 0x00, 0xb0, 0x00, 0x08, 0x00, 0xb8, 0x00, 0x08, 0x00, 0xc0, + 0x00, 0x08, 0x00, 0xc8, 0x00, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x00, 0xd8, 0x00, 0x08, 0x00, 0xe0, + 0x00, 0x08, 0x00, 0xe8, 0x00, 0x08, 0x00, 0xf0, 0x00, 0x08, 0x00, 0xf8, 0x00, 0x08, 0x01, 0x00, + 0x00, 0x08, 0x01, 0x08, 0x00, 0x08, 0x01, 0x10, 0x00, 0x08, 0x01, 0x18, 0x00, 0x08, 0x01, 0x20, + 0x00, 0x08, 0x01, 0x28, 0x00, 0x08, 0x01, 0x30, 0x00, 0x08, 0x01, 0x38, 0x00, 0x08, 0x01, 0x40, + 0x00, 0x08, 0x01, 0x48, 0x00, 0x08, 0x01, 0x50, 0x00, 0x08, 0x01, 0x58, 0x00, 0x08, 0x01, 0x60, + 0x00, 0x08, 0x01, 0x68, 0x00, 0x08, 0x01, 0x70, 0x00, 0x08, 0x01, 0x78, 0x00, 0x08, 0x01, 0x80, + 0x00, 0x08, 0x01, 0x88, 0x00, 0x08, 0x01, 0x90, 0x00, 0x08, 0x01, 0x98, 0x00, 0x08, 0x01, 0xa0, + 0x00, 0x08, 0x01, 0xa8, 0x00, 0x08, 0x01, 0xb0, 0x00, 0x08, 0x01, 0xb8, 0x00, 0x08, 0x01, 0xc0, + 0x00, 0x08, 0x01, 0xc8, 0x00, 0x08, 0x01, 0xd0, 0x00, 0x08, 0x01, 0xd8, 0x00, 0x08, 0x01, 0xe0, + 0x00, 0x08, 0x01, 0xe8, 0x00, 0x08, 0x01, 0xf0, 0x00, 0x08, 0x01, 0xf8, 0x00, 0x08, 0x02, 0x00, + 0x00, 0x08, 0x02, 0x08, 0x00, 0x08, 0x02, 0x10, 0x00, 0x08, 0x02, 0x18, 0x00, 0x08, 0x02, 0x20, + 0x00, 0x08, 0x02, 0x28, 0x00, 0x08, 0x02, 0x30, 0x00, 0x08, 0x02, 0x38, 0x00, 0x08, 0x02, 0x40, + 0x00, 0x08, 0x02, 0x48, 0x00, 0x08, 0x02, 0x50, 0x00, 0x08, 0x02, 0x58, 0x00, 0x08, 0x02, 0x60, + 0x00, 0x08, 0x02, 0x68, 0x00, 0x08, 0x02, 0x70, 0x00, 0x08, 0x02, 0x78, 0x00, 0x08, 0x02, 0x80, + 0x00, 0x08, 0x02, 0x88, 0x00, 0x08, 0x02, 0x90, 0x00, 0x08, 0x02, 0x98, 0x00, 0x08, 0x02, 0xa0, + 0x00, 0x08, 0x02, 0xa8, 0x00, 0x08, 0x02, 0xb0, 0x00, 0x08, 0x02, 0xb8, 0x00, 0x08, 0x02, 0xc0, + 0x00, 0x08, 0x02, 0xc8, 0x00, 0x08, 0x02, 0xd0, 0x00, 0x08, 0x02, 0xd8, 0x00, 0x08, 0x02, 0xe0, + 0x00, 0x08, 0x02, 0xe8, 0x00, 0x08, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf8, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, + 0x00, 0x08, 0x03, 0x08, 0x00, 0x08, 0x03, 0x10, 0x00, 0x08, 0x03, 0x18, 0x00, 0x08, 0x03, 0x20, + 0x00, 0x08, 0x03, 0x28, 0x00, 0x08, 0x03, 0x30, 0x00, 0x08, 0x03, 0x38, 0x00, 0x08, 0x03, 0x40, + 0x00, 0x08, 0x03, 0x48, 0x00, 0x08, 0x03, 0x50, 0x00, 0x08, 0x03, 0x58, 0x00, 0x08, 0x03, 0x60, + 0x00, 0x08, 0x00, 0x68, 0x00, 0x08, 0x03, 0x68, 0x00, 0x08, 0x03, 0x70, 0x00, 0x08, 0x03, 0x78, + 0x00, 0x08, 0x03, 0x80, 0x00, 0x08, 0x03, 0x88, 0x00, 0x08, 0x03, 0x90, 0x00, 0x08, 0x03, 0x98, + 0x00, 0x08, 0x03, 0xa0, 0x00, 0x08, 0x03, 0xa8, 0x00, 0x08, 0x03, 0xb0, 0x00, 0x08, 0x03, 0xb8, + 0x00, 0x08, 0x03, 0xc0, 0x00, 0x08, 0x03, 0xc8, 0x00, 0x08, 0x03, 0xd0, 0x00, 0x08, 0x03, 0xd8, + 0x00, 0x08, 0x03, 0xe0, 0x00, 0x08, 0x03, 0xe8, 0x00, 0x08, 0x03, 0xf0, 0x00, 0x08, 0x03, 0xf8, + 0x00, 0x08, 0x04, 0x00, 0x00, 0x08, 0x04, 0x08, 0x00, 0x08, 0x04, 0x10, 0x00, 0x08, 0x04, 0x18, + 0x00, 0x08, 0x04, 0x20, 0x00, 0x08, 0x04, 0x28, 0x00, 0x08, 0x04, 0x30, 0x00, 0x08, 0x04, 0x38, + 0x00, 0x08, 0x04, 0x40, 0x00, 0x08, 0x04, 0x48, 0x00, 0x08, 0x04, 0x50, 0x00, 0x08, 0x04, 0x58, + 0x00, 0x08, 0x04, 0x60, 0x00, 0x08, 0x04, 0x68, 0x00, 0x08, 0x04, 0x70, 0x00, 0x08, 0x04, 0x78, + 0x00, 0x08, 0x04, 0x80, 0x00, 0x08, 0x04, 0x88, 0x00, 0x08, 0x04, 0x90, 0x00, 0x08, 0x04, 0x98, + 0x00, 0x08, 0x04, 0xa0, 0x00, 0x08, 0x04, 0xa8, 0x00, 0x08, 0x04, 0xb0, 0x00, 0x08, 0x04, 0xb8, + 0x00, 0x08, 0x04, 0xc0, 0x00, 0x08, 0x04, 0xc8, 0x00, 0x08, 0x04, 0xd0, 0x00, 0x08, 0x04, 0xd8, + 0x00, 0x08, 0x04, 0xe0, 0x00, 0x08, 0x04, 0xe8, 0x00, 0x08, 0x04, 0xf0, 0x00, 0x08, 0x04, 0xf8, + 0x00, 0x08, 0x05, 0x00, 0x00, 0x08, 0x05, 0x08, 0x00, 0x08, 0x05, 0x10, 0x00, 0x08, 0x05, 0x18, + 0x00, 0x08, 0x05, 0x20, 0x00, 0x08, 0x05, 0x28, 0x00, 0x08, 0x05, 0x30, 0x00, 0x08, 0x05, 0x38, + 0x00, 0x08, 0x05, 0x40, 0x00, 0x08, 0x05, 0x48, 0x00, 0x08, 0x05, 0x50, 0x00, 0x08, 0x05, 0x58, + 0x00, 0x08, 0x05, 0x60, 0x00, 0x08, 0x05, 0x68, 0x00, 0x08, 0x05, 0x70, 0x00, 0x08, 0x05, 0x78, + 0x00, 0x08, 0x05, 0x80, 0x00, 0x08, 0x05, 0x88, 0x00, 0x08, 0x05, 0x90, 0x00, 0x08, 0x05, 0x98, + 0x00, 0x08, 0x05, 0xa0, 0x00, 0x08, 0x05, 0xa8, 0x00, 0x08, 0x05, 0xb0, 0x00, 0x08, 0x05, 0xb8, + 0x00, 0x08, 0x05, 0xc0, 0x00, 0x08, 0x05, 0xc8, 0x00, 0x08, 0x05, 0xd0, 0x00, 0x08, 0x05, 0xd8, + 0x00, 0x08, 0x05, 0xe0, 0x00, 0x08, 0x05, 0xe8, 0x00, 0x08, 0x00, 0x38, 0x00, 0x08, 0x03, 0x00, + 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x03, 0xec, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x62, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf2 +}; + + const char *_zoneFlagNamesRes[] = { "closed", @@ -133,8 +300,8 @@ const char *_instructionNamesRes[] = { }; const char *_callableNamesRes[] = { - "HBOff", "Projector", + "HBOff", "StartIntro", "EndIntro", "MoveSheet", @@ -160,9 +327,10 @@ const char *_callableNamesRes[] = { "TestResult" }; +typedef void (*callable)(void*); + void _c_play_boogie(void*); -void _c_play_boogie(void*); void _c_startIntro(void*); void _c_endIntro(void*); void _c_moveSheet(void*); @@ -170,7 +338,6 @@ void _c_sketch(void*); void _c_shade(void*); void _c_score(void*); void _c_fade(void*); -void _c_play_boogie(void*); void _c_moveSarc(void*); void _c_contaFoglie(void*); void _c_zeroFoglie(void*); @@ -185,35 +352,14 @@ void _c_ridux(void*); void _c_testResult(void*); void _c_null(void*); -typedef void (*callable)(void*); +void _c_projector(void*); +void _c_HBOff(void*); +void _c_offSound(void*); +void _c_startMusic(void*); +void _c_closeMusic(void*); +void _c_HBOn(void*); -callable _callables[] = { - _c_play_boogie, - _c_play_boogie, - _c_startIntro, - _c_endIntro, - _c_moveSheet, - _c_sketch, - _c_shade, - _c_score, - _c_null, - _c_null, - _c_null, - _c_fade, - _c_play_boogie, - _c_moveSarc, - _c_contaFoglie, - _c_zeroFoglie, - _c_trasformata, - _c_offMouse, - _c_onMouse, - _c_setMask, - _c_endComment, - _c_frankenstein, - _c_finito, - _c_ridux, - _c_testResult -}; +callable _callables[25]; Credit _credits[] = { @@ -222,8 +368,7 @@ Credit _credits[] = { {"Project Manager", "LOVRANO CANEPA"}, {"Production", "BRUNO BOZ"}, {"Special Thanks to", "LUIGI BENEDICENTI - GILDA and DANILO"}, - {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"}, - {"CLICK MOUSE BUTTON TO START", 0} + {"Copyright 1992 Euclidea s.r.l ITALY", "All rights reserved"} }; const char *_dinoName = "dino"; @@ -248,6 +393,60 @@ void Parallaction::initResources() { _localFlagNames = new Table(120); _localFlagNames->addData("visited"); + if (getPlatform() == Common::kPlatformPC) { + _callables[0] = _c_play_boogie; + _callables[1] = _c_play_boogie; + _callables[2] = _c_startIntro; + _callables[3] = _c_endIntro; + _callables[4] = _c_moveSheet; + _callables[5] = _c_sketch; + _callables[6] = _c_shade; + _callables[7] = _c_score; + _callables[8] = _c_null; + _callables[9] = _c_null; + _callables[10] = _c_null; + _callables[11] = _c_fade; + _callables[12] = _c_play_boogie; + _callables[13] = _c_moveSarc; + _callables[14] = _c_contaFoglie; + _callables[15] = _c_zeroFoglie; + _callables[16] = _c_trasformata; + _callables[17] = _c_offMouse; + _callables[18] = _c_onMouse; + _callables[19] = _c_setMask; + _callables[20] = _c_endComment; + _callables[21] = _c_frankenstein; + _callables[22] = _c_finito; + _callables[23] = _c_ridux; + _callables[24] = _c_testResult; + } else { + _callables[0] = _c_projector; + _callables[1] = _c_HBOff; + _callables[2] = _c_startIntro; + _callables[3] = _c_endIntro; + _callables[4] = _c_moveSheet; + _callables[5] = _c_sketch; + _callables[6] = _c_shade; + _callables[7] = _c_score; + _callables[8] = _c_offSound; + _callables[9] = _c_startMusic; + _callables[10] = _c_closeMusic; + _callables[11] = _c_fade; + _callables[12] = _c_HBOn; + _callables[13] = _c_moveSarc; + _callables[14] = _c_contaFoglie; + _callables[15] = _c_zeroFoglie; + _callables[16] = _c_trasformata; + _callables[17] = _c_offMouse; + _callables[18] = _c_onMouse; + _callables[19] = _c_setMask; + _callables[20] = _c_endComment; + _callables[21] = _c_frankenstein; + _callables[22] = _c_finito; + _callables[23] = _c_ridux; + _callables[24] = _c_testResult; + } + } diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index 4910bc07ba..aae5233e61 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -20,17 +20,12 @@ * */ -#include "parallaction/defs.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/commands.h" -#include "parallaction/graphics.h" -#include "parallaction/walk.h" -#include "parallaction/zone.h" namespace Parallaction { -uint16 walkFunc1(int16, int16, WalkNode *); - static byte *_buffer; static uint16 _doorData1 = 1000; @@ -40,6 +35,17 @@ static uint16 walkData1 = 0; static uint16 walkData2 = 0; // next walk frame +uint16 queryPath(uint16 x, uint16 y) { + + // NOTE: a better solution would have us mirror each byte in the mask in the loading routine + // AmigaDisk::loadPath() instead of doing it here. + + byte _al = _buffer[y*40 + x/8]; + byte _dl = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7)); + + return _al & (1 << _dl); +} + // adjusts position towards nearest walkable point // void PathBuilder::correctPathPoint(Common::Point &to) { @@ -135,7 +141,15 @@ uint32 PathBuilder::buildSubPath(const Common::Point& pos, const Common::Point& return v34; } +#if 0 +void printNodes(WalkNodeList *list, const char* text) { + printf("%s\n-------------------\n", text); + for (WalkNodeList::iterator it = list->begin(); it != list->end(); it++) + printf("node [%p] (%i, %i)\n", *it, (*it)->_x, (*it)->_y); + return; +} +#endif // // x, y: mouse click (foot) coordinates // @@ -163,10 +177,12 @@ WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { // path is obstructed: look for alternative _list = new WalkNodeList; _list->push_back(v48); +#if 0 + printNodes(_list, "start"); +#endif Common::Point stop(v48->_x, v48->_y); Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); - uint32 v34 = buildSubPath(pos, stop); if (v38 != 0 && v34 > v38) { // no alternative path (gap?) @@ -175,14 +191,16 @@ WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { return _list; } _list->insert(_list->begin(), _subPath.begin(), _subPath.end()); +#if 0 + printNodes(_list, "first segment"); +#endif (*_list->begin())->getPoint(stop); - buildSubPath(pos, stop); _list->insert(_list->begin(), _subPath.begin(), _subPath.end()); - - for (WalkNodeList::iterator it = _list->begin(); it != _list->end(); it++) - printf("node (%i, %i)\n", (*it)->_x, (*it)->_y); +#if 0 + printNodes(_list, "complete"); +#endif delete v44; return _list; @@ -196,7 +214,7 @@ WalkNodeList *PathBuilder::buildPath(uint16 x, uint16 y) { // 1 : Point reachable in a straight line // other values: square distance to target (point not reachable in a straight line) // -uint16 walkFunc1(int16 x, int16 y, WalkNode *Node) { +uint16 PathBuilder::walkFunc1(int16 x, int16 y, WalkNode *Node) { Common::Point arg(x, y); @@ -249,7 +267,7 @@ uint16 walkFunc1(int16 x, int16 y, WalkNode *Node) { return 1; } -void clipMove(Common::Point& pos, const WalkNode* from) { +void Parallaction::clipMove(Common::Point& pos, const WalkNode* from) { if ((pos.x < from->_x) && (pos.x < SCREEN_WIDTH) && (queryPath(_vm->_char._ani.width()/2 + pos.x + 2, _vm->_char._ani.height() + pos.y) != 0)) { pos.x = (pos.x + 2 < from->_x) ? pos.x + 2 : from->_x; @@ -270,7 +288,7 @@ void clipMove(Common::Point& pos, const WalkNode* from) { return; } -int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from) { +int16 Parallaction::selectWalkFrame(const Common::Point& pos, const WalkNode* from) { Common::Point dist(from->_x - pos.x, from->_y - pos.y); @@ -312,51 +330,7 @@ int16 selectWalkFrame(const Common::Point& pos, const WalkNode* from) { return v16; } -void finalizeWalk(WalkNodeList *list) { - checkDoor(); - delete list; -} - -void jobWalk(void *parm, Job *j) { - WalkNodeList *list = (WalkNodeList*)parm; - - Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); - _vm->_char._ani._oldPos = pos; - - WalkNodeList::iterator it = list->begin(); - - if ((*it)->_x == pos.x && (*it)->_y == pos.y) { - debugC(1, kDebugWalk, "jobWalk moving to next node (%i, %i)", (*it)->_x, (*it)->_y); - it = list->erase(it); - } - if (it == list->end()) { - debugC(1, kDebugWalk, "jobWalk reached last node"); - j->_finished = 1; - finalizeWalk(list); - return; - } - j->_parm = list; - - // selectWalkFrame must be performed before position is changed by clipMove - int16 v16 = selectWalkFrame(pos, *it); - clipMove(pos, *it); - - _vm->_char._ani._left = pos.x; - _vm->_char._ani._top = pos.y; - - if (pos == _vm->_char._ani._oldPos) { - debugC(1, kDebugWalk, "jobWalk was blocked by an unforeseen obstacle"); - j->_finished = 1; - finalizeWalk(list); - } else { - _vm->_char._ani._frame = v16 + walkData2 + 1; - } - - return; -} - - -uint16 checkDoor() { +uint16 Parallaction::checkDoor() { // printf("checkDoor()..."); if (_vm->_currentLocationIndex != _doorData1) { @@ -404,20 +378,58 @@ uint16 checkDoor() { return _vm->_char._ani._frame; } -uint16 queryPath(uint16 x, uint16 y) { - byte _al = _buffer[y*40 + x/8]; - byte _dl = 1 << (x % 8); +void Parallaction::finalizeWalk(WalkNodeList *list) { + checkDoor(); + delete list; +} + +void jobWalk(void *parm, Job *j) { + WalkNodeList *list = (WalkNodeList*)parm; + + Common::Point pos(_vm->_char._ani._left, _vm->_char._ani._top); + _vm->_char._ani._oldPos = pos; + + WalkNodeList::iterator it = list->begin(); + + if (it != list->end()) { + if ((*it)->_x == pos.x && (*it)->_y == pos.y) { + debugC(1, kDebugWalk, "jobWalk reached node (%i, %i)", (*it)->_x, (*it)->_y); + it = list->erase(it); + } + } + if (it == list->end()) { + debugC(1, kDebugWalk, "jobWalk reached last node"); + j->_finished = 1; + _vm->finalizeWalk(list); + return; + } + j->_parm = list; - return _al & _dl; + // selectWalkFrame must be performed before position is changed by clipMove + int16 v16 = _vm->selectWalkFrame(pos, *it); + _vm->clipMove(pos, *it); + _vm->_char._ani._left = pos.x; + _vm->_char._ani._top = pos.y; + + if (pos == _vm->_char._ani._oldPos) { + debugC(1, kDebugWalk, "jobWalk was blocked by an unforeseen obstacle"); + j->_finished = 1; + _vm->finalizeWalk(list); + } else { + _vm->_char._ani._frame = v16 + walkData2 + 1; + } + + return; } -void setPath(byte *path) { + +void Parallaction::setPath(byte *path) { memcpy(_buffer, path, SCREENPATH_WIDTH*SCREEN_HEIGHT); } -void initWalk() { +void Parallaction::initWalk() { _buffer = (byte*)malloc(SCREENPATH_WIDTH * SCREEN_HEIGHT); } @@ -425,7 +437,7 @@ void initWalk() { WalkNode::WalkNode() : _x(0), _y(0) { } -WalkNode::WalkNode(int32 x, int32 y) : _x(x), _y(y) { +WalkNode::WalkNode(int16 x, int16 y) : _x(x), _y(y) { } WalkNode::WalkNode(const WalkNode& w) : _x(w._x), _y(w._y) { diff --git a/engines/parallaction/walk.h b/engines/parallaction/walk.h index 8b8e189df7..eb0aa3643f 100644 --- a/engines/parallaction/walk.h +++ b/engines/parallaction/walk.h @@ -31,12 +31,12 @@ struct Animation; struct Job; struct WalkNode { - int32 _x; - int32 _y; + int16 _x; + int16 _y; public: WalkNode(); - WalkNode(int32 x, int32 y); + WalkNode(int16 x, int16 y); WalkNode(const WalkNode& w); void getPoint(Common::Point &p) const; @@ -44,22 +44,20 @@ public: typedef ManagedList<WalkNode*> WalkNodeList; -//WalkNode *buildWalkPath(uint16 x, uint16 y); + void jobWalk(void*, Job *j); -uint16 checkDoor(); -void setPath(byte *path); -void initWalk(); -uint16 queryPath(uint16 x, uint16 y); + class PathBuilder { Animation *_anim; WalkNodeList *_list; - WalkNodeList _subPath; + Common::List<WalkNode*> _subPath; void correctPathPoint(Common::Point &to); uint32 buildSubPath(const Common::Point& pos, const Common::Point& stop); + uint16 walkFunc1(int16 x, int16 y, WalkNode *Node); public: PathBuilder(Animation *anim); diff --git a/engines/parallaction/zone.cpp b/engines/parallaction/zone.cpp index ebf2136f05..16581e9174 100644 --- a/engines/parallaction/zone.cpp +++ b/engines/parallaction/zone.cpp @@ -21,11 +21,10 @@ */ -#include "parallaction/parser.h" +#include "common/stdafx.h" + #include "parallaction/parallaction.h" -#include "parallaction/graphics.h" -#include "parallaction/inventory.h" -#include "parallaction/zone.h" +#include "parallaction/sound.h" namespace Parallaction { @@ -271,6 +270,10 @@ void Parallaction::parseZoneTypeBlock(Script &script, Zone *z) { case kZoneHear: // hear Zone init if (!scumm_stricmp(_tokens[0], "sound")) { strcpy(u->hear->_name, _tokens[1]); + z->u.hear->_channel = atoi(_tokens[2]); + } + if (!scumm_stricmp(_tokens[0], "freq")) { + z->u.hear->_freq = atoi(_tokens[1]); } break; @@ -304,7 +307,7 @@ void Parallaction::displayCharacterComment(ExamineData *data) { v3C._data0 = _char._talk->getFramePtr(0); v3C._data1 = NULL; //_talk->field_8[0]; - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); _gfx->flatBlitCnv(&v3C, 190, 80, Gfx::kBitFront); int16 v26, v28; @@ -314,6 +317,8 @@ void Parallaction::displayCharacterComment(ExamineData *data) { _gfx->drawBalloon(r, 0); _gfx->displayWrappedString(data->_description, 140, 10, 130, 0); + _gfx->updateScreen(); + waitUntilLeftClick(); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); @@ -334,6 +339,8 @@ void Parallaction::displayItemComment(ExamineData *data) { if (data->_description == NULL) return; + _gfx->setHalfbriteMode(true); + char v68[PATH_LEN]; strcpy(v68, data->_filename); data->_cnv = _disk->loadStatic(v68); @@ -343,7 +350,7 @@ void Parallaction::displayItemComment(ExamineData *data) { int16 v6A = 0, v6C = 0; - _gfx->setFont("comic"); + _gfx->setFont(kFontDialogue); _gfx->getStringExtent(data->_description, 130, &v6C, &v6A); Common::Rect r(v6C, v6A); r.moveTo(0, 90); @@ -352,9 +359,11 @@ void Parallaction::displayItemComment(ExamineData *data) { _gfx->displayWrappedString(data->_description, 0, 90, 130, 0); jobEraseAnimations((void*)1, NULL); + _gfx->updateScreen(); waitUntilLeftClick(); + _gfx->setHalfbriteMode(false); _gfx->copyScreen(Gfx::kBitBack, Gfx::kBitFront); return; @@ -394,7 +403,7 @@ uint16 Parallaction::runZone(Zone *z) { break; case kZoneHear: - strcpy(_soundFile, z->u.hear->_name); + _soundMan->playSfx(z->u.hear->_name, z->u.hear->_channel, (z->_flags & kFlagsLooping) == kFlagsLooping, 60); break; case kZoneSpeak: @@ -446,13 +455,18 @@ void jobToggleDoor(void *parm, Job *j) { - - - // // ZONE TYPE: GET // +int16 Parallaction::pickupItem(Zone *z) { + int r = addInventoryItem(z->u.get->_icon); + if (r == 0) + addJob(&jobRemovePickedItem, z, kPriority17 ); + + return r; +} + void jobRemovePickedItem(void *parm, Job *j) { Zone *z = (Zone*)parm; @@ -480,7 +494,7 @@ void jobDisplayDroppedItem(void *parm, Job *j) { Zone *z = (Zone*)parm; if (z->u.get->_cnv) { - if (z->u.get->_cnv->_data0 != NULL) { + if (j->_count == 0) { _vm->_gfx->backupGetBackground(z->u.get, z->_left, z->_top); } @@ -601,7 +615,7 @@ Zone::Zone() { } Zone::~Zone() { - printf("~Zone(%s)\n", _label._text); +// printf("~Zone(%s)\n", _label._text); switch (_type & 0xFFFF) { case kZoneExamine: @@ -642,11 +656,6 @@ Zone::~Zone() { default: break; } - - free(_label._text); - _label._text = NULL; - _vm->_gfx->freeStaticCnv(&_label._cnv); - } void Zone::getRect(Common::Rect& r) const { @@ -671,5 +680,15 @@ uint16 Zone::height() const { return _bottom - _top; } +Label::Label() { + _text = NULL; +} + +Label::~Label() { + _vm->_gfx->freeStaticCnv(&_cnv); + if (_text) + free(_text); +} + } // namespace Parallaction diff --git a/engines/parallaction/zone.h b/engines/parallaction/zone.h index 1a0a616624..a2a852f31c 100644 --- a/engines/parallaction/zone.h +++ b/engines/parallaction/zone.h @@ -26,6 +26,7 @@ #include "common/list.h" #include "parallaction/defs.h" + #include "parallaction/commands.h" #include "parallaction/graphics.h" @@ -147,8 +148,12 @@ struct DoorData { // size = 28 }; struct HearData { // size = 20 char _name[20]; + int _channel; + int _freq; HearData() { + _channel = -1; + _freq = -1; _name[0] = '\0'; } }; @@ -184,9 +189,8 @@ struct Label { char* _text; StaticCnv _cnv; - Label() { - _text = NULL; - } + Label(); + ~Label(); }; struct Zone { @@ -308,13 +312,6 @@ struct Animation : public Zone { typedef Animation* AnimationPointer; typedef ManagedList<AnimationPointer> AnimationList; -void dropItem(uint16 v); -int16 pickupItem(Zone *z); - - -void loadProgram(Animation *, char *filename); - - } // namespace Parallaction diff --git a/engines/queen/command.h b/engines/queen/command.h index 98218ee1b3..659b67f8ed 100644 --- a/engines/queen/command.h +++ b/engines/queen/command.h @@ -185,7 +185,7 @@ private: void lookForCurrentIcon(int16 cx, int16 cy); //! returns true if the verb is an action verb - bool isVerbAction(Verb v) const { return (v >= VERB_PANEL_COMMAND_FIRST && v <= VERB_PANEL_COMMAND_LAST) || (v == VERB_WALK_TO); }; + bool isVerbAction(Verb v) const { return (v >= VERB_PANEL_COMMAND_FIRST && v <= VERB_PANEL_COMMAND_LAST) || (v == VERB_WALK_TO); } //! return true if the verb is an inventory item bool isVerbInv(Verb v) const { return v >= VERB_INV_FIRST && v <= VERB_INV_LAST; } diff --git a/engines/queen/sound.cpp b/engines/queen/sound.cpp index d3ffcd6c2e..378fc04e92 100644 --- a/engines/queen/sound.cpp +++ b/engines/queen/sound.cpp @@ -83,7 +83,7 @@ protected: #ifdef USE_FLAC class FLACSound : public PCSound { public: - FLACSound(Audio::Mixer *mixer, QueenEngine *vm) : PCSound(mixer, vm) {}; + FLACSound(Audio::Mixer *mixer, QueenEngine *vm) : PCSound(mixer, vm) {} protected: void playSoundData(Common::File *f, uint32 size, Audio::SoundHandle *soundHandle) { _mixer->playInputStream(Audio::Mixer::kSFXSoundType, soundHandle, Audio::makeFlacStream(f, size)); diff --git a/engines/saga/actor.cpp b/engines/saga/actor.cpp index 9f8b767c75..c26f06b33a 100644 --- a/engines/saga/actor.cpp +++ b/engines/saga/actor.cpp @@ -88,6 +88,45 @@ static int tileCommonObjectCompare(const CommonObjectDataPointer& obj1, const Co return 1; } +inline int16 int16Compare(int16 i1, int16 i2) { + return ((i1) > (i2) ? 1 : ((i1) < (i2) ? -1 : 0)); +} + +inline int16 quickDistance(const Point &point1, const Point &point2) { + Point delta; + delta.x = ABS(point1.x - point2.x) / 2; + delta.y = ABS(point1.y - point2.y); + return ((delta.x < delta.y) ? (delta.y + delta.x / 2) : (delta.x + delta.y / 2)); +} + +inline void calcDeltaS(const Point &point1, const Point &point2, Point &delta, Point &s) { + + delta.x = point2.x - point1.x; + if (delta.x == 0) { + s.x = 0; + } else { + if (delta.x > 0) { + s.x = 1; + } else { + s.x = -1; + delta.x = -delta.x; + } + } + + + delta.y = point2.y - point1.y; + if (delta.y == 0) { + s.y = 0; + } else { + if (delta.y > 0) { + s.y = 1; + } else { + s.y = -1; + delta.y = -delta.y; + } + } +} + // Lookup table to convert 8 cardinal directions to 4 static const int actorDirectectionsLUT[8] = { ACTOR_DIRECTION_BACK, // kDirUp @@ -101,14 +140,14 @@ static const int actorDirectectionsLUT[8] = { }; static const PathDirectionData pathDirectionLUT[8][3] = { - { { 0, 0, -1 }, { 7, -1, -1 }, { 4, 1, -1 } }, - { { 1, 1, 0 }, { 4, 1, -1 }, { 5, 1, 1 } }, - { { 2, 0, 1 }, { 5, 1, 1 }, { 6, -1, 1 } }, - { { 3, -1, 0 }, { 6, -1, 1 }, { 7, -1, -1 } }, - { { 0, 0, -1 }, { 1, 1, 0 }, { 4, 1, -1 } }, - { { 1, 1, 0 }, { 2, 0, 1 }, { 5, 1, 1 } }, - { { 2, 0, 1 }, { 3, -1, 0 }, { 6, -1, 1 } }, - { { 3, -1, 0 }, { 0, 0, -1 }, { 7, -1, -1 } } + { { 0, Point( 0, -1) }, { 7, Point(-1, -1) }, { 4, Point( 1, -1) } }, + { { 1, Point( 1, 0) }, { 4, Point( 1, -1) }, { 5, Point( 1, 1) } }, + { { 2, Point( 0, 1) }, { 5, Point( 1, 1) }, { 6, Point(-1, 1) } }, + { { 3, Point(-1, 0) }, { 6, Point(-1, 1) }, { 7, Point(-1, -1) } }, + { { 0, Point( 0, -1) }, { 1, Point( 1, 0) }, { 4, Point( 1, -1) } }, + { { 1, Point( 1, 0) }, { 2, Point( 0, 1) }, { 5, Point( 1, 1) } }, + { { 2, Point( 0, 1) }, { 3, Point(-1, 0) }, { 6, Point(-1, 1) } }, + { { 3, Point(-1, 0) }, { 0, Point( 0, -1) }, { 7, Point(-1, -1) } } }; static const int pathDirectionLUT2[8][2] = { @@ -2605,51 +2644,57 @@ void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point bool Actor::scanPathLine(const Point &point1, const Point &point2) { Point point; Point delta; - bool interchange = false; + Point s; Point fDelta; - int errterm; - int s1; - int s2; - int i; + int16 errterm; + calcDeltaS(point1, point2, delta, s); point = point1; - delta.x = ABS(point1.x - point2.x); - delta.y = ABS(point1.y - point2.y); - s1 = integerCompare(point2.x, point1.x); - s2 = integerCompare(point2.y, point1.y); - - if (delta.y > delta.x) { - SWAP(delta.y, delta.x); - interchange = true; - } fDelta.x = delta.x * 2; fDelta.y = delta.y * 2; - errterm = fDelta.y - delta.x; + if (delta.y > delta.x) { - for (i = 0; i < delta.x; i++) { - while (errterm >= 0) { - if (interchange) { - point.x += s1; - } else { - point.y += s2; + errterm = fDelta.x - delta.y; + + while (delta.y > 0) { + while (errterm >= 0) { + point.x += s.x; + errterm -= fDelta.y; } - errterm -= fDelta.x; + + point.y += s.y; + errterm += fDelta.x; + + if (!validPathCellPoint(point)) { + return false; + } + if (getPathCell(point) == kPathCellBarrier) { + return false; + } + delta.y--; } + } else { - if (interchange) - point.y += s2; - else - point.x += s1; + errterm = fDelta.y - delta.x; - errterm += fDelta.y; + while (delta.x > 0) { + while (errterm >= 0) { + point.y += s.y; + errterm -= fDelta.x; + } + + point.x += s.x; + errterm += fDelta.y; - if (!validPathCellPoint(point)) { - return false; - } - if (getPathCell(point) == kPathCellBarrier) { - return false; + if (!validPathCellPoint(point)) { + return false; + } + if (getPathCell(point) == kPathCellBarrier) { + return false; + } + delta.x--; } } return true; @@ -2675,8 +2720,7 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be for (startDirection = 0; startDirection < 4; startDirection++) { newPathDirection = addPathDirectionListData(); - newPathDirection->x = fromPoint.x; - newPathDirection->y = fromPoint.y; + newPathDirection->coord = fromPoint; newPathDirection->direction = startDirection; } @@ -2694,8 +2738,9 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be pathDirection = &_pathDirectionList[i]; for (directionCount = 0; directionCount < 3; directionCount++) { samplePathDirection = &pathDirectionLUT[pathDirection->direction][directionCount]; - nextPoint.x = samplePathDirection->x + pathDirection->x; - nextPoint.y = samplePathDirection->y + pathDirection->y; + nextPoint = pathDirection->coord; + nextPoint.x += samplePathDirection->coord.x; + nextPoint.y += samplePathDirection->coord.y; if (!validPathCellPoint(nextPoint)) { continue; @@ -2711,8 +2756,7 @@ int Actor::fillPathArray(const Point &fromPoint, const Point &toPoint, Point &be addDebugPoint(nextPoint, samplePathDirection->direction + 96); #endif newPathDirection = addPathDirectionListData(); - newPathDirection->x = nextPoint.x; - newPathDirection->y = nextPoint.y; + newPathDirection->coord = nextPoint; newPathDirection->direction = samplePathDirection->direction; ++pointCounter; if (nextPoint == toPoint) { @@ -2783,8 +2827,8 @@ void Actor::pathToNode() { --point; point2 = *point; if (direction == 0) { - delta.x = integerCompare(point2.x, point1.x); - delta.y = integerCompare(point2.y, point1.y); + delta.x = int16Compare(point2.x, point1.x); + delta.y = int16Compare(point2.y, point1.y); direction++; } if ((point1.x + delta.x != point2.x) || (point1.y + delta.y != point2.y)) { @@ -2801,47 +2845,55 @@ int pathLine(Point *pointList, const Point &point1, const Point &point2) { Point point; Point delta; Point tempPoint; - int s1; - int s2; - bool interchange = false; - int errterm; - int i; + Point s; + int16 errterm; + int16 res; - delta.x = ABS(point2.x - point1.x); - delta.y = ABS(point2.y - point1.y); - point = point1; - s1 = integerCompare(point2.x, point1.x); - s2 = integerCompare(point2.y, point1.y); + calcDeltaS(point1, point2, delta, s); - if (delta.y > delta.x) { - SWAP(delta.y, delta.x); - interchange = true; - } + point = point1; tempPoint.x = delta.x * 2; tempPoint.y = delta.y * 2; - errterm = tempPoint.y - delta.x; + if (delta.y > delta.x) { + + errterm = tempPoint.x - delta.y; + res = delta.y; - for (i = 0; i < delta.x; i++) { - while (errterm >= 0) { - if (interchange) { - point.x += s1; - } else { - point.y += s2; + while (delta.y > 0) { + while (errterm >= 0) { + point.x += s.x; + errterm -= tempPoint.y; } - errterm -= tempPoint.x; - } - if (interchange) { - point.y += s2; - } else { - point.x += s1; + + point.y += s.y; + errterm += tempPoint.x; + + *pointList = point; + pointList++; + delta.y--; } - errterm += tempPoint.y; + } else { + + errterm = tempPoint.y - delta.x; + res = delta.x; + + while (delta.x > 0) { + while (errterm >= 0) { + point.y += s.y; + errterm -= tempPoint.x; + } + + point.x += s.x; + errterm += tempPoint.y; - pointList[i] = point; + *pointList = point; + pointList++; + delta.x--; + } } - return delta.x; + return res; } void Actor::nodeToPath() { diff --git a/engines/saga/actor.h b/engines/saga/actor.h index 2c247d7bba..d6ca4c4f41 100644 --- a/engines/saga/actor.h +++ b/engines/saga/actor.h @@ -147,8 +147,7 @@ enum DragonMoveTypes { struct PathDirectionData { int8 direction; - int16 x; - int16 y; + Point coord; }; struct ActorFrameRange { @@ -622,15 +621,19 @@ private: (testPoint.y < 0) || (testPoint.y >= _yCellCount)); } void setPathCell(const Point &testPoint, int8 value) { +#ifdef ACTOR_DEBUG if (!validPathCellPoint(testPoint)) { error("Actor::setPathCell wrong point"); } +#endif _pathCell[testPoint.x + testPoint.y * _xCellCount] = value; } int8 getPathCell(const Point &testPoint) { +#ifdef ACTOR_DEBUG if (!validPathCellPoint(testPoint)) { error("Actor::getPathCell wrong point"); } +#endif return _pathCell[testPoint.x + testPoint.y * _xCellCount]; } bool scanPathLine(const Point &point1, const Point &point2); @@ -767,12 +770,6 @@ public: #endif }; -inline int16 quickDistance(const Point &point1, const Point &point2) { - Point delta; - delta.x = ABS(point1.x - point2.x) / 2; - delta.y = ABS(point1.y - point2.y); - return ((delta.x < delta.y) ? (delta.y + delta.x / 2) : (delta.x + delta.y / 2)); -} } // End of namespace Saga #endif diff --git a/engines/saga/game.cpp b/engines/saga/detection.cpp index 820331b9c7..15c6a47682 100644 --- a/engines/saga/game.cpp +++ b/engines/saga/detection.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project + * Copyright (C) 2004-2007 The ScummVM project * * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. * @@ -29,12 +29,12 @@ #include "common/config-manager.h" #include "common/advancedDetector.h" +#include "saga/displayinfo.h" #include "saga/rscfile.h" #include "saga/interface.h" #include "saga/scene.h" #include "saga/sagaresnames.h" - namespace Saga { struct SAGAGameDescription { Common::ADGameDescription desc; @@ -42,7 +42,6 @@ struct SAGAGameDescription { int gameType; int gameId; uint32 features; - const GameDisplayInfo *gameDisplayInfo; int startSceneNumber; const GameResourceDescription *resourceDescription; int fontsCount; @@ -94,11 +93,7 @@ static const Common::ADObsoleteGameID obsoleteGameIDsTable[] = { {0, 0, Common::kPlatformUnknown} }; -namespace Saga { - -#include "sagagame.cpp" - -} +#include "saga/detection_tables.h" static const Common::ADParams detectionParams = { // Pointer to ADGameDescription or its superset structure @@ -132,11 +127,24 @@ bool SagaEngine::initGame() { if (_gameDescription == 0) return false; - _gameDisplayInfo = *_gameDescription->gameDisplayInfo; - _displayClip.right = _gameDisplayInfo.logicalWidth; - _displayClip.bottom = _gameDisplayInfo.logicalHeight; + _displayClip.right = getDisplayInfo().logicalWidth; + _displayClip.bottom = getDisplayInfo().logicalHeight; return _resource->createContexts(); } +const GameDisplayInfo &SagaEngine::getDisplayInfo() { + return _gameDescription->gameType == GType_ITE ? ITE_DisplayInfo : IHNM_DisplayInfo; +} + +int SagaEngine::getDisplayWidth() const { + const GameDisplayInfo &di = _gameDescription->gameType == GType_ITE ? ITE_DisplayInfo : IHNM_DisplayInfo; + return di.logicalWidth; +} + +int SagaEngine::getDisplayHeight() const { + const GameDisplayInfo &di = _gameDescription->gameType == GType_ITE ? ITE_DisplayInfo : IHNM_DisplayInfo; + return di.logicalHeight; +} + } // End of namespace Saga diff --git a/engines/saga/sagagame.cpp b/engines/saga/detection_tables.h index db13831669..404ef783c1 100644 --- a/engines/saga/sagagame.cpp +++ b/engines/saga/detection_tables.h @@ -1,154 +1,28 @@ -#define ITE_CONVERSE_MAX_TEXT_WIDTH (256 - 60) -#define ITE_CONVERSE_TEXT_HEIGHT 10 -#define ITE_CONVERSE_TEXT_LINES 4 - -//TODO: ihnm -#define IHNM_CONVERSE_MAX_TEXT_WIDTH (256 - 60) -#define IHNM_CONVERSE_TEXT_HEIGHT 10 -#define IHNM_CONVERSE_TEXT_LINES 10 - -// ITE section -static PanelButton ITE_MainPanelButtons[] = { - {kPanelButtonVerb, 52,4, 57,10, kVerbITEWalkTo,'w',0, 0,1,0}, - {kPanelButtonVerb, 52,15, 57,10, kVerbITELookAt,'l',0, 2,3,0}, - {kPanelButtonVerb, 52,26, 57,10, kVerbITEPickUp,'p',0, 4,5,0}, - {kPanelButtonVerb, 52,37, 57,10, kVerbITETalkTo,'t',0, 0,1,0}, - {kPanelButtonVerb, 110,4, 56,10, kVerbITEOpen,'o',0, 6,7,0}, - {kPanelButtonVerb, 110,15, 56,10, kVerbITEClose,'c',0, 8,9,0}, - {kPanelButtonVerb, 110,26, 56,10, kVerbITEUse,'u',0, 10,11,0}, - {kPanelButtonVerb, 110,37, 56,10, kVerbITEGive,'g',0, 12,13,0}, - {kPanelButtonArrow, 306,6, 8,5, -1,'U',0, 0,4,2}, - {kPanelButtonArrow, 306,41, 8,5, 1,'D',0, 1,5,3}, - - {kPanelButtonInventory, 181 + 32*0,6, 27,18, 0,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*1,6, 27,18, 1,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*2,6, 27,18, 2,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*3,6, 27,18, 3,'-',0, 0,0,0}, - - {kPanelButtonInventory, 181 + 32*0,27, 27,18, 4,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*1,27, 27,18, 5,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*2,27, 27,18, 6,'-',0, 0,0,0}, - {kPanelButtonInventory, 181 + 32*3,27, 27,18, 7,'-',0, 0,0,0} -}; - -static PanelButton ITE_ConversePanelButtons[] = { - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 0, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 0,'1',0, 0,0,0}, - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 1, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 1,'2',0, 0,0,0}, - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 2, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 2,'3',0, 0,0,0}, - {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 3, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 3,'4',0, 0,0,0}, - {kPanelButtonArrow, 257,6, 9,6, -1,'u',0, 0,4,2}, - {kPanelButtonArrow, 257,41, 9,6, 1,'d',0, 1,5,3}, -}; - -static PanelButton ITE_OptionPanelButtons[] = { - {kPanelButtonOptionSlider, 284,19, 13,75, 0,'-',0, 0,0,0}, //slider-scroller - {kPanelButtonOption, 113,18, 45,17, kTextReadingSpeed,'r',0, 0,0,0}, //read speed - {kPanelButtonOption, 113,37, 45,17, kTextMusic,'m',0, 0,0,0}, //music - {kPanelButtonOption, 113,56, 45,17, kTextSound,'n',0, 0,0,0}, //sound-noise - {kPanelButtonOption, 13,79, 135,17, kTextQuitGame,'q',0, 0,0,0}, //quit - {kPanelButtonOption, 13,98, 135,17, kTextContinuePlaying,'c',0, 0,0,0}, //continue - {kPanelButtonOption, 164,98, 57,17, kTextLoad,'l',0, 0,0,0}, //load - {kPanelButtonOption, 241,98, 57,17, kTextSave,'s',0, 0,0,0}, //save - {kPanelButtonOptionSaveFiles, 166,20, 112,74, 0,'-',0, 0,0,0}, //savefiles - - {kPanelButtonOptionText,106,4, 0,0, kTextGameOptions,'-',0, 0,0,0}, // text: game options - {kPanelButtonOptionText,11,22, 0,0, kTextReadingSpeed,'-',0, 0,0,0}, // text: read speed - {kPanelButtonOptionText,28,22, 0,0, kTextShowDialog,'-',0, 0,0,0}, // text: read speed - {kPanelButtonOptionText,73,41, 0,0, kTextMusic,'-',0, 0,0,0}, // text: music - {kPanelButtonOptionText,69,60, 0,0, kTextSound,'-',0, 0,0,0}, // text: noise -}; - -static PanelButton ITE_QuitPanelButtons[] = { - {kPanelButtonQuit, 11,17, 60,16, kTextQuit,'q',0, 0,0,0}, - {kPanelButtonQuit, 121,17, 60,16, kTextCancel,'c',0, 0,0,0}, - {kPanelButtonQuitText, -1,5, 0,0, kTextQuitTheGameQuestion,'-',0, 0,0,0}, -}; - -static PanelButton ITE_LoadPanelButtons[] = { - {kPanelButtonLoad, 101,19, 60,16, kTextOK,'o',0, 0,0,0}, - {kPanelButtonLoadText, -1,5, 0,0, kTextLoadSuccessful,'-',0, 0,0,0}, -}; - -static PanelButton ITE_SavePanelButtons[] = { - {kPanelButtonSave, 11,37, 60,16, kTextSave,'s',0, 0,0,0}, - {kPanelButtonSave, 101,37, 60,16, kTextCancel,'c',0, 0,0,0}, - {kPanelButtonSaveEdit, 26,17, 119,17, 0,'-',0, 0,0,0}, - {kPanelButtonSaveText, -1,5, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0}, -}; - -static PanelButton ITE_ProtectPanelButtons[] = { - {kPanelButtonProtectEdit, 26,17, 119,17, 0,'-',0, 0,0,0}, - {kPanelButtonProtectText, -1,5, 0,0, kTextEnterProtectAnswer,'-',0, 0,0,0}, -}; - -/* -static PanelButton ITE_ProtectionPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -};*/ - -static const GameDisplayInfo ITE_DisplayInfo = { - 320, 200, // logical width&height - - 35, // scene path y offset - 137, // scene height - - 0, // status x offset - 137, // status y offset - 320, // status width - 11, // status height - 2, // status text y offset - 186, // status text color - 15, // status BG color - 308,137, // save reminder pos - 12,12, // save reminder w & h - 6,7, // save reminder sprite numbers - - 5, 4, // left portrait x, y offset - 274, 4, // right portrait x, y offset - - 8, 9, // inventory Up & Down button indexies - 2, 4, // inventory rows, columns - - 0, 148, // main panel offsets - ARRAYSIZE(ITE_MainPanelButtons), - ITE_MainPanelButtons, - - ITE_CONVERSE_MAX_TEXT_WIDTH, - ITE_CONVERSE_TEXT_HEIGHT, - ITE_CONVERSE_TEXT_LINES, - 4, 5, // converse Up & Down button indexies - 0, 148, // converse panel offsets - ARRAYSIZE(ITE_ConversePanelButtons), - ITE_ConversePanelButtons, - - 8, 0, // save file index - 8, // optionSaveFileVisible - 8, 8, // option panel offsets - ARRAYSIZE(ITE_OptionPanelButtons), - ITE_OptionPanelButtons, - - 64,54, // quit panel offsets - 192,38, // quit panel width & height - ARRAYSIZE(ITE_QuitPanelButtons), - ITE_QuitPanelButtons, - - 74, 53, // load panel offsets - 172, 40, // load panel width & height - ARRAYSIZE(ITE_LoadPanelButtons), - ITE_LoadPanelButtons, - - 2, // save edit index - 74, 44, // save panel offsets - 172, 58, // save panel width & height - ARRAYSIZE(ITE_SavePanelButtons), - ITE_SavePanelButtons, - - 0, // protect edit index - 74, 44, // protect panel offsets - 172, 58, // protect panel width & height - ARRAYSIZE(ITE_ProtectPanelButtons), - ITE_ProtectPanelButtons -}; +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2007 The ScummVM project + * + * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +namespace Saga { static const GameResourceDescription ITE_Resources = { RID_ITE_SCENE_LUT, // Scene lookup table RN @@ -406,122 +280,6 @@ static const GamePatchDescription ITELinPatch_Files[] = { // IHNM section -static PanelButton IHNM_MainPanelButtons[] = { - {kPanelButtonVerb, 106,12, 114,30, kVerbIHNMWalk,'w',0, 0,1,0}, - {kPanelButtonVerb, 106,44, 114,30, kVerbIHNMLookAt,'l',0, 2,3,0}, - {kPanelButtonVerb, 106,76, 114,30, kVerbIHNMTake,'k',0, 4,5,0}, - {kPanelButtonVerb, 106,108, 114,30, kVerbIHNMUse,'u',0, 6,7,0}, - {kPanelButtonVerb, 223,12, 114,30, kVerbIHNMTalkTo,'t',0, 8,9,0}, - {kPanelButtonVerb, 223,44, 114,30, kVerbIHNMSwallow,'s',0, 10,11,0}, - {kPanelButtonVerb, 223,76, 114,30, kVerbIHNMGive,'g',0, 12,13,0}, - {kPanelButtonVerb, 223,108, 114,30, kVerbIHNMPush,'p',0, 14,15,0}, - {kPanelButtonArrow, 606,22, 20,25, -1,'[',0, 0,0,0}, //TODO: arrow Sprite Numbers - {kPanelButtonArrow, 606,108, 20,25, 1,']',0, 0,0,0}, - - {kPanelButtonInventory, 357 + 64*0,18, 54,54, 0,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*1,18, 54,54, 1,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*2,18, 54,54, 2,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*3,18, 54,54, 3,'-',0, 0,0,0}, - - {kPanelButtonInventory, 357 + 64*0,80, 54,54, 4,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*1,80, 54,54, 5,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*2,80, 54,54, 6,'-',0, 0,0,0}, - {kPanelButtonInventory, 357 + 64*3,80, 54,54, 7,'-',0, 0,0,0} -}; - -static PanelButton IHNM_ConversePanelButtons[] = { - {kPanelButtonConverseText, 117,18 + IHNM_CONVERSE_TEXT_HEIGHT * 0, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 0,'1',0, 0,0,0}, - {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 1, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 1,'2',0, 0,0,0}, - {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 2, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 2,'3',0, 0,0,0}, - {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 3, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 3,'4',0, 0,0,0}, - //..... - {kPanelButtonArrow, 606,22, 20,25, -1,'[',0, 0,0,0}, //TODO: arrow Sprite Numbers - {kPanelButtonArrow, 606,108, 20,25, 1,']',0, 0,0,0} -}; - -static PanelButton IHNM_OptionPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - -static PanelButton IHNM_QuitPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - -static PanelButton IHNM_LoadPanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - -static PanelButton IHNM_SavePanelButtons[] = { - {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO -}; - - -static const GameDisplayInfo IHNM_DisplayInfo = { //TODO: fill it all - 640, 480, // logical width&height - - 0, // scene path y offset - 304, // scene height - - 0, // status x offset - 304, // status y offset - 616, // status width - 24, // status height - 8, // status text y offset - 253, // status text color - 250, // status BG color - 616, 303, // save reminder pos - 24, 24, // save reminder w&h - 0,1, // save reminder sprite numbers - - 11, 12, // left portrait x, y offset - -1, -1, // right portrait x, y offset - - -1, -1, // inventory Up & Down button indexies - 2, 4, // inventory rows, columns - - 0, 328, // main panel offsets - ARRAYSIZE(IHNM_MainPanelButtons), - IHNM_MainPanelButtons, - - -1, -1, // converse Up & Down button indexies - - IHNM_CONVERSE_MAX_TEXT_WIDTH, - IHNM_CONVERSE_TEXT_HEIGHT, - IHNM_CONVERSE_TEXT_LINES, - 0, 328, // converse panel offsets - ARRAYSIZE(IHNM_ConversePanelButtons), - IHNM_ConversePanelButtons, - - -1, -1, // save file index - 0, // optionSaveFileVisible - 0, 0, // option panel offsets - ARRAYSIZE(IHNM_OptionPanelButtons), - IHNM_OptionPanelButtons, - - 0,0, // quit panel offsets - 0,0, // quit panel width & height - ARRAYSIZE(IHNM_QuitPanelButtons), - IHNM_QuitPanelButtons, - - 0, 0, // load panel offsets - 0, 0, // load panel width & height - ARRAYSIZE(IHNM_LoadPanelButtons), - IHNM_LoadPanelButtons, - - -1, // save edit index - 0, 0, // save panel offsets - 0, 0, // save panel width & height - ARRAYSIZE(IHNM_SavePanelButtons), - IHNM_SavePanelButtons, - - // No protection panel in IHNM - -1, // protect edit index - 0, 0, // protect panel offsets - 0, 0, // protect panel width & height - ARRAYSIZE(IHNM_SavePanelButtons), - IHNM_SavePanelButtons -}; - static const GameResourceDescription IHNM_Resources = { RID_IHNM_SCENE_LUT, // Scene lookup table RN RID_IHNM_SCRIPT_LUT, // Script lookup table RN @@ -581,7 +339,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_DEMO_G, // Game id 0, // features - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, // Starting scene number &ITEDemo_Resources, ARRAYSIZE(ITEDEMO_GameFonts), @@ -613,7 +370,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_MACDEMO2, GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -645,7 +401,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_MACDEMO1, GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -677,7 +432,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_MACCD_G, GF_BIG_ENDIAN_DATA | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -709,7 +463,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_MACCD, GF_BIG_ENDIAN_DATA | GF_WYRMKEEP | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -742,7 +495,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_LINDEMO, GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -774,7 +526,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_WINDEMO3, GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -805,7 +556,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_WINDEMO2, GF_WYRMKEEP | GF_CD_FX | GF_SCENE_SUBSTITUTES, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -836,7 +586,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_WINDEMO1, GF_WYRMKEEP | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEWINDEMO_GameFonts), @@ -873,7 +622,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_MULTICD, GF_WYRMKEEP | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -905,7 +653,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_LINCD, GF_WYRMKEEP | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -936,7 +683,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_WINCD, GF_WYRMKEEP | GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -967,7 +713,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_CD_G, GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -999,7 +744,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_CD_G2, GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -1031,7 +775,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_CD_DE, GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -1063,7 +806,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_CD_DE2, GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -1094,7 +836,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_CD, GF_CD_FX, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITECD_GameFonts), @@ -1124,7 +865,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_DISK_DE, 0, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEDISK_GameFonts), @@ -1155,7 +895,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_DISK_DE2, 0, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEDISK_GameFonts), @@ -1185,7 +924,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_DISK_G, 0, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEDISK_GameFonts), @@ -1216,7 +954,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_ITE, GID_ITE_DISK_G2, 0, - &ITE_DisplayInfo, ITE_DEFAULT_SCENE, &ITE_Resources, ARRAYSIZE(ITEDISK_GameFonts), @@ -1247,7 +984,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_IHNM, GID_IHNM_DEMO, 0, - &IHNM_DisplayInfo, 0, &IHNM_Resources, ARRAYSIZE(IHNMDEMO_GameFonts), @@ -1287,7 +1023,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_IHNM, GID_IHNM_CD, 0, - &IHNM_DisplayInfo, IHNM_DEFAULT_SCENE, &IHNM_Resources, ARRAYSIZE(IHNMCD_GameFonts), @@ -1328,7 +1063,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_IHNM, GID_IHNM_CD_DE, 0, - &IHNM_DisplayInfo, IHNM_DEFAULT_SCENE, &IHNM_Resources, ARRAYSIZE(IHNMCD_GameFonts), @@ -1368,7 +1102,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_IHNM, GID_IHNM_CD_ES, 0, - &IHNM_DisplayInfo, IHNM_DEFAULT_SCENE, &IHNM_Resources, ARRAYSIZE(IHNMCD_GameFonts), @@ -1408,7 +1141,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_IHNM, GID_IHNM_CD_RU, 0, - &IHNM_DisplayInfo, IHNM_DEFAULT_SCENE, &IHNM_Resources, ARRAYSIZE(IHNMCD_GameFonts), @@ -1447,7 +1179,6 @@ static const SAGAGameDescription gameDescriptions[] = { GType_IHNM, GID_IHNM_CD_FR, 0, - &IHNM_DisplayInfo, IHNM_DEFAULT_SCENE, &IHNM_Resources, ARRAYSIZE(IHNMCD_GameFonts), @@ -1458,5 +1189,7 @@ static const SAGAGameDescription gameDescriptions[] = { 0, NULL, }, - { AD_TABLE_END_MARKER, 0, 0, 0, NULL, 0, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL } + { AD_TABLE_END_MARKER, 0, 0, 0, 0, NULL, 0, NULL, NULL, NULL, NULL, 0, NULL } }; + +} // End of namespace Saga diff --git a/engines/saga/displayinfo.h b/engines/saga/displayinfo.h new file mode 100644 index 0000000000..6bf58eca9b --- /dev/null +++ b/engines/saga/displayinfo.h @@ -0,0 +1,422 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004-2007 The ScummVM project + * + * The ReInherit Engine is (C)2000-2003 by Daniel Balsom. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SAGA_DISPLAYINFO_H +#define SAGA_DISPLAYINFO_H + +namespace Saga { + +struct PanelButton { + PanelButtonType type; + int xOffset; + int yOffset; + int width; + int height; + int id; + uint16 ascii; + int state; + int upSpriteNumber; + int downSpriteNumber; + int overSpriteNumber; +}; + +struct GameDisplayInfo { + int logicalWidth; + int logicalHeight; + + int pathStartY; + int sceneHeight; + + int statusXOffset; + int statusYOffset; + int statusWidth; + int statusHeight; + int statusTextY; + int statusTextColor; + int statusBGColor; + + int saveReminderXOffset; + int saveReminderYOffset; + int saveReminderWidth; + int saveReminderHeight; + int saveReminderFirstSpriteNumber; + int saveReminderSecondSpriteNumber; + + int leftPortraitXOffset; + int leftPortraitYOffset; + int rightPortraitXOffset; + int rightPortraitYOffset; + + int inventoryUpButtonIndex; + int inventoryDownButtonIndex; + int inventoryRows; + int inventoryColumns; + + int mainPanelXOffset; + int mainPanelYOffset; + int mainPanelButtonsCount; + PanelButton *mainPanelButtons; + + int converseMaxTextWidth; + int converseTextHeight; + int converseTextLines; + int converseUpButtonIndex; + int converseDownButtonIndex; + + int conversePanelXOffset; + int conversePanelYOffset; + int conversePanelButtonsCount; + PanelButton *conversePanelButtons; + + int optionSaveFilePanelIndex; + int optionSaveFileSliderIndex; + uint32 optionSaveFileVisible; + + int optionPanelXOffset; + int optionPanelYOffset; + int optionPanelButtonsCount; + PanelButton *optionPanelButtons; + + int quitPanelXOffset; + int quitPanelYOffset; + int quitPanelWidth; + int quitPanelHeight; + int quitPanelButtonsCount; + PanelButton *quitPanelButtons; + + int loadPanelXOffset; + int loadPanelYOffset; + int loadPanelWidth; + int loadPanelHeight; + int loadPanelButtonsCount; + PanelButton *loadPanelButtons; + + int saveEditIndex; + int savePanelXOffset; + int savePanelYOffset; + int savePanelWidth; + int savePanelHeight; + int savePanelButtonsCount; + PanelButton *savePanelButtons; + + int protectEditIndex; + int protectPanelXOffset; + int protectPanelYOffset; + int protectPanelWidth; + int protectPanelHeight; + int protectPanelButtonsCount; + PanelButton *protectPanelButtons; +}; + +#define ITE_CONVERSE_MAX_TEXT_WIDTH (256 - 60) +#define ITE_CONVERSE_TEXT_HEIGHT 10 +#define ITE_CONVERSE_TEXT_LINES 4 + +// ITE section +static PanelButton ITE_MainPanelButtons[] = { + {kPanelButtonVerb, 52,4, 57,10, kVerbITEWalkTo,'w',0, 0,1,0}, + {kPanelButtonVerb, 52,15, 57,10, kVerbITELookAt,'l',0, 2,3,0}, + {kPanelButtonVerb, 52,26, 57,10, kVerbITEPickUp,'p',0, 4,5,0}, + {kPanelButtonVerb, 52,37, 57,10, kVerbITETalkTo,'t',0, 0,1,0}, + {kPanelButtonVerb, 110,4, 56,10, kVerbITEOpen,'o',0, 6,7,0}, + {kPanelButtonVerb, 110,15, 56,10, kVerbITEClose,'c',0, 8,9,0}, + {kPanelButtonVerb, 110,26, 56,10, kVerbITEUse,'u',0, 10,11,0}, + {kPanelButtonVerb, 110,37, 56,10, kVerbITEGive,'g',0, 12,13,0}, + {kPanelButtonArrow, 306,6, 8,5, -1,'U',0, 0,4,2}, + {kPanelButtonArrow, 306,41, 8,5, 1,'D',0, 1,5,3}, + + {kPanelButtonInventory, 181 + 32*0,6, 27,18, 0,'-',0, 0,0,0}, + {kPanelButtonInventory, 181 + 32*1,6, 27,18, 1,'-',0, 0,0,0}, + {kPanelButtonInventory, 181 + 32*2,6, 27,18, 2,'-',0, 0,0,0}, + {kPanelButtonInventory, 181 + 32*3,6, 27,18, 3,'-',0, 0,0,0}, + + {kPanelButtonInventory, 181 + 32*0,27, 27,18, 4,'-',0, 0,0,0}, + {kPanelButtonInventory, 181 + 32*1,27, 27,18, 5,'-',0, 0,0,0}, + {kPanelButtonInventory, 181 + 32*2,27, 27,18, 6,'-',0, 0,0,0}, + {kPanelButtonInventory, 181 + 32*3,27, 27,18, 7,'-',0, 0,0,0} +}; + +static PanelButton ITE_ConversePanelButtons[] = { + {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 0, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 0,'1',0, 0,0,0}, + {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 1, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 1,'2',0, 0,0,0}, + {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 2, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 2,'3',0, 0,0,0}, + {kPanelButtonConverseText, 52,6 + ITE_CONVERSE_TEXT_HEIGHT * 3, ITE_CONVERSE_MAX_TEXT_WIDTH,ITE_CONVERSE_TEXT_HEIGHT, 3,'4',0, 0,0,0}, + {kPanelButtonArrow, 257,6, 9,6, -1,'u',0, 0,4,2}, + {kPanelButtonArrow, 257,41, 9,6, 1,'d',0, 1,5,3}, +}; + +static PanelButton ITE_OptionPanelButtons[] = { + {kPanelButtonOptionSlider, 284,19, 13,75, 0,'-',0, 0,0,0}, //slider-scroller + {kPanelButtonOption, 113,18, 45,17, kTextReadingSpeed,'r',0, 0,0,0}, //read speed + {kPanelButtonOption, 113,37, 45,17, kTextMusic,'m',0, 0,0,0}, //music + {kPanelButtonOption, 113,56, 45,17, kTextSound,'n',0, 0,0,0}, //sound-noise + {kPanelButtonOption, 13,79, 135,17, kTextQuitGame,'q',0, 0,0,0}, //quit + {kPanelButtonOption, 13,98, 135,17, kTextContinuePlaying,'c',0, 0,0,0}, //continue + {kPanelButtonOption, 164,98, 57,17, kTextLoad,'l',0, 0,0,0}, //load + {kPanelButtonOption, 241,98, 57,17, kTextSave,'s',0, 0,0,0}, //save + {kPanelButtonOptionSaveFiles, 166,20, 112,74, 0,'-',0, 0,0,0}, //savefiles + + {kPanelButtonOptionText,106,4, 0,0, kTextGameOptions,'-',0, 0,0,0}, // text: game options + {kPanelButtonOptionText,11,22, 0,0, kTextReadingSpeed,'-',0, 0,0,0}, // text: read speed + {kPanelButtonOptionText,28,22, 0,0, kTextShowDialog,'-',0, 0,0,0}, // text: read speed + {kPanelButtonOptionText,73,41, 0,0, kTextMusic,'-',0, 0,0,0}, // text: music + {kPanelButtonOptionText,69,60, 0,0, kTextSound,'-',0, 0,0,0}, // text: noise +}; + +static PanelButton ITE_QuitPanelButtons[] = { + {kPanelButtonQuit, 11,17, 60,16, kTextQuit,'q',0, 0,0,0}, + {kPanelButtonQuit, 121,17, 60,16, kTextCancel,'c',0, 0,0,0}, + {kPanelButtonQuitText, -1,5, 0,0, kTextQuitTheGameQuestion,'-',0, 0,0,0}, +}; + +static PanelButton ITE_LoadPanelButtons[] = { + {kPanelButtonLoad, 101,19, 60,16, kTextOK,'o',0, 0,0,0}, + {kPanelButtonLoadText, -1,5, 0,0, kTextLoadSuccessful,'-',0, 0,0,0}, +}; + +static PanelButton ITE_SavePanelButtons[] = { + {kPanelButtonSave, 11,37, 60,16, kTextSave,'s',0, 0,0,0}, + {kPanelButtonSave, 101,37, 60,16, kTextCancel,'c',0, 0,0,0}, + {kPanelButtonSaveEdit, 26,17, 119,17, 0,'-',0, 0,0,0}, + {kPanelButtonSaveText, -1,5, 0,0, kTextEnterSaveGameName,'-',0, 0,0,0}, +}; + +static PanelButton ITE_ProtectPanelButtons[] = { + {kPanelButtonProtectEdit, 26,17, 119,17, 0,'-',0, 0,0,0}, + {kPanelButtonProtectText, -1,5, 0,0, kTextEnterProtectAnswer,'-',0, 0,0,0}, +}; + +/* +static PanelButton ITE_ProtectionPanelButtons[] = { + {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO +};*/ + +static const GameDisplayInfo ITE_DisplayInfo = { + 320, 200, // logical width&height + + 35, // scene path y offset + 137, // scene height + + 0, // status x offset + 137, // status y offset + 320, // status width + 11, // status height + 2, // status text y offset + 186, // status text color + 15, // status BG color + 308,137, // save reminder pos + 12,12, // save reminder w & h + 6,7, // save reminder sprite numbers + + 5, 4, // left portrait x, y offset + 274, 4, // right portrait x, y offset + + 8, 9, // inventory Up & Down button indexies + 2, 4, // inventory rows, columns + + 0, 148, // main panel offsets + ARRAYSIZE(ITE_MainPanelButtons), + ITE_MainPanelButtons, + + ITE_CONVERSE_MAX_TEXT_WIDTH, + ITE_CONVERSE_TEXT_HEIGHT, + ITE_CONVERSE_TEXT_LINES, + 4, 5, // converse Up & Down button indexies + 0, 148, // converse panel offsets + ARRAYSIZE(ITE_ConversePanelButtons), + ITE_ConversePanelButtons, + + 8, 0, // save file index + 8, // optionSaveFileVisible + 8, 8, // option panel offsets + ARRAYSIZE(ITE_OptionPanelButtons), + ITE_OptionPanelButtons, + + 64,54, // quit panel offsets + 192,38, // quit panel width & height + ARRAYSIZE(ITE_QuitPanelButtons), + ITE_QuitPanelButtons, + + 74, 53, // load panel offsets + 172, 40, // load panel width & height + ARRAYSIZE(ITE_LoadPanelButtons), + ITE_LoadPanelButtons, + + 2, // save edit index + 74, 44, // save panel offsets + 172, 58, // save panel width & height + ARRAYSIZE(ITE_SavePanelButtons), + ITE_SavePanelButtons, + + 0, // protect edit index + 74, 44, // protect panel offsets + 172, 58, // protect panel width & height + ARRAYSIZE(ITE_ProtectPanelButtons), + ITE_ProtectPanelButtons +}; + + +//TODO: ihnm +#define IHNM_CONVERSE_MAX_TEXT_WIDTH (256 - 60) +#define IHNM_CONVERSE_TEXT_HEIGHT 10 +#define IHNM_CONVERSE_TEXT_LINES 10 + +static PanelButton IHNM_MainPanelButtons[] = { + // TODO: The +2's are needed here to fix the verbs, investigate why + // The computation of textid in Interface::drawVerbPanelText has also been changed accordingly + {kPanelButtonVerb, 106,12, 114,30, kVerbIHNMWalk + 2,'w',0, 0,1,0}, + {kPanelButtonVerb, 106,44, 114,30, kVerbIHNMLookAt + 2,'l',0, 2,3,0}, + {kPanelButtonVerb, 106,76, 114,30, kVerbIHNMTake + 2,'k',0, 4,5,0}, + {kPanelButtonVerb, 106,108, 114,30, kVerbIHNMUse + 2,'u',0, 6,7,0}, + {kPanelButtonVerb, 223,12, 114,30, kVerbIHNMTalkTo + 2,'t',0, 8,9,0}, + {kPanelButtonVerb, 223,44, 114,30, kVerbIHNMSwallow + 2,'s',0, 10,11,0}, + {kPanelButtonVerb, 223,76, 114,30, kVerbIHNMGive + 2,'g',0, 12,13,0}, + {kPanelButtonVerb, 223,108, 114,30, kVerbIHNMPush + 2,'p',0, 14,15,0}, + {kPanelButtonArrow, 606,22, 20,25, -1,'[',0, 0,0,0}, //TODO: arrow Sprite Numbers + {kPanelButtonArrow, 606,108, 20,25, 1,']',0, 0,0,0}, + + {kPanelButtonInventory, 357 + 64*0,18, 54,54, 0,'-',0, 0,0,0}, + {kPanelButtonInventory, 357 + 64*1,18, 54,54, 1,'-',0, 0,0,0}, + {kPanelButtonInventory, 357 + 64*2,18, 54,54, 2,'-',0, 0,0,0}, + {kPanelButtonInventory, 357 + 64*3,18, 54,54, 3,'-',0, 0,0,0}, + + {kPanelButtonInventory, 357 + 64*0,80, 54,54, 4,'-',0, 0,0,0}, + {kPanelButtonInventory, 357 + 64*1,80, 54,54, 5,'-',0, 0,0,0}, + {kPanelButtonInventory, 357 + 64*2,80, 54,54, 6,'-',0, 0,0,0}, + {kPanelButtonInventory, 357 + 64*3,80, 54,54, 7,'-',0, 0,0,0} +}; + +static PanelButton IHNM_ConversePanelButtons[] = { + {kPanelButtonConverseText, 117,18 + IHNM_CONVERSE_TEXT_HEIGHT * 0, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 0,'1',0, 0,0,0}, + {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 1, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 1,'2',0, 0,0,0}, + {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 2, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 2,'3',0, 0,0,0}, + {kPanelButtonConverseText, 52,18 + IHNM_CONVERSE_TEXT_HEIGHT * 3, IHNM_CONVERSE_MAX_TEXT_WIDTH,IHNM_CONVERSE_TEXT_HEIGHT, 3,'4',0, 0,0,0}, + //..... + {kPanelButtonArrow, 606,22, 20,25, -1,'[',0, 0,0,0}, //TODO: arrow Sprite Numbers + {kPanelButtonArrow, 606,108, 20,25, 1,']',0, 0,0,0} +}; + +static PanelButton IHNM_OptionPanelButtons[] = { + //TODO: Add the rest of the buttons + {kPanelButtonOptionText,28,36, 0,0, kTextReadingSpeed,'-',0, 0,0,0}, // text: read speed + {kPanelButtonOptionText,60,61, 0,0, kTextMusic,'-',0, 0,0,0}, // text: music + {kPanelButtonOptionText,60,86, 0,0, kTextSound,'-',0, 0,0,0}, // text: noise + // TODO: Add Voices text here + {kPanelButtonOption, 154,30, 79,23, kTextReadingSpeed,'r',0, 0,0,0}, //read speed + {kPanelButtonOption, 154,55, 79,23, kTextMusic,'m',0, 0,0,0}, //music + {kPanelButtonOption, 154,80, 79,23, kTextSound,'n',0, 0,0,0}, //sound-noise + // TODO: Add Voices widget here + {kPanelButtonOption, 19,149, 200,25, kTextQuitGame,'q',0, 0,0,0}, //quit + {kPanelButtonOption, 19,177, 200,25, kTextContinuePlaying,'c',0, 0,0,0}, //continue + // TODO: Implement load/save + {kPanelButtonOption, 244,164, 79,23, kTextLoad,'l',0, 0,0,0}, //load + {kPanelButtonOption, 335,164, 79,23, kTextSave,'s',0, 0,0,0}, //save +}; + +static PanelButton IHNM_QuitPanelButtons[] = { + //FIXME: Show the correct quit dialog background + //TODO: Those coordinates might not be pixel perfect, check with the original interpreter + {kPanelButtonQuit, 25,80, 80,25, kTextQuit,'q',0, 0,0,0}, + {kPanelButtonQuit, 155,80, 80,25, kTextCancel,'c',0, 0,0,0}, + {kPanelButtonQuitText, -1,5, 0,0, kTextQuitTheGameQuestion,'-',0, 0,0,0}, +}; + +static PanelButton IHNM_LoadPanelButtons[] = { + {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO +}; + +static PanelButton IHNM_SavePanelButtons[] = { + {kPanelButtonArrow, 0,0, 0,0, 0,'-',0, 0,0,0}, //TODO +}; + + +static const GameDisplayInfo IHNM_DisplayInfo = { //TODO: fill it all + 640, 480, // logical width&height + + 0, // scene path y offset + 304, // scene height + + 0, // status x offset + 304, // status y offset + 616, // status width + 24, // status height + 8, // status text y offset + 253, // status text color + 250, // status BG color + 616, 303, // save reminder pos + 24, 24, // save reminder w&h + 0,1, // save reminder sprite numbers + + 11, 12, // left portrait x, y offset + -1, -1, // right portrait x, y offset + + -1, -1, // inventory Up & Down button indexies + 2, 4, // inventory rows, columns + + 0, 328, // main panel offsets + ARRAYSIZE(IHNM_MainPanelButtons), + IHNM_MainPanelButtons, + + -1, -1, // converse Up & Down button indexies + + IHNM_CONVERSE_MAX_TEXT_WIDTH, + IHNM_CONVERSE_TEXT_HEIGHT, + IHNM_CONVERSE_TEXT_LINES, + 0, 328, // converse panel offsets + ARRAYSIZE(IHNM_ConversePanelButtons), + IHNM_ConversePanelButtons, + + -1, -1, // save file index + 0, // optionSaveFileVisible + 92, 46, // option panel offsets + ARRAYSIZE(IHNM_OptionPanelButtons), + IHNM_OptionPanelButtons, + + 190,180, // quit panel offsets + 260,115, // quit panel width & height + ARRAYSIZE(IHNM_QuitPanelButtons), + IHNM_QuitPanelButtons, + + 0, 0, // load panel offsets + 0, 0, // load panel width & height + ARRAYSIZE(IHNM_LoadPanelButtons), + IHNM_LoadPanelButtons, + + -1, // save edit index + 0, 0, // save panel offsets + 0, 0, // save panel width & height + ARRAYSIZE(IHNM_SavePanelButtons), + IHNM_SavePanelButtons, + + // No protection panel in IHNM + -1, // protect edit index + 0, 0, // protect panel offsets + 0, 0, // protect panel width & height + ARRAYSIZE(IHNM_SavePanelButtons), + IHNM_SavePanelButtons +}; + +} // End of namespace Saga + +#endif diff --git a/engines/saga/events.cpp b/engines/saga/events.cpp index b3e2230c5b..f58b17ca17 100644 --- a/engines/saga/events.cpp +++ b/engines/saga/events.cpp @@ -437,6 +437,15 @@ int Events::handleOneShot(Event *event) { case kEventHide: _vm->_gfx->showCursor(false); break; + case kEventSetNormalCursor: + // in ITE there is just one cursor + if (_vm->getGameType() == GType_IHNM) + _vm->_gfx->setCursor(kCursorNormal); + break; + case kEventSetBusyCursor: + if (_vm->getGameType() == GType_IHNM) + _vm->_gfx->setCursor(kCursorBusy); + break; default: break; } diff --git a/engines/saga/events.h b/engines/saga/events.h index d89b3d89f5..2e4d9cf987 100644 --- a/engines/saga/events.h +++ b/engines/saga/events.h @@ -97,6 +97,8 @@ enum EventOps { // CURSOR events kEventShow = 1, // kEventHide = 2, // reused + kEventSetNormalCursor = 3, + kEventSetBusyCursor = 4, // GRAPHICS events kEventFillRect = 1, // kEventSetFlag = 4, // reused diff --git a/engines/saga/gfx.h b/engines/saga/gfx.h index 0ffd0ea434..ab161a9420 100644 --- a/engines/saga/gfx.h +++ b/engines/saga/gfx.h @@ -148,9 +148,9 @@ public: void palToBlack(PalEntry *src_pal, double percent); void blackToPal(PalEntry *src_pal, double percent); void showCursor(bool state); + void setCursor(CursorType cursorType = kCursorNormal); private: - void setCursor(CursorType cursorType = kCursorNormal); int _init; Surface _backBuffer; byte _currentPal[PAL_ENTRIES * 4]; diff --git a/engines/saga/interface.cpp b/engines/saga/interface.cpp index 7c37126d59..2d15db80ee 100644 --- a/engines/saga/interface.cpp +++ b/engines/saga/interface.cpp @@ -28,6 +28,7 @@ #include "saga/gfx.h" #include "saga/actor.h" #include "saga/console.h" +#include "saga/displayinfo.h" #include "saga/events.h" #include "saga/font.h" #include "saga/objectmap.h" @@ -68,14 +69,14 @@ static int verbTypeToTextStringsIdLUT[2][kVerbTypeIdsMax] = { -1, -1}, {-1, - 3, //TODO:check - 2, - 1, - 5, - 6, //TODO:check - 8, //TODO:check - 7, - 4} + kVerbIHNMWalk, + kVerbIHNMLookAt, + kVerbIHNMTake, + kVerbIHNMUse, + kVerbIHNMTalkTo, + kVerbIHNMSwallow, + kVerbIHNMGive, + kVerbIHNMPush} }; Interface::Interface(SagaEngine *vm) : _vm(vm) { @@ -535,6 +536,10 @@ void Interface::setStatusText(const char *text, int statusColor) { assert(text != NULL); assert(strlen(text) < STATUS_TEXT_LEN); + // Disable the status text in IHNM when the chapter is 8 + if (_vm->getGameType() == GType_IHNM && _vm->_scene->currentChapterNumber() == 8) + return; + if (_vm->_render->getFlags() & (RF_PLACARD | RF_MAP)) return; @@ -696,14 +701,20 @@ void Interface::drawPanelText(Surface *ds, InterfacePanel *panel, PanelButton *p text = _vm->getTextString(panelButton->id); panel->calcPanelButtonRect(panelButton, rect); if (panelButton->xOffset < 0) { - textWidth = _vm->_font->getStringWidth(kKnownFontMedium, text, 0, kFontNormal); + if (_vm->getGameType() == GType_ITE) + textWidth = _vm->_font->getStringWidth(kKnownFontMedium, text, 0, kFontNormal); + else + textWidth = _vm->_font->getStringWidth(kKnownFontVerb, text, 0, kFontNormal); rect.left += 2 + (panel->imageWidth - 1 - textWidth) / 2; } textPoint.x = rect.left; textPoint.y = rect.top + 1; - _vm->_font->textDraw(kKnownFontMedium, ds, text, textPoint, _vm->KnownColor2ColorId(kKnownColorVerbText), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); + if (_vm->getGameType() == GType_ITE) + _vm->_font->textDraw(kKnownFontMedium, ds, text, textPoint, _vm->KnownColor2ColorId(kKnownColorVerbText), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); + else + _vm->_font->textDraw(kKnownFontVerb, ds, text, textPoint, _vm->KnownColor2ColorId(kKnownColorVerbText), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); } void Interface::drawOption() { @@ -718,7 +729,7 @@ void Interface::drawOption() { Rect rect2; PanelButton *panelButton; Point textPoint; - if (_optionSaveFileSlider == NULL) return;//TODO:REMOVE + Point point; backBuffer = _vm->_gfx->getBackBuffer(); @@ -727,6 +738,15 @@ void Interface::drawOption() { for (i = 0; i < _optionPanel.buttonsCount; i++) { panelButton = &_optionPanel.buttons[i]; + + // TODO: This probably works for the button background, but the resources are still not loeaded + // (_optionPanel.sprites) + /* + point.x = _optionPanel.x + panelButton->xOffset; + point.y = _optionPanel.y + panelButton->yOffset; + _vm->_sprite->draw(backBuffer, _vm->getDisplayClip(), _optionPanel.sprites, i, point, 256); + */ + if (panelButton->type == kPanelButtonOption) { drawPanelButtonText(backBuffer, &_optionPanel, panelButton); } @@ -736,9 +756,17 @@ void Interface::drawOption() { } if (_optionSaveRectTop.height() > 0) { - backBuffer->drawRect(_optionSaveRectTop, kITEColorDarkGrey); + if (_vm->getGameType() == GType_ITE) { + backBuffer->drawRect(_optionSaveRectTop, kITEColorDarkGrey); + } else { + // TODO: Draw the button graphic properly for IHNM + } } + // FIXME: The _optionSaveFileSlider checks exist for IHNM, where + // _optionSaveFileSlider is not initialized correctly yet + if (_optionSaveFileSlider == NULL) return; //TODO:REMOVE + drawButtonBox(backBuffer, _optionSaveRectSlider, kSlider, _optionSaveFileSlider->state > 0); if (_optionSaveRectBottom.height() > 0) { @@ -1496,14 +1524,12 @@ void Interface::drawStatusBar() { int stringWidth; int color; - if (_panelMode == kPanelChapterSelection) + // Disable the status text in IHNM when the chapter is 8 + if (_vm->getGameType() == GType_IHNM && _vm->_scene->currentChapterNumber() == 8) return; backBuffer = _vm->_gfx->getBackBuffer(); - // Disable this for IHNM for now, since that game uses the full screen - // in some cases. - // Erase background of status bar rect.left = _vm->getDisplayInfo().statusXOffset; rect.top = _vm->getDisplayInfo().statusYOffset; @@ -1889,8 +1915,13 @@ void Interface::drawPanelButtonText(Surface *ds, InterfacePanel *panel, PanelBut } text = _vm->getTextString(textId); - textWidth = _vm->_font->getStringWidth(kKnownFontMedium, text, 0, kFontNormal); - textHeight = _vm->_font->getHeight(kKnownFontMedium); + if (_vm->getGameType() == GType_ITE) { + textWidth = _vm->_font->getStringWidth(kKnownFontMedium, text, 0, kFontNormal); + textHeight = _vm->_font->getHeight(kKnownFontMedium); + } else { + textWidth = _vm->_font->getStringWidth(kKnownFontVerb, text, 0, kFontNormal); + textHeight = _vm->_font->getHeight(kKnownFontVerb); + } point.x = panel->x + panelButton->xOffset + (panelButton->width / 2) - (textWidth / 2); point.y = panel->y + panelButton->yOffset + (panelButton->height / 2) - (textHeight / 2); @@ -1904,8 +1935,12 @@ void Interface::drawPanelButtonText(Surface *ds, InterfacePanel *panel, PanelBut panel->calcPanelButtonRect(panelButton, rect); drawButtonBox(ds, rect, kButton, panelButton->state > 0); - _vm->_font->textDraw(kKnownFontMedium, ds, text, point, - _vm->KnownColor2ColorId(textColor), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); + if (_vm->getGameType() == GType_ITE) + _vm->_font->textDraw(kKnownFontMedium, ds, text, point, + _vm->KnownColor2ColorId(textColor), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); + else + _vm->_font->textDraw(kKnownFontVerb, ds, text, point, + _vm->KnownColor2ColorId(textColor), _vm->KnownColor2ColorId(kKnownColorVerbTextShadow), kFontShadow); } void Interface::drawPanelButtonArrow(Surface *ds, InterfacePanel *panel, PanelButton *panelButton) { @@ -1938,7 +1973,8 @@ void Interface::drawVerbPanelText(Surface *ds, PanelButton *panelButton, KnownCo textId = verbTypeToTextStringsIdLUT[0][panelButton->id]; text = _vm->getTextString(textId); } else { - textId = verbTypeToTextStringsIdLUT[1][panelButton->id]; + // This -2 has been placed because of the changes in the ids in IHNM_MainPanelButtons + textId = verbTypeToTextStringsIdLUT[1][panelButton->id - 2]; text = _vm->_script->_mainStrings.getString(textId + 1); textShadowKnownColor = kKnownColorTransparent; } diff --git a/engines/saga/interface.h b/engines/saga/interface.h index 6dfaaa4984..a69d94b6b9 100644 --- a/engines/saga/interface.h +++ b/engines/saga/interface.h @@ -29,6 +29,7 @@ #include "common/savefile.h" +#include "saga/displayinfo.h" #include "saga/sprite.h" #include "saga/script.h" diff --git a/engines/saga/module.mk b/engines/saga/module.mk index 205e243a72..6c1812ad23 100644 --- a/engines/saga/module.mk +++ b/engines/saga/module.mk @@ -4,10 +4,10 @@ MODULE_OBJS := \ actor.o \ animation.o \ console.o \ + detection.o \ events.o \ font.o \ font_map.o \ - game.o \ gfx.o \ ihnm_introproc.o \ image.o \ diff --git a/engines/saga/music.cpp b/engines/saga/music.cpp index fc031c07ce..0126e79b6b 100644 --- a/engines/saga/music.cpp +++ b/engines/saga/music.cpp @@ -30,9 +30,6 @@ #include "sound/audiostream.h" #include "sound/mididrv.h" #include "sound/midiparser.h" -#include "sound/mp3.h" -#include "sound/vorbis.h" -#include "sound/flac.h" #include "common/config-manager.h" #include "common/file.h" @@ -40,24 +37,6 @@ namespace Saga { #define BUFFER_SIZE 4096 -struct TrackFormat { - Audio::DigitalTrackInfo* (*openTrackFunction)(int); -}; - -static const TrackFormat TRACK_FORMATS[] = { -#ifdef USE_FLAC - { Audio::getFlacTrack }, -#endif -#ifdef USE_VORBIS - { Audio::getVorbisTrack }, -#endif -#ifdef USE_MAD - { Audio::getMP3Track }, -#endif - - { NULL } // Terminator -}; - // I haven't decided yet if it's a good idea to make looping part of the audio // stream class, or if I should use a "wrapper" class, like I did for Broken // Sword 2, to make it easier to add support for compressed music... but I'll @@ -307,8 +286,6 @@ Music::Music(SagaEngine *vm, Audio::Mixer *mixer, MidiDriver *driver, int enable _songTableLen = 0; _songTable = 0; - _track = NULL; - _midiMusicData = NULL; } @@ -411,13 +388,18 @@ void Music::play(uint32 resourceId, MusicFlags flags) { } // Try to open standalone digital track - for (int i = 0; i < ARRAYSIZE(TRACK_FORMATS) - 1; ++i) - if ((_track = TRACK_FORMATS[i].openTrackFunction(realTrackNumber))) { - break; + char trackName[2][16]; + sprintf(trackName[0], "track%d", realTrackNumber); + sprintf(trackName[1], "track%02d", realTrackNumber); + Audio::AudioStream *stream = 0; + for (int i = 0; i < 2; ++i) { + // We multiply by 40 / 3 = 1000 / 75 to convert frames to milliseconds + // FIXME: Do we really want a duration of 10000 frames = 133 seconds, or is that just a random value? + stream = Audio::AudioStream::openStreamFile(trackName[i], 0, 10000 * 40 / 3, (flags == MUSIC_LOOP) ? 0 : 1); + if (stream) { + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_musicHandle, stream); + return; } - if (_track) { - _track->play(_mixer, &_musicHandle, (flags == MUSIC_LOOP) ? -1 : 1, 0, 10000); - return; } if (_vm->getGameType() == GType_ITE) { diff --git a/engines/saga/music.h b/engines/saga/music.h index b02c8c9eb1..4e14f3fc01 100644 --- a/engines/saga/music.h +++ b/engines/saga/music.h @@ -137,8 +137,6 @@ private: MidiParser *xmidiParser; MidiParser *smfParser; - Audio::DigitalTrackInfo *_track; - byte *_midiMusicData; static void musicVolumeGaugeCallback(void *refCon); diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp index 6094bc4387..264863d043 100644 --- a/engines/saga/saga.cpp +++ b/engines/saga/saga.cpp @@ -156,7 +156,7 @@ int SagaEngine::init() { // Detect game and open resource files if (!initGame()) { - GUIErrorMessage("No valid games were found in the specified directory."); + GUIErrorMessage("Error loading game resources."); return FAILURE; } diff --git a/engines/saga/saga.h b/engines/saga/saga.h index 832d5292bc..0d9a464e19 100644 --- a/engines/saga/saga.h +++ b/engines/saga/saga.h @@ -87,8 +87,237 @@ enum ERRORCODE { SUCCESS = 0 }; -#include "sagagame.h" +enum SAGAGameType { + GType_ITE = 0, + GType_IHNM = 1 +}; + +enum GameIds { + // Dreamers Guild + GID_ITE_DEMO_G = 0, + GID_ITE_DISK_G, + GID_ITE_DISK_G2, + GID_ITE_CD_G, + GID_ITE_CD_G2, + GID_ITE_MACCD_G, + + // Wyrmkeep + GID_ITE_CD, // data for Win rerelease is same as in old DOS + GID_ITE_WINCD, // but it has a bunch of patch files + GID_ITE_MACCD, + GID_ITE_LINCD, + GID_ITE_MULTICD, // Wyrmkeep combined Windows/Mac/Linux version + GID_ITE_WINDEMO1, // older Wyrmkeep windows demo + GID_ITE_MACDEMO1, // older Wyrmkeep mac demo + GID_ITE_LINDEMO, + GID_ITE_WINDEMO2, + GID_ITE_WINDEMO3, + GID_ITE_MACDEMO2, + + // German + GID_ITE_DISK_DE, + GID_ITE_DISK_DE2, + GID_ITE_AMIGACD_DE, // TODO + GID_ITE_OLDMAC_DE, // TODO + GID_ITE_AMIGA_FL_DE,// TODO + GID_ITE_CD_DE, // reported by mld. Bestsellergamers cover disk + GID_ITE_CD_DE2, + GID_ITE_AMIGA_AGA_DEMO, // TODO + GID_ITE_AMIGA_ECS_DEMO, // TODO + + GID_IHNM_DEMO, + GID_IHNM_CD, + GID_IHNM_CD_DE, // reported by mld. German retail + GID_IHNM_CD_ES, + GID_IHNM_CD_RU, + GID_IHNM_CD_FR +}; + +enum GameFileTypes { + GAME_RESOURCEFILE = 1 << 0, + GAME_SCRIPTFILE = 1 << 1, + GAME_SOUNDFILE = 1 << 2, + GAME_VOICEFILE = 1 << 3, + GAME_DEMOFILE = 1 << 4, + GAME_MUSICFILE = 1 << 5, + GAME_MUSICFILE_GM = 1 << 6, + GAME_MUSICFILE_FM = 1 << 7, + GAME_PATCHFILE = 1 << 8, + GAME_MACBINARY = 1 << 9, + GAME_SWAPENDIAN = 1 << 10 +}; + +enum GameFeatures { + GF_BIG_ENDIAN_DATA = 1 << 0, + GF_WYRMKEEP = 1 << 1, + GF_CD_FX = 1 << 2, + GF_SCENE_SUBSTITUTES = 1 << 3 +}; + +enum VerbTypeIds { + kVerbITENone = 0, + kVerbITEPickUp = 1, + kVerbITELookAt = 2, + kVerbITEWalkTo = 3, + kVerbITETalkTo = 4, + kVerbITEOpen = 5, + kVerbITEClose = 6, + kVerbITEGive = 7, + kVerbITEUse = 8, + kVerbITEOptions = 9, + kVerbITEEnter = 10, + kVerbITELeave = 11, + kVerbITEBegin = 12, + kVerbITEWalkOnly = 13, + kVerbITELookOnly = 14, + + + kVerbIHNMNone = 0, + kVerbIHNMWalk = 1, + kVerbIHNMLookAt = 2, + kVerbIHNMTake = 3, + kVerbIHNMUse = 4, + kVerbIHNMTalkTo = 5, + kVerbIHNMSwallow = 6, + kVerbIHNMGive = 7, + kVerbIHNMPush = 8, + kVerbIHNMOptions = 9, + kVerbIHNMEnter = 10, + kVerbIHNMLeave = 11, + kVerbIHNMBegin = 12, + kVerbIHNMWalkOnly = 13, + kVerbIHNMLookOnly = 14, + + kVerbTypeIdsMax = kVerbITELookOnly + 1 +}; +enum PanelButtonType { + kPanelButtonVerb = 1 << 0, + kPanelButtonArrow = 1 << 1, + kPanelButtonConverseText = 1 << 2, + kPanelButtonInventory = 1 << 3, + + kPanelButtonOption = 1 << 4, + kPanelButtonOptionSlider = 1 << 5, + kPanelButtonOptionSaveFiles = 1 << 6, + kPanelButtonOptionText = 1 << 7, + + kPanelButtonQuit = 1 << 8, + kPanelButtonQuitText = 1 << 9, + + kPanelButtonLoad = 1 << 10, + kPanelButtonLoadText = 1 << 11, + + kPanelButtonSave = 1 << 12, + kPanelButtonSaveText = 1 << 13, + kPanelButtonSaveEdit = 1 << 14, + + kPanelButtonProtectText = 1 << 15, + kPanelButtonProtectEdit = 1 << 16, + + kPanelAllButtons = 0xFFFFF +}; + +enum GameSoundTypes { + kSoundPCM = 0, + kSoundVOX = 1, + kSoundVOC = 2, + kSoundWAV = 3, + kSoundMacPCM = 4 +}; + +enum TextStringIds { + kTextWalkTo, + kTextLookAt, + kTextPickUp, + kTextTalkTo, + kTextOpen, + kTextClose, + kTextUse, + kTextGive, + kTextOptions, + kTextTest, + kTextDemo, + kTextHelp, + kTextQuitGame, + kTextFast, + kTextSlow, + kTextOn, + kTextOff, + kTextContinuePlaying, + kTextLoad, + kTextSave, + kTextGameOptions, + kTextReadingSpeed, + kTextMusic, + kTextSound, + kTextCancel, + kTextQuit, + kTextOK, + kTextMid, + kTextClick, + kText10Percent, + kText20Percent, + kText30Percent, + kText40Percent, + kText50Percent, + kText60Percent, + kText70Percent, + kText80Percent, + kText90Percent, + kTextMax, + kTextQuitTheGameQuestion, + kTextLoadSuccessful, + kTextEnterSaveGameName, + kTextGiveTo, + kTextUseWidth, + kTextNewSave, + kTextICantPickup, + kTextNothingSpecial, + kTextNoPlaceToOpen, + kTextNoOpening, + kTextDontKnow, + kTextShowDialog, + kTextEnterProtectAnswer +}; + + +struct GameResourceDescription { + uint32 sceneLUTResourceId; + uint32 moduleLUTResourceId; + uint32 mainPanelResourceId; + uint32 conversePanelResourceId; + uint32 optionPanelResourceId; + uint32 mainSpritesResourceId; + uint32 mainPanelSpritesResourceId; + uint32 defaultPortraitsResourceId; + uint32 mainStringsResourceId; + uint32 actorsStringsResourceId; +}; + +struct GameFontDescription { + uint32 fontResourceId; +}; + +struct GameDisplayInfo; + +struct GameSoundInfo { + GameSoundTypes resourceType; + long frequency; + int sampleBits; + bool stereo; + bool isBigEndian; + bool isSigned; +}; + +struct GamePatchDescription { + const char *fileName; + uint16 fileType; + uint32 resourceId; + const GameSoundInfo *soundInfo; +}; + +struct SAGAGameDescription; enum GameObjectTypes { kGameObjectNone = 0, @@ -234,10 +463,6 @@ inline int clamp(int minValue, int value, int maxValue) { } } -inline int integerCompare(int i1, int i2) { - return ((i1) > (i2) ? 1 : ((i1) < (i2) ? -1 : 0)); -} - inline int objectTypeId(uint16 objectId) { return objectId >> OBJECT_TYPE_SHIFT; } @@ -363,9 +588,6 @@ public: Common::String _gameTitle; Common::Rect _displayClip; -protected: - GameDisplayInfo _gameDisplayInfo; - public: int32 _frameCount; @@ -396,9 +618,9 @@ public: const Common::ADGameFileDescription *getFilesDescriptions() const; const Common::Rect &getDisplayClip() const { return _displayClip;} - int getDisplayWidth() const { return _gameDisplayInfo.logicalWidth; } - int getDisplayHeight() const { return _gameDisplayInfo.logicalHeight;} - const GameDisplayInfo & getDisplayInfo() { return _gameDisplayInfo; } + int getDisplayWidth() const; + int getDisplayHeight() const; + const GameDisplayInfo &getDisplayInfo(); const char *getTextString(int textStringId); void getExcuseInfo(int verb, const char *&textString, int &soundResourceId); diff --git a/engines/saga/sagagame.h b/engines/saga/sagagame.h deleted file mode 100644 index cd4aa48faf..0000000000 --- a/engines/saga/sagagame.h +++ /dev/null @@ -1,332 +0,0 @@ -enum SAGAGameType { - GType_ITE = 0, - GType_IHNM = 1 -}; - -enum GameIds { - // Dreamers Guild - GID_ITE_DEMO_G = 0, - GID_ITE_DISK_G, - GID_ITE_DISK_G2, - GID_ITE_CD_G, - GID_ITE_CD_G2, - GID_ITE_MACCD_G, - - // Wyrmkeep - GID_ITE_CD, // data for Win rerelease is same as in old DOS - GID_ITE_WINCD, // but it has a bunch of patch files - GID_ITE_MACCD, - GID_ITE_LINCD, - GID_ITE_MULTICD, // Wyrmkeep combined Windows/Mac/Linux version - GID_ITE_WINDEMO1, // older Wyrmkeep windows demo - GID_ITE_MACDEMO1, // older Wyrmkeep mac demo - GID_ITE_LINDEMO, - GID_ITE_WINDEMO2, - GID_ITE_WINDEMO3, - GID_ITE_MACDEMO2, - - // German - GID_ITE_DISK_DE, - GID_ITE_DISK_DE2, - GID_ITE_AMIGACD_DE, // TODO - GID_ITE_OLDMAC_DE, // TODO - GID_ITE_AMIGA_FL_DE,// TODO - GID_ITE_CD_DE, // reported by mld. Bestsellergamers cover disk - GID_ITE_CD_DE2, - GID_ITE_AMIGA_AGA_DEMO, // TODO - GID_ITE_AMIGA_ECS_DEMO, // TODO - - GID_IHNM_DEMO, - GID_IHNM_CD, - GID_IHNM_CD_DE, // reported by mld. German retail - GID_IHNM_CD_ES, - GID_IHNM_CD_RU, - GID_IHNM_CD_FR -}; - -enum GameFileTypes { - GAME_RESOURCEFILE = 1 << 0, - GAME_SCRIPTFILE = 1 << 1, - GAME_SOUNDFILE = 1 << 2, - GAME_VOICEFILE = 1 << 3, - GAME_DEMOFILE = 1 << 4, - GAME_MUSICFILE = 1 << 5, - GAME_MUSICFILE_GM = 1 << 6, - GAME_MUSICFILE_FM = 1 << 7, - GAME_PATCHFILE = 1 << 8, - GAME_MACBINARY = 1 << 9, - GAME_SWAPENDIAN = 1 << 10 -}; - -enum GameFeatures { - GF_BIG_ENDIAN_DATA = 1 << 0, - GF_WYRMKEEP = 1 << 1, - GF_CD_FX = 1 << 2, - GF_SCENE_SUBSTITUTES = 1 << 3 -}; - -enum VerbTypeIds { - kVerbITENone = 0, - kVerbITEPickUp = 1, - kVerbITELookAt = 2, - kVerbITEWalkTo = 3, - kVerbITETalkTo = 4, - kVerbITEOpen = 5, - kVerbITEClose = 6, - kVerbITEGive = 7, - kVerbITEUse = 8, - kVerbITEOptions = 9, - kVerbITEEnter = 10, - kVerbITELeave = 11, - kVerbITEBegin = 12, - kVerbITEWalkOnly = 13, - kVerbITELookOnly = 14, - - - kVerbIHNMNone = 0, - kVerbIHNMWalk = 1, - kVerbIHNMLookAt = 2, - kVerbIHNMTake = 3, - kVerbIHNMUse = 4, - kVerbIHNMTalkTo = 5, - kVerbIHNMSwallow = 6, - kVerbIHNMGive = 7, - kVerbIHNMPush = 8, - kVerbIHNMOptions = 9, - kVerbIHNMEnter = 10, - kVerbIHNMLeave = 11, - kVerbIHNMBegin = 12, - kVerbIHNMWalkOnly = 13, - kVerbIHNMLookOnly = 14, - - kVerbTypeIdsMax = kVerbITELookOnly + 1 -}; -enum PanelButtonType { - kPanelButtonVerb = 1 << 0, - kPanelButtonArrow = 1 << 1, - kPanelButtonConverseText = 1 << 2, - kPanelButtonInventory = 1 << 3, - - kPanelButtonOption = 1 << 4, - kPanelButtonOptionSlider = 1 << 5, - kPanelButtonOptionSaveFiles = 1 << 6, - kPanelButtonOptionText = 1 << 7, - - kPanelButtonQuit = 1 << 8, - kPanelButtonQuitText = 1 << 9, - - kPanelButtonLoad = 1 << 10, - kPanelButtonLoadText = 1 << 11, - - kPanelButtonSave = 1 << 12, - kPanelButtonSaveText = 1 << 13, - kPanelButtonSaveEdit = 1 << 14, - - kPanelButtonProtectText = 1 << 15, - kPanelButtonProtectEdit = 1 << 16, - - kPanelAllButtons = 0xFFFFF -}; - -enum GameSoundTypes { - kSoundPCM = 0, - kSoundVOX = 1, - kSoundVOC = 2, - kSoundWAV = 3, - kSoundMacPCM = 4 -}; - -enum TextStringIds { - kTextWalkTo, - kTextLookAt, - kTextPickUp, - kTextTalkTo, - kTextOpen, - kTextClose, - kTextUse, - kTextGive, - kTextOptions, - kTextTest, - kTextDemo, - kTextHelp, - kTextQuitGame, - kTextFast, - kTextSlow, - kTextOn, - kTextOff, - kTextContinuePlaying, - kTextLoad, - kTextSave, - kTextGameOptions, - kTextReadingSpeed, - kTextMusic, - kTextSound, - kTextCancel, - kTextQuit, - kTextOK, - kTextMid, - kTextClick, - kText10Percent, - kText20Percent, - kText30Percent, - kText40Percent, - kText50Percent, - kText60Percent, - kText70Percent, - kText80Percent, - kText90Percent, - kTextMax, - kTextQuitTheGameQuestion, - kTextLoadSuccessful, - kTextEnterSaveGameName, - kTextGiveTo, - kTextUseWidth, - kTextNewSave, - kTextICantPickup, - kTextNothingSpecial, - kTextNoPlaceToOpen, - kTextNoOpening, - kTextDontKnow, - kTextShowDialog, - kTextEnterProtectAnswer -}; - - -struct GameResourceDescription { - uint32 sceneLUTResourceId; - uint32 moduleLUTResourceId; - uint32 mainPanelResourceId; - uint32 conversePanelResourceId; - uint32 optionPanelResourceId; - uint32 mainSpritesResourceId; - uint32 mainPanelSpritesResourceId; - uint32 defaultPortraitsResourceId; - uint32 mainStringsResourceId; - uint32 actorsStringsResourceId; -}; - -struct GameFontDescription { - uint32 fontResourceId; -}; - -struct PanelButton { - PanelButtonType type; - int xOffset; - int yOffset; - int width; - int height; - int id; - uint16 ascii; - int state; - int upSpriteNumber; - int downSpriteNumber; - int overSpriteNumber; -}; - -struct GameDisplayInfo { - int logicalWidth; - int logicalHeight; - - int pathStartY; - int sceneHeight; - - int statusXOffset; - int statusYOffset; - int statusWidth; - int statusHeight; - int statusTextY; - int statusTextColor; - int statusBGColor; - - int saveReminderXOffset; - int saveReminderYOffset; - int saveReminderWidth; - int saveReminderHeight; - int saveReminderFirstSpriteNumber; - int saveReminderSecondSpriteNumber; - - int leftPortraitXOffset; - int leftPortraitYOffset; - int rightPortraitXOffset; - int rightPortraitYOffset; - - int inventoryUpButtonIndex; - int inventoryDownButtonIndex; - int inventoryRows; - int inventoryColumns; - - int mainPanelXOffset; - int mainPanelYOffset; - int mainPanelButtonsCount; - PanelButton *mainPanelButtons; - - int converseMaxTextWidth; - int converseTextHeight; - int converseTextLines; - int converseUpButtonIndex; - int converseDownButtonIndex; - - int conversePanelXOffset; - int conversePanelYOffset; - int conversePanelButtonsCount; - PanelButton *conversePanelButtons; - - int optionSaveFilePanelIndex; - int optionSaveFileSliderIndex; - uint32 optionSaveFileVisible; - - int optionPanelXOffset; - int optionPanelYOffset; - int optionPanelButtonsCount; - PanelButton *optionPanelButtons; - - int quitPanelXOffset; - int quitPanelYOffset; - int quitPanelWidth; - int quitPanelHeight; - int quitPanelButtonsCount; - PanelButton *quitPanelButtons; - - int loadPanelXOffset; - int loadPanelYOffset; - int loadPanelWidth; - int loadPanelHeight; - int loadPanelButtonsCount; - PanelButton *loadPanelButtons; - - int saveEditIndex; - int savePanelXOffset; - int savePanelYOffset; - int savePanelWidth; - int savePanelHeight; - int savePanelButtonsCount; - PanelButton *savePanelButtons; - - int protectEditIndex; - int protectPanelXOffset; - int protectPanelYOffset; - int protectPanelWidth; - int protectPanelHeight; - int protectPanelButtonsCount; - PanelButton *protectPanelButtons; -}; - -struct GameSoundInfo { - GameSoundTypes resourceType; - long frequency; - int sampleBits; - bool stereo; - bool isBigEndian; - bool isSigned; -}; - -struct GamePatchDescription { - const char *fileName; - uint16 fileType; - uint32 resourceId; - const GameSoundInfo *soundInfo; -}; - -struct SAGAGameDescription; - -#define FILE_MD5_BYTES 5000 diff --git a/engines/saga/scene.cpp b/engines/saga/scene.cpp index 8311308018..74cae1f4cf 100644 --- a/engines/saga/scene.cpp +++ b/engines/saga/scene.cpp @@ -45,7 +45,7 @@ #include "saga/rscfile.h" #include "saga/sagaresnames.h" -#include "graphics/ilbm.h" +#include "graphics/iff.h" #include "common/util.h" namespace Saga { @@ -437,7 +437,7 @@ void Scene::changeScene(int16 sceneNumber, int actorsEntrance, SceneTransitionTy _vm->_interface->setMode(kPanelSceneSubstitute); if (file.open(sceneSubstitutes[i].image)) { - Graphics::decodeILBM(file, bbmBuffer, pal); + Graphics::decodePBM(file, bbmBuffer, pal); colors = pal; rect.setWidth(bbmBuffer.w); rect.setHeight(bbmBuffer.h); @@ -502,28 +502,6 @@ void Scene::getBGInfo(BGInfo &bgInfo) { bgInfo.bounds.setHeight(_bg.h); } -int Scene::getBGMaskType(const Point &testPoint) { - uint offset; - if (!_bgMask.loaded) { - return 0; - } - offset = testPoint.x + testPoint.y * _bgMask.w; - if (offset >= _bgMask.buf_len) { - error("Scene::getBGMaskType offset 0x%X exceed bufferLength 0x%X", offset, (int)_bgMask.buf_len); - } - - return (_bgMask.buf[offset] >> 4) & 0x0f; -} - -bool Scene::validBGMaskPoint(const Point &testPoint) { - if (!_bgMask.loaded) { - error("Scene::validBGMaskPoint _bgMask not loaded"); - } - - return !((testPoint.x < 0) || (testPoint.x >= _bgMask.w) || - (testPoint.y < 0) || (testPoint.y >= _bgMask.h)); -} - bool Scene::canWalk(const Point &testPoint) { int maskType; @@ -571,20 +549,6 @@ void Scene::getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &buffer bufferLength = _bgMask.buf_len; } -void Scene::setDoorState(int doorNumber, int doorState) { - if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX)) - error("Scene::setDoorState wrong doorNumber"); - - _sceneDoors[doorNumber] = doorState; -} - -int Scene::getDoorState(int doorNumber) { - if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX)) - error("Scene::getDoorState wrong doorNumber"); - - return _sceneDoors[doorNumber]; -} - void Scene::initDoorsState() { memcpy(_sceneDoors, initSceneDoors, sizeof (_sceneDoors) ); } @@ -594,7 +558,14 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { Event event; Event *q_event; static PalEntry current_pal[PAL_ENTRIES]; - + + // Change the cursor to an hourglass in IHNM + event.type = kEvTOneshot; + event.code = kCursorEvent; + event.op = kEventSetBusyCursor; + event.time = 0; + _vm->_events->queue(&event); + if ((_vm->getGameType() == GType_IHNM) && (loadSceneParams->chapter != NO_CHAPTER_CHANGE)) { if (loadSceneParams->loadFlag != kLoadBySceneNumber) { error("loadScene wrong usage"); @@ -680,7 +651,7 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { _vm->_resource->loadResource(_sceneContext, _resourceList[i].resourceId, _resourceList[i].buffer, _resourceList[i].size); - + if (_resourceList[i].size >= 6) { if (!memcmp(_resourceList[i].buffer, "DUMMY!", 6)) { _resourceList[i].invalid = true; @@ -874,8 +845,6 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { loadSceneParams->sceneProc(SCENE_BEGIN, this); } - - // We probably don't want "followers" to go into scene -1 , 0. At the very // least we don't want garbage to be drawn that early in the ITE intro. if (_sceneNumber > 0 && _sceneNumber != ITE_SCENE_PUZZLE) @@ -892,12 +861,19 @@ void Scene::loadScene(LoadSceneParams *loadSceneParams) { event.time = 0; _vm->_events->queue(&event); } + + // Change the cursor back to a crosshair in IHNM + event.type = kEvTOneshot; + event.code = kCursorEvent; + event.op = kEventSetNormalCursor; + event.time = 0; + _vm->_events->queue(&event); } void Scene::loadSceneDescriptor(uint32 resourceId) { byte *sceneDescriptorData; size_t sceneDescriptorDataLength; - + memset(&_sceneDescription, 0, sizeof(_sceneDescription)); if (resourceId == 0) { @@ -970,7 +946,7 @@ void Scene::processSceneResources() { SAGAResourceTypes resType; getResourceTypes(types, typesCount); - + // Process the scene resource list for (i = 0; i < _resourceListCount; i++) { if (_resourceList[i].invalid) { diff --git a/engines/saga/scene.h b/engines/saga/scene.h index 7f99140d10..ce76bde4a2 100644 --- a/engines/saga/scene.h +++ b/engines/saga/scene.h @@ -34,6 +34,8 @@ namespace Saga { +//#define SCENE_DEBUG // for scene debugging + #define SCENE_DOORS_MAX 16 #define NO_CHAPTER_CHANGE -2 @@ -233,13 +235,55 @@ class Scene { void getBGMaskInfo(int &width, int &height, byte *&buffer, size_t &bufferLength); int isBGMaskPresent() { return _bgMask.loaded; } - int getBGMaskType(const Point &testPoint); - bool validBGMaskPoint(const Point &testPoint); + + int getBGMaskType(const Point &testPoint) { + uint offset; + if (!_bgMask.loaded) { + return 0; + } + offset = testPoint.x + testPoint.y * _bgMask.w; + + #ifdef SCENE_DEBUG + if (offset >= _bgMask.buf_len) { + error("Scene::getBGMaskType offset 0x%X exceed bufferLength 0x%X", offset, (int)_bgMask.buf_len); + } + #endif + + return (_bgMask.buf[offset] >> 4) & 0x0f; + } + + bool validBGMaskPoint(const Point &testPoint) { + #ifdef SCENE_DEBUG + if (!_bgMask.loaded) { + error("Scene::validBGMaskPoint _bgMask not loaded"); + } + #endif + + return !((testPoint.x < 0) || (testPoint.x >= _bgMask.w) || + (testPoint.y < 0) || (testPoint.y >= _bgMask.h)); + } + bool canWalk(const Point &testPoint); bool offscreenPath(Point &testPoint); - void setDoorState(int doorNumber, int doorState); - int getDoorState(int doorNumber); + void setDoorState(int doorNumber, int doorState) { + #ifdef SCENE_DEBUG + if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX)) + error("Scene::setDoorState wrong doorNumber"); + #endif + + _sceneDoors[doorNumber] = doorState; + } + + int getDoorState(int doorNumber) { + #ifdef SCENE_DEBUG + if ((doorNumber < 0) || (doorNumber >= SCENE_DOORS_MAX)) + error("Scene::getDoorState wrong doorNumber"); + #endif + + return _sceneDoors[doorNumber]; + } + void initDoorsState(); void getBGInfo(BGInfo &bgInfo); @@ -257,9 +301,11 @@ class Scene { bool isSceneLoaded() const { return _sceneLoaded; } int getSceneResourceId(int sceneNumber) { + #ifdef SCENE_DEBUG if ((sceneNumber < 0) || (sceneNumber >= _sceneCount)) { error("getSceneResourceId: wrong sceneNumber %i", sceneNumber); } + #endif return _sceneLUT[sceneNumber]; } int currentSceneNumber() const { return _sceneNumber; } @@ -278,9 +324,9 @@ class Scene { int getHeight() const { if (_vm->_interface->getMode() == kPanelChapterSelection) - return _vm->_gameDisplayInfo.logicalHeight; + return _vm->getDisplayInfo().logicalHeight; else - return _vm->_gameDisplayInfo.sceneHeight; + return _vm->getDisplayInfo().sceneHeight; } private: diff --git a/engines/saga/script.cpp b/engines/saga/script.cpp index 7c203605ee..8a1e61cd46 100644 --- a/engines/saga/script.cpp +++ b/engines/saga/script.cpp @@ -479,18 +479,21 @@ void Script::doVerb() { if (scriptEntrypointNumber > 0) { - event.type = kEvTOneshot; - event.code = kScriptEvent; - event.op = kEventExecNonBlocking; - event.time = 0; - event.param = scriptModuleNumber; - event.param2 = scriptEntrypointNumber; - event.param3 = _pendingVerb; // Action - event.param4 = _pendingObject[0]; // Object - event.param5 = _pendingObject[1]; // With Object - event.param6 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor - - _vm->_events->queue(&event); + // WORKAROUND: Fixes bug #1690045 "ITE: Item description missing / ScummVM crash" + if (!(_vm->_scene->currentSceneNumber() == 278 && (_pendingObject[0] == 16419 || _pendingObject[1] == 16419) && _vm->getGameType() == GType_ITE)) { + event.type = kEvTOneshot; + event.code = kScriptEvent; + event.op = kEventExecNonBlocking; + event.time = 0; + event.param = scriptModuleNumber; + event.param2 = scriptEntrypointNumber; + event.param3 = _pendingVerb; // Action + event.param4 = _pendingObject[0]; // Object + event.param5 = _pendingObject[1]; // With Object + event.param6 = (objectType == kGameObjectActor) ? _pendingObject[0] : ID_PROTAG; // Actor + + _vm->_events->queue(&event); + } } else { _vm->getExcuseInfo(_pendingVerb, excuseText, excuseSampleResourceId); diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index af5726a273..c3384ff2ce 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1850,6 +1850,7 @@ void ScummEngine::resetV1ActorTalkColor() { #ifndef DISABLE_SCUMM_7_8 void ScummEngine_v7::actorTalk(const byte *msg) { Actor *a; + bool stringWrap = false; convertMessageToString(msg, _charsetBuffer, sizeof(_charsetBuffer)); @@ -1861,30 +1862,31 @@ void ScummEngine_v7::actorTalk(const byte *msg) { } if (_actorToPrintStrFor == 0xFF) { setTalkingActor(0xFF); + _charsetColor = (byte)_string[0].color; } else { a = derefActor(_actorToPrintStrFor, "actorTalk"); setTalkingActor(a->_number); if (!_string[0].no_talk_anim) { a->runActorTalkScript(a->_talkStartFrame); - _useTalkAnims = true; } - } - - if (getTalkingActor() > 0x7F) { - _charsetColor = (byte)_string[0].color; - } else { - a = derefActor(getTalkingActor(), "actorTalk(2)"); _charsetColor = a->_talkColor; } + _charsetBufPos = 0; _talkDelay = 0; _haveMsg = 1; if (_game.version == 7) VAR(VAR_HAVE_MSG) = 0xFF; _haveActorSpeechMsg = true; + if (_game.version == 8) { + stringWrap = _string[0].wrapping; + _string[0].wrapping = true; + } CHARSET_1(); - if (_game.version == 8) + if (_game.version == 8) { VAR(VAR_HAVE_MSG) = (_string[0].no_talk_anim) ? 2 : 1; + _string[0].wrapping = stringWrap; + } } #endif @@ -2289,9 +2291,12 @@ void ScummEngine_v71he::postProcessAuxQueue() { if (ae->actorNum != -1) { Actor *a = derefActor(ae->actorNum, "postProcessAuxQueue"); const uint8 *cost = getResourceAddress(rtCostume, a->_costume); - int dy = a->_offsY + a->getPos().y - a->getElevation(); + int dy = a->_offsY + a->getPos().y; int dx = a->_offsX + a->getPos().x; + if (_game.heversion >= 72) + dy -= a->getElevation(); + const uint8 *akax = findResource(MKID_BE('AKAX'), cost); assert(akax); const uint8 *auxd = findPalInPals(akax, ae->subIndex) - _resourceHeaderSize; diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp index b343fde319..7b51268f42 100644 --- a/engines/scumm/boxes.cpp +++ b/engines/scumm/boxes.cpp @@ -443,7 +443,9 @@ byte ScummEngine::getNumBoxes() { if (!ptr) return 0; if (_game.version == 8) - return (byte) READ_LE_UINT32(ptr); + return (byte)READ_LE_UINT32(ptr); + else if (_game.features >= 5) + return (byte)READ_LE_UINT16(ptr); else return ptr[0]; } diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp new file mode 100644 index 0000000000..d9ac3e42df --- /dev/null +++ b/engines/scumm/detection.cpp @@ -0,0 +1,952 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001 Ludvig Strigeus + * Copyright (C) 2001-2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" + +#include "base/plugins.h" + +#include "common/config-manager.h" +#include "common/fs.h" +#include "common/list.h" +#include "common/md5.h" + +#include "scumm/detection.h" +#include "scumm/detection_tables.h" +#include "scumm/scumm.h" +#include "scumm/intern.h" +#include "scumm/he/intern_he.h" + +namespace Scumm { + +enum { + // We only compute the MD5 of the first megabyte of our data files. + kMD5FileSizeLimit = 1024 * 1024 +}; + +#pragma mark - +#pragma mark --- Miscellaneous --- +#pragma mark - + +static const char *findDescriptionFromGameID(const char *gameid) { + const PlainGameDescriptor *g = gameDescriptions; + while (g->gameid) { + if (!scumm_stricmp(g->gameid, gameid)) { + return g->description; + } + g++; + } + error("Unknown gameid '%s' encountered in findDescriptionFromGameID", gameid); +} + +static int compareMD5Table(const void *a, const void *b) { + const char *key = (const char *)a; + const MD5Table *elem = (const MD5Table *)b; + return strcmp(key, elem->md5); +} + +static const MD5Table *findInMD5Table(const char *md5) { +#ifdef PALMOS_68K + uint32 arraySize = MemPtrSize((void *)md5table) / sizeof(MD5Table) - 1; +#else + uint32 arraySize = ARRAYSIZE(md5table) - 1; +#endif + return (const MD5Table *)bsearch(md5, md5table, arraySize, sizeof(MD5Table), compareMD5Table); +} + +Common::String ScummEngine::generateFilename(const int room) const { + const int diskNumber = (room > 0) ? _res->roomno[rtRoom][room] : 0; + char buf[128]; + + if (_game.version == 4) { + if (room == 0 || room >= 900) { + snprintf(buf, sizeof(buf), "%03d.lfl", room); + } else { + snprintf(buf, sizeof(buf), "disk%02d.lec", diskNumber); + } + } else { + char id = 0; + + switch (_filenamePattern.genMethod) { + case kGenDiskNum: + snprintf(buf, sizeof(buf), _filenamePattern.pattern, diskNumber); + break; + + case kGenRoomNum: + snprintf(buf, sizeof(buf), _filenamePattern.pattern, room); + break; + + case kGenHEMac: + case kGenHEMacNoParens: + case kGenHEPC: + if (room < 0) { + id = '0' - room; + } else if (_game.heversion >= 98) { + int disk = 0; + if (_heV7DiskOffsets) + disk = _heV7DiskOffsets[room]; + + switch (disk) { + case 2: + id = 'b'; + snprintf(buf, sizeof(buf), "%s.(b)", _filenamePattern.pattern); + break; + case 1: + id = 'a'; + snprintf(buf, sizeof(buf), "%s.(a)", _filenamePattern.pattern); + break; + default: + id = '0'; + snprintf(buf, sizeof(buf), "%s.he0", _filenamePattern.pattern); + } + } else if (_game.heversion >= 70) { + id = (room == 0) ? '0' : '1'; + } else { + id = diskNumber + '0'; + } + + if (_filenamePattern.genMethod == kGenHEPC) { + // For HE >= 98, we already called snprintf above. + if (_game.heversion < 98 || room < 0) + snprintf(buf, sizeof(buf), "%s.he%c", _filenamePattern.pattern, id); + } else { + if (id == '3') { // special case for cursors + // For mac they're stored in game binary + strncpy(buf, _filenamePattern.pattern, sizeof(buf)); + } else { + if (_filenamePattern.genMethod == kGenHEMac) + snprintf(buf, sizeof(buf), "%s (%c)", _filenamePattern.pattern, id); + else + snprintf(buf, sizeof(buf), "%s %c", _filenamePattern.pattern, id); + } + } + + break; + + case kGenUnchanged: + strncpy(buf, _filenamePattern.pattern, sizeof(buf)); + break; + + default: + error("generateFilename: Unsupported genMethod"); + } + } + + return buf; +} + +static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod) { + char buf[128]; + + switch (genMethod) { + case kGenDiskNum: + case kGenRoomNum: + snprintf(buf, sizeof(buf), pattern, 0); + break; + + case kGenHEPC: + snprintf(buf, sizeof(buf), "%s.he0", pattern); + break; + + case kGenHEMac: + snprintf(buf, sizeof(buf), "%s (0)", pattern); + break; + + case kGenHEMacNoParens: + snprintf(buf, sizeof(buf), "%s 0", pattern); + break; + + case kGenUnchanged: + strncpy(buf, pattern, sizeof(buf)); + break; + + default: + error("generateFilenameForDetection: Unsupported genMethod"); + } + + return buf; +} + +struct DetectorDesc { + FilesystemNode node; + Common::String md5; + const MD5Table *md5Entry; // Entry of the md5 table corresponding to this file, if any. +}; + +typedef Common::HashMap<Common::String, DetectorDesc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DescMap; + +static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Common::String &file); + + +// Search for a node with the given "name", inside fslist. Ignores case +// when performing the matching. The first match is returned, so if you +// search for "resource" and two nodes "RESOURE and "resource" are present, +// the first match is used. +static bool searchFSNode(const FSList &fslist, const Common::String &name, FilesystemNode &result) { + for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (!scumm_stricmp(file->name().c_str(), name.c_str())) { + result = *file; + return true; + } + } + return false; +} + +// The following function tries to detect the language for COMI and DIG +static Common::Language detectLanguage(const FSList &fslist, byte id) { + assert(id == GID_CMI || id == GID_DIG); + + // Check for LANGUAGE.BND (Dig) resp. LANGUAGE.TAB (CMI). + // These are usually inside the "RESOURCE" subdirectory. + // If found, we match based on the file size (should we + // ever determine that this is insufficient, we can still + // switch to MD5 based detection). + const char *filename = (id == GID_CMI) ? "LANGUAGE.TAB" : "LANGUAGE.BND"; + Common::File tmp; + FilesystemNode langFile; + if (!searchFSNode(fslist, filename, langFile) || !tmp.open(langFile)) { + // try loading in RESOURCE sub dir... + FilesystemNode resDir; + FSList tmpList; + if (searchFSNode(fslist, "RESOURCE", resDir) + && resDir.isDirectory() + && resDir.listDir(tmpList, FilesystemNode::kListFilesOnly) + && searchFSNode(tmpList, filename, langFile)) { + tmp.open(langFile); + } + } + if (tmp.isOpen()) { + uint size = tmp.size(); + if (id == GID_CMI) { + switch (size) { + case 439080: // 2daf3db71d23d99d19fc9a544fcf6431 + return Common::EN_ANY; + case 493252: // 5d59594b24f3f1332e7d7e17455ed533 + return Common::DE_DEU; + case 461746: // 35bbe0e4d573b318b7b2092c331fd1fa + return Common::FR_FRA; + case 443439: // 4689d013f67aabd7c35f4fd7c4b4ad69 + return Common::IT_ITA; + case 440586: // 5a1d0f4fa00917bdbfe035a72a6bba9d + return Common::PT_BRA; + case 449787: // 64f3fe479d45b52902cf88145c41d172 + return Common::ES_ESP; + } + } else { + switch (size) { + case 248627: // 1fd585ac849d57305878c77b2f6c74ff + return Common::DE_DEU; + case 257460: // 04cf6a6ba6f57e517bc40eb81862cfb0 + return Common::FR_FRA; + case 231402: // 93d13fcede954c78e65435592182a4db + return Common::IT_ITA; + case 228772: // 5d9ad90d3a88ea012d25d61791895ebe + return Common::PT_BRA; + case 229884: // d890074bc15c6135868403e73c5f4f36 + return Common::ES_ESP; + } + } + } + + return Common::UNK_LANG; +} + + +static void computeGameSettingsFromMD5(const FSList &fslist, const GameFilenamePattern *gfp, const MD5Table *md5Entry, DetectorResult &dr) { + dr.language = md5Entry->language; + dr.extra = md5Entry->extra; + + // Compute the precise game settings using gameVariantsTable. + for (const GameSettings *g = gameVariantsTable; g->gameid; ++g) { + if (g->gameid[0] == 0 || !scumm_stricmp(md5Entry->gameid, g->gameid)) { + // The gameid either matches, or is empty. The latter indicates + // a generic entry, currently used for some generic HE settings. + if (g->variant == 0 || !scumm_stricmp(md5Entry->variant, g->variant)) { + // Perfect match found, use it and stop the loop + dr.game = *g; + dr.game.gameid = md5Entry->gameid; + + // Set the platform value. The value from the MD5 record has + // highest priority; if missing (i.e. set to unknown) we try + // to use that from the filename pattern record instead. + if (md5Entry->platform != Common::kPlatformUnknown) { + dr.game.platform = md5Entry->platform; + } else if (gfp->platform != Common::kPlatformUnknown) { + dr.game.platform = gfp->platform; + } + + // HACK: Special case to distinguish the V1 demo from the full version + // (since they have identical MD5): + if (dr.game.id == GID_MANIAC && !strcmp(gfp->pattern, "%02d.MAN")) { + dr.extra = "V1 Demo"; + } + + // HACK: If 'Demo' occurs in the extra string, set the GF_DEMO flag, + // required by some game demos (e.g. Dig, FT and COMI). + if (dr.extra && strstr(dr.extra, "Demo")) { + dr.game.features |= GF_DEMO; + } + + // HACK: Detect COMI & Dig languages + if (dr.language == UNK_LANG && (dr.game.id == GID_CMI || dr.game.id == GID_DIG)) { + dr.language = detectLanguage(fslist, dr.game.id); + } + break; + } + } + } +} + +static void detectGames(const FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) { + DescMap fileMD5Map; + DetectorResult dr; + + for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { + if (!file->isDirectory()) { + DetectorDesc d; + d.node = *file; + d.md5Entry = 0; + fileMD5Map[file->name()] = d; + } + } + + // Iterate over all filename patterns. + for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) { + // If a gameid was specified, we only try to detect that specific game, + // so we can just skip over everything with a differing gameid. + if (gameid && scumm_stricmp(gameid, gfp->gameid)) + continue; + + // Generate the detectname corresponding to the gfp. If the file doesn't + // exist in the directory we are looking at, we can skip to the next + // one immediately. + Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod)); + if (!fileMD5Map.contains(file)) + continue; + + // Reset the DetectorResult variable + dr.fp.pattern = gfp->pattern; + dr.fp.genMethod = gfp->genMethod; + dr.game.gameid = 0; + dr.language = gfp->language; + dr.md5.clear(); + dr.extra = 0; + + // ____ _ _ + // | _ \ __ _ _ __| |_ / | + // | |_) / _` | '__| __| | | + // | __/ (_| | | | |_ | | + // |_| \__,_|_| \__| |_| + // + // PART 1: Trying to find an exact match using MD5. + // + // + // Background: We found a valid detection file. Check if its MD5 + // checksum occurs in our MD5 table. If it does, try to use that + // to find an exact match. + // + // We only do that if the MD5 hadn't already been computed (since + // we may look at some detection files multiple times). + // + DetectorDesc &d = fileMD5Map[file]; + if (d.md5.empty()) { + char md5str[32+1]; + if (Common::md5_file_string(d.node, md5str, kMD5FileSizeLimit)) { + + d.md5 = md5str; + d.md5Entry = findInMD5Table(md5str); + + dr.md5 = d.md5; + + if (d.md5Entry) { + // Exact match found. Compute the precise game settings. + computeGameSettingsFromMD5(fslist, gfp, d.md5Entry, dr); + + // Sanity check: We *should* have found a matching gameid / variant at this point. + // If not, then there's a bug in our data tables... + assert(dr.game.gameid != 0); + + // Add it to the list of detected games + results.push_back(dr); + } + } + } + + // If an exact match for this file has already been found, don't bother + // looking at it anymore. + if (d.md5Entry) + continue; + + + // ____ _ ____ + // | _ \ __ _ _ __| |_ |___ \ * + // | |_) / _` | '__| __| __) | + // | __/ (_| | | | |_ / __/ + // |_| \__,_|_| \__| |_____| + // + // PART 2: Fuzzy matching for files with unknown MD5. + // + + + // We loop over the game variants matching the gameid associated to + // the gfp record. We then try to decide for each whether it could be + // appropriate or not. + dr.md5 = d.md5; + for (const GameSettings *g = gameVariantsTable; g->gameid; ++g) { + // Skip over entries with a different gameid. + if (g->gameid[0] == 0 || scumm_stricmp(gfp->gameid, g->gameid)) + continue; + + dr.game = *g; + dr.extra = g->variant; // FIXME: We (ab)use 'variant' for the 'extra' description for now. + + if (gfp->platform != Common::kPlatformUnknown) + dr.game.platform = gfp->platform; + + + // If a variant has been specified, use that! + if (gfp->variant) { + if (!scumm_stricmp(gfp->variant, g->variant)) { + // perfect match found + results.push_back(dr); + break; + } + continue; + } + + + // Add the game/variant to the candidates list if it is consistent + // with the file(s) we are seeing. + if (testGame(g, fileMD5Map, file)) + results.push_back(dr); + } + } +} + +static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Common::String &file) { + const DetectorDesc &d = fileMD5Map[file]; + + // At this point, we know that the gameid matches, but no variant + // was specified, yet there are multiple ones. So we try our best + // to distinguish between the variants. + // To do this, we take a close look at the detection file and + // try to filter out some cases. + + Common::File tmp; + if (!tmp.open(d.node)) { + warning("SCUMM detectGames: failed to open '%s' for read access", d.node.path().c_str()); + return false; + } + + if (file == "maniac1.d64" || file == "maniac1.dsk" || file == "zak1.d64") { + // TODO + } else if (file == "00.LFL") { + // Used in V1, V2, V3 games. + if (g->version > 3) + return false; + + // Read a few bytes to narrow down the game. + byte buf[6]; + tmp.read(buf, 6); + + if (buf[0] == 0xbc && buf[1] == 0xb9) { + // The NES version of MM + if (g->id == GID_MANIAC && g->platform == Common::kPlatformNES) { + // perfect match + return true; + } + } else if ((buf[0] == 0xCE && buf[1] == 0xF5) || // PC + (buf[0] == 0xCD && buf[1] == 0xFE)) { // Commodore 64 + // Could be V0 or V1. + // Candidates: maniac classic, zak classic + + if (g->version >= 2) + return false; + + // Zak has 58.LFL, Maniac doesn't have it. + const bool has58LFL = fileMD5Map.contains("58.LFL"); + if (g->id == GID_MANIAC && !has58LFL) { + } else if (g->id == GID_ZAK && has58LFL) { + } else + return false; + } else if (buf[0] == 0xFF && buf[1] == 0xFE) { + // GF_OLD_BUNDLE: could be V2 or old V3. + // Note that GF_OLD_BUNDLE is true if and only if GF_OLD256 is false. + // Candidates: maniac enhanced, zak enhanced, indy3ega, loom + + if (g->version != 2 && g->version != 3 || (g->features & GF_OLD256)) + return false; + + /* We distinguish the games by the presence/absence of + certain files. In the following, '+' means the file + present, '-' means the file is absent. + + maniac: -58.LFL, -84.LFL,-86.LFL, -98.LFL + + zak: +58.LFL, -84.LFL,-86.LFL, -98.LFL + zakdemo: +58.LFL, -84.LFL,-86.LFL, -98.LFL + + loom: +58.LFL, -84.LFL,+86.LFL, -98.LFL + loomdemo: -58.LFL, +84.LFL,-86.LFL, -98.LFL + + indy3: +58.LFL, +84.LFL,+86.LFL, +98.LFL + indy3demo: -58.LFL, +84.LFL,-86.LFL, +98.LFL + */ + const bool has58LFL = fileMD5Map.contains("58.LFL"); + const bool has84LFL = fileMD5Map.contains("84.LFL"); + const bool has86LFL = fileMD5Map.contains("86.LFL"); + const bool has98LFL = fileMD5Map.contains("98.LFL"); + + if (g->id == GID_INDY3 && has98LFL && has84LFL) { + } else if (g->id == GID_ZAK && !has98LFL && !has86LFL && !has84LFL && has58LFL) { + } else if (g->id == GID_MANIAC && !has98LFL && !has86LFL && !has84LFL && !has58LFL) { + } else if (g->id == GID_LOOM && !has98LFL && (has86LFL != has84LFL)) { + } else + return false; + } else if (buf[4] == '0' && buf[5] == 'R') { + // newer V3 game + // Candidates: indy3, indy3Towns, zakTowns, loomTowns + + if (g->version != 3 || !(g->features & GF_OLD256)) + return false; + + /* + Considering that we know about *all* TOWNS versions, and + know their MD5s, we could simply rely on this and if we find + something which has an unknown MD5, assume that it is an (so + far unknown) version of Indy3. However, there are also fan + translations of the TOWNS versions, so we can't do that. + + But we could at least look at the resource headers to distinguish + TOWNS versions from regular games: + + Indy3: + _numGlobalObjects 1000 + _numRooms 99 + _numCostumes 129 + _numScripts 139 + _numSounds 84 + + Indy3Towns, ZakTowns, ZakLoom demo: + _numGlobalObjects 1000 + _numRooms 99 + _numCostumes 199 + _numScripts 199 + _numSounds 199 + + Assuming that all the town variants look like the latter, we can + do the check like this: + if (numScripts == 139) + assume Indy3 + else if (numScripts == 199) + assume towns game + else + unknown, do not accept it + */ + + // We now try to exclude various possibilities by the presence of certain + // LFL files. Note that we only exclude something based on the *presence* + // of a LFL file here; compared to checking for the absence of files, this + // has the advantage that we are less likely to accidentally exclude demos + // (which, after all, are usually missing many LFL files present in the + // full version of the game). + + // No version of Indy3 has 05.LFL but MM, Loom and Zak all have it + if (g->id == GID_INDY3 && fileMD5Map.contains("05.LFL")) + return false; + + // All versions of Indy3 have 93.LFL, but no other game + if (g->id != GID_INDY3 && fileMD5Map.contains("93.LFL")) + return false; + + // No version of Loom has 48.LFL + if (g->id == GID_LOOM && fileMD5Map.contains("48.LFL")) + return false; + + // No version of Zak has 60.LFL, but most (non-demo) versions of Indy3 have it + if (g->id == GID_ZAK && fileMD5Map.contains("60.LFL")) + return false; + + // All versions of Indy3 and ZakTOWNS have 98.LFL, but no other game + if (g->id == GID_LOOM && fileMD5Map.contains("98.LFL")) + return false; + + + } else { + // TODO: Unknown file header, deal with it. Maybe an unencrypted + // variant... + // Anyway, we don't know to deal with the file, so we + // just skip it. + } + } else if (file == "000.LFL") { + // Used in V4 + // Candidates: monkeyEGA, pass, monkeyVGA, loomcd + + if (g->version != 4) + return false; + + /* + For all of them, we have: + _numGlobalObjects 1000 + _numRooms 99 + _numCostumes 199 + _numScripts 199 + _numSounds 199 + + Any good ideas to distinguish those? Maybe by the presence / absence + of some files? + At least PASS and the monkeyEGA demo differ by 903.LFL missing... + And the count of DISK??.LEC files differs depending on what version + you have (4 or 8 floppy versions). + loomcd of course shipped on only one "disc". + + pass: 000.LFL, 901.LFL, 902.LFL, 904.LFL, disk01.lec + monkeyEGA: 000.LFL, 901-904.LFL, DISK01-09.LEC + monkeyEGA DEMO: 000.LFL, 901.LFL, 902.LFL, 904.LFL, disk01.lec + monkeyVGA: 000.LFL, 901-904.LFL, DISK01-04.LEC + loomcd: 000.LFL, 901-904.LFL, DISK01.LEC + */ + + const bool has903LFL = fileMD5Map.contains("903.LFL"); + const bool hasDisk02 = fileMD5Map.contains("DISK02.LEC"); + + // There is not much we can do based on the presence / absence + // of files. Only that if 903.LFL is present, it can't be PASS; + // and if DISK02.LEC is present, it can't be LoomCD + if (g->id == GID_PASS && !has903LFL && !hasDisk02) { + } else if (g->id == GID_LOOM && has903LFL && !hasDisk02) { + } else if (g->id == GID_MONKEY_VGA) { + } else if (g->id == GID_MONKEY_EGA) { + } else + return false; + } else { + // Must be a V5+ game + if (g->version < 5) + return false; + + // So at this point the gameid is determined, but not necessarily + // the variant! + + // TODO: Add code that handles this, at least for the non-HE games. + // Note sure how realistic it is to correctly detect HE-game + // variants, would require me to look at a sufficiently large + // sample collection of HE games (assuming I had the time :). + + // TODO: For Mac versions in container file, we can sometimes + // distinguish the demo from the regular version by looking + // at the content of the container file and then looking for + // the *.000 file in there. + } + + return true; +} + + +} // End of namespace Scumm + +#pragma mark - +#pragma mark --- Plugin code --- +#pragma mark - + + +using namespace Scumm; + +GameList Engine_SCUMM_gameIDList() { + const PlainGameDescriptor *g = gameDescriptions; + GameList games; + while (g->gameid) { + games.push_back(GameDescriptor(g->gameid, g->description)); + g++; + } + return games; +} + +GameDescriptor Engine_SCUMM_findGameID(const char *gameid) { + // First search the list of supported game IDs. + const PlainGameDescriptor *g = gameDescriptions; + while (g->gameid) { + if (0 == scumm_stricmp(gameid, g->gameid)) + return GameDescriptor(g->gameid, g->description); + g++; + } + + // If we didn't find the gameid in the main list, check if it + // is an obsolete game id. + GameDescriptor gs; + const ObsoleteGameID *o = obsoleteGameIDsTable; + while (o->from) { + if (0 == scumm_stricmp(gameid, o->from)) { + gs["gameid"] = gameid; + gs["description"] = "Obsolete game ID"; + return gs; + } + o++; + } + return gs; +} + + +GameList Engine_SCUMM_detectGames(const FSList &fslist) { + GameList detectedGames; + Common::List<DetectorResult> results; + + detectGames(fslist, results, 0); + + // TODO: We still don't handle the FM-TOWNS demos (like zakloom) very well. + // In particular, they are detected as ZakTowns, which is bad. + + for (Common::List<DetectorResult>::iterator x = results.begin(); x != results.end(); ++x) { + GameDescriptor dg(x->game.gameid, findDescriptionFromGameID(x->game.gameid), + x->language, x->game.platform); + dg.updateDesc(x->extra); // Append additional information, if set, to the description. + + // Compute and set the preferred target name for this game. + // Based on generateComplexID() in advancedDetector.cpp. + Common::String res(x->game.gameid); + + if (x->game.preferredTag) { + res = res + "-" + x->game.preferredTag; + } + + if (x->game.features & GF_DEMO) { + res = res + "-demo"; + } + + // Append the platform, if a non-standard one has been specified. + if (x->game.platform != Common::kPlatformPC && x->game.platform != Common::kPlatformUnknown) { + // HACK: For CoMI, it's pointless to encode the fact that it's for Windows + if (x->game.id != GID_CMI) + res = res + "-" + Common::getPlatformAbbrev(x->game.platform); + } + + // Append the language, if a non-standard one has been specified + if (x->language != Common::EN_ANY && x->language != Common::UNK_LANG) { + res = res + "-" + Common::getLanguageCode(x->language); + } + + dg["preferredtarget"] = res; + + detectedGames.push_back(dg); + } + + return detectedGames; +} + +/** + * Create a ScummEngine instance, based on the given detector data. + * + * This is heavily based on our MD5 detection scheme. + */ +PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) { + assert(syst); + assert(engine); + const char *gameid = ConfMan.get("gameid").c_str(); + + // We start by checking whether the specified game ID is obsolete. + // If that is the case, we automatically upgrade the target to use + // the correct new game ID (and platform, if specified). + for (const ObsoleteGameID *o = obsoleteGameIDsTable; o->from; ++o) { + if (!scumm_stricmp(gameid, o->from)) { + // Match found, perform upgrade + gameid = o->to; + ConfMan.set("gameid", o->to); + + if (o->platform != Common::kPlatformUnknown) + ConfMan.set("platform", Common::getPlatformCode(o->platform)); + + warning("Target upgraded from game ID %s to %s", o->from, o->to); + ConfMan.flushToDisk(); + break; + } + } + + // Fetch the list of files in the current directory + FSList fslist; + FilesystemNode dir(ConfMan.get("path")); + if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) { + return kInvalidPathError; + } + + // Invoke the detector, but fixed to the specified gameid. + Common::List<DetectorResult> results; + detectGames(fslist, results, gameid); + + // Unable to locate game data + if (results.empty()) { + return kNoGameDataFoundError; + } + + // No unique match found. If a platform override is present, try to + // narrow down the list a bit more. + if (results.size() > 1 && ConfMan.hasKey("platform")) { + Common::Platform platform = Common::parsePlatform(ConfMan.get("platform")); + for (Common::List<DetectorResult>::iterator x = results.begin(); x != results.end(); ) { + if (x->game.platform != platform) { + x = results.erase(x); + } else { + ++x; + } + } + } + + // If we narrowed it down too much, abort + if (results.empty()) { + warning("Engine_SCUMM_create: Game data inconsistent with platform override"); + return kNoGameDataFoundError; + } + + // Still no unique match found -> print a warning + if (results.size() > 1) { + warning("Engine_SCUMM_create: No unique game candidate found, using first one"); + } + + // Simply use the first match + DetectorResult res(*(results.begin())); + debug(1, "Using gameid %s, variant %s, extra %s", res.game.gameid, res.game.variant, res.extra); + + // Print the MD5 of the game; either verbose using printf, in case of an + // unknown MD5, or with a medium debug level in case of a known MD5 (for + // debugging purposes). + if (!findInMD5Table(res.md5.c_str())) { + printf("Your game version appears to be unknown. Please, report the following\n"); + printf("data to the ScummVM team along with name of the game you tried to add\n"); + printf("and its version/language/etc.:\n"); + + printf(" SCUMM gameid '%s', file '%s', MD5 '%s'\n\n", + res.game.gameid, + generateFilenameForDetection(res.fp.pattern, res.fp.genMethod).c_str(), + res.md5.c_str()); + } else { + debug(1, "Using MD5 '%s'", res.md5.c_str()); + } + + // Check for a user override of the platform. We allow the user to override + // the platform, to make it possible to add games which are not yet in + // our MD5 database but require a specific platform setting. + // TODO: Do we really still need / want the platform override ? + if (ConfMan.hasKey("platform")) + res.game.platform = Common::parsePlatform(ConfMan.get("platform")); + + // Language override + if (ConfMan.hasKey("language")) + res.language = Common::parseLanguage(ConfMan.get("language")); + + // V3 FM-TOWNS games *always* should use the corresponding music driver, + // anything else makes no sense for them. + // TODO: Maybe allow the null driver, too? + if (res.game.platform == Common::kPlatformFMTowns && res.game.version == 3) + res.game.midi = MDT_TOWNS; + + // Finally, we have massaged the GameDescriptor to our satisfaction, and can + // instantiate the appropriate game engine. Hooray! + switch (res.game.version) { + case 0: + *engine = new ScummEngine_v0(syst, res); + break; + case 1: + case 2: + *engine = new ScummEngine_v2(syst, res); + break; + case 3: + if ((res.game.features & GF_OLD256) || res.game.platform == Common::kPlatformPCEngine) + *engine = new ScummEngine_v3(syst, res); + else + *engine = new ScummEngine_v3old(syst, res); + break; + case 4: + *engine = new ScummEngine_v4(syst, res); + break; + case 5: + *engine = new ScummEngine_v5(syst, res); + break; + case 6: + switch (res.game.heversion) { +#ifndef DISABLE_HE + case 200: + *engine = new ScummEngine_vCUPhe(syst, res); + break; + case 100: + *engine = new ScummEngine_v100he(syst, res); + break; + case 99: + *engine = new ScummEngine_v99he(syst, res); + break; + case 98: + case 95: + case 90: + *engine = new ScummEngine_v90he(syst, res); + break; + case 85: + case 80: + *engine = new ScummEngine_v80he(syst, res); + break; + case 73: + case 72: + *engine = new ScummEngine_v72he(syst, res); + break; + case 71: + *engine = new ScummEngine_v71he(syst, res); + break; + case 70: + *engine = new ScummEngine_v70he(syst, res); + break; +#endif +#ifndef PALMOS_68K + case 61: + *engine = new ScummEngine_v60he(syst, res); + break; +#endif + default: + *engine = new ScummEngine_v6(syst, res); + } + break; +#ifndef DISABLE_SCUMM_7_8 + case 7: + *engine = new ScummEngine_v7(syst, res); + break; + case 8: + *engine = new ScummEngine_v8(syst, res); + break; +#endif + default: + error("Engine_SCUMM_create(): Unknown version of game engine"); + } + + return kNoError; +} + +REGISTER_PLUGIN(SCUMM, "Scumm Engine", + "LucasArts SCUMM Games (C) LucasArts\n" + "Humongous SCUMM Games (C) Humongous" ); + +#ifdef PALMOS_68K +#include "scumm_globals.h" + +_GINIT(Scumm_md5table) +_GSETPTR(md5table, GBVARS_MD5TABLE_INDEX, MD5Table, GBVARS_SCUMM) +_GEND + +_GRELEASE(Scumm_md5table) +_GRELEASEPTR(GBVARS_MD5TABLE_INDEX, GBVARS_SCUMM) +_GEND + +#endif diff --git a/engines/scumm/plugin.h b/engines/scumm/detection.h index 3b0ddabd54..b75fd7c46e 100644 --- a/engines/scumm/plugin.h +++ b/engines/scumm/detection.h @@ -21,8 +21,8 @@ * */ -#ifndef SCUMM_PLUGIN_H -#define SCUMM_PLUGIN_H +#ifndef SCUMM_DETECTION_H +#define SCUMM_DETECTION_H #include "common/util.h" diff --git a/engines/scumm/plugin.cpp b/engines/scumm/detection_tables.h index ae5ecc1b59..85813aa606 100644 --- a/engines/scumm/plugin.cpp +++ b/engines/scumm/detection_tables.h @@ -1,6 +1,6 @@ /* ScummVM - Scumm Interpreter * Copyright (C) 2001 Ludvig Strigeus - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,19 +21,18 @@ * */ -#include "common/stdafx.h" +#ifndef SCUMM_DETECTION_TABLES_H +#define SCUMM_DETECTION_TABLES_H -#include "base/plugins.h" +#include "common/stdafx.h" -#include "common/config-manager.h" -#include "common/fs.h" -#include "common/list.h" -#include "common/md5.h" +#include "common/rect.h" +#include "common/util.h" -#include "scumm/plugin.h" +#include "scumm/detection.h" #include "scumm/scumm.h" -#include "scumm/intern.h" -#include "scumm/he/intern_he.h" +//#include "scumm/intern.h" +//#include "scumm/he/intern_he.h" #ifdef PALMOS_68K #include "extras/palm-scumm-md5.h" @@ -48,11 +47,6 @@ namespace Scumm { #pragma mark --- Data types & constants --- #pragma mark - -enum { - // We only compute the MD5 of the first megabyte of our data files. - kMD5FileSizeLimit = 1024 * 1024 -}; - struct ObsoleteGameID { const char *from; const char *to; @@ -61,8 +55,6 @@ struct ObsoleteGameID { #define UNK Common::kPlatformUnknown - - #pragma mark - #pragma mark --- Tables --- #pragma mark - @@ -694,6 +686,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "puttcircus", "Putt Circus", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "puttcircus", "PuttIHC", kGenHEPC, Common::NL_NLD, UNK, 0 }, { "puttcircus", "PuttPuttIHC", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, + { "puttcircus", "PuttPuttJTC", kGenHEPC, UNK_LANG, UNK, 0 }, { "puttcircus", "ToffToffGZZ", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "puttrace", "puttrace", kGenHEPC, UNK_LANG, UNK, 0 }, @@ -829,912 +822,6 @@ static const GameFilenamePattern gameFilenamesTable[] = { { NULL, NULL, kGenUnchanged, UNK_LANG, UNK, 0 } }; - -#pragma mark - -#pragma mark --- Miscellaneous --- -#pragma mark - - - -static const char *findDescriptionFromGameID(const char *gameid) { - const PlainGameDescriptor *g = gameDescriptions; - while (g->gameid) { - if (!scumm_stricmp(g->gameid, gameid)) { - return g->description; - } - g++; - } - error("Unknown gameid '%s' encountered in findDescriptionFromGameID", gameid); -} - -static int compareMD5Table(const void *a, const void *b) { - const char *key = (const char *)a; - const MD5Table *elem = (const MD5Table *)b; - return strcmp(key, elem->md5); -} - -static const MD5Table *findInMD5Table(const char *md5) { -#ifdef PALMOS_68K - uint32 arraySize = MemPtrSize((void *)md5table) / sizeof(MD5Table) - 1; -#else - uint32 arraySize = ARRAYSIZE(md5table) - 1; -#endif - return (const MD5Table *)bsearch(md5, md5table, arraySize, sizeof(MD5Table), compareMD5Table); -} - -Common::String ScummEngine::generateFilename(const int room) const { - const int diskNumber = (room > 0) ? _res->roomno[rtRoom][room] : 0; - char buf[128]; - - if (_game.version == 4) { - if (room == 0 || room >= 900) { - snprintf(buf, sizeof(buf), "%03d.lfl", room); - } else { - snprintf(buf, sizeof(buf), "disk%02d.lec", diskNumber); - } - } else { - char id = 0; - - switch (_filenamePattern.genMethod) { - case kGenDiskNum: - snprintf(buf, sizeof(buf), _filenamePattern.pattern, diskNumber); - break; - - case kGenRoomNum: - snprintf(buf, sizeof(buf), _filenamePattern.pattern, room); - break; - - case kGenHEMac: - case kGenHEMacNoParens: - case kGenHEPC: - if (room < 0) { - id = '0' - room; - } else if (_game.heversion >= 98) { - int disk = 0; - if (_heV7DiskOffsets) - disk = _heV7DiskOffsets[room]; - - switch (disk) { - case 2: - id = 'b'; - snprintf(buf, sizeof(buf), "%s.(b)", _filenamePattern.pattern); - break; - case 1: - id = 'a'; - snprintf(buf, sizeof(buf), "%s.(a)", _filenamePattern.pattern); - break; - default: - id = '0'; - snprintf(buf, sizeof(buf), "%s.he0", _filenamePattern.pattern); - } - } else if (_game.heversion >= 70) { - id = (room == 0) ? '0' : '1'; - } else { - id = diskNumber + '0'; - } - - if (_filenamePattern.genMethod == kGenHEPC) { - // For HE >= 98, we already called snprintf above. - if (_game.heversion < 98 || room < 0) - snprintf(buf, sizeof(buf), "%s.he%c", _filenamePattern.pattern, id); - } else { - if (id == '3') { // special case for cursors - // For mac they're stored in game binary - strncpy(buf, _filenamePattern.pattern, sizeof(buf)); - } else { - if (_filenamePattern.genMethod == kGenHEMac) - snprintf(buf, sizeof(buf), "%s (%c)", _filenamePattern.pattern, id); - else - snprintf(buf, sizeof(buf), "%s %c", _filenamePattern.pattern, id); - } - } - - break; - - case kGenUnchanged: - strncpy(buf, _filenamePattern.pattern, sizeof(buf)); - break; - - default: - error("generateFilename: Unsupported genMethod"); - } - } - - return buf; -} - -static Common::String generateFilenameForDetection(const char *pattern, FilenameGenMethod genMethod) { - char buf[128]; - - switch (genMethod) { - case kGenDiskNum: - case kGenRoomNum: - snprintf(buf, sizeof(buf), pattern, 0); - break; - - case kGenHEPC: - snprintf(buf, sizeof(buf), "%s.he0", pattern); - break; - - case kGenHEMac: - snprintf(buf, sizeof(buf), "%s (0)", pattern); - break; - - case kGenHEMacNoParens: - snprintf(buf, sizeof(buf), "%s 0", pattern); - break; - - case kGenUnchanged: - strncpy(buf, pattern, sizeof(buf)); - break; - - default: - error("generateFilenameForDetection: Unsupported genMethod"); - } - - return buf; -} - -struct DetectorDesc { - FilesystemNode node; - Common::String md5; - const MD5Table *md5Entry; // Entry of the md5 table corresponding to this file, if any. -}; - -typedef Common::HashMap<Common::String, DetectorDesc, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> DescMap; - -static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Common::String &file); - - -// Search for a node with the given "name", inside fslist. Ignores case -// when performing the matching. The first match is returned, so if you -// search for "resource" and two nodes "RESOURE and "resource" are present, -// the first match is used. -static bool searchFSNode(const FSList &fslist, const Common::String &name, FilesystemNode &result) { - for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { - if (!scumm_stricmp(file->name().c_str(), name.c_str())) { - result = *file; - return true; - } - } - return false; -} - -// The following function tries to detect the language for COMI and DIG -static Common::Language detectLanguage(const FSList &fslist, byte id) { - assert(id == GID_CMI || id == GID_DIG); - - // Check for LANGUAGE.BND (Dig) resp. LANGUAGE.TAB (CMI). - // These are usually inside the "RESOURCE" subdirectory. - // If found, we match based on the file size (should we - // ever determine that this is insufficient, we can still - // switch to MD5 based detection). - const char *filename = (id == GID_CMI) ? "LANGUAGE.TAB" : "LANGUAGE.BND"; - Common::File tmp; - FilesystemNode langFile; - if (!searchFSNode(fslist, filename, langFile) || !tmp.open(langFile)) { - // try loading in RESOURCE sub dir... - FilesystemNode resDir; - FSList tmpList; - if (searchFSNode(fslist, "RESOURCE", resDir) - && resDir.isDirectory() - && resDir.listDir(tmpList, FilesystemNode::kListFilesOnly) - && searchFSNode(tmpList, filename, langFile)) { - tmp.open(langFile); - } - } - if (tmp.isOpen()) { - uint size = tmp.size(); - if (id == GID_CMI) { - switch (size) { - case 439080: // 2daf3db71d23d99d19fc9a544fcf6431 - return Common::EN_ANY; - case 493252: // 5d59594b24f3f1332e7d7e17455ed533 - return Common::DE_DEU; - case 461746: // 35bbe0e4d573b318b7b2092c331fd1fa - return Common::FR_FRA; - case 443439: // 4689d013f67aabd7c35f4fd7c4b4ad69 - return Common::IT_ITA; - case 440586: // 5a1d0f4fa00917bdbfe035a72a6bba9d - return Common::PT_BRA; - case 449787: // 64f3fe479d45b52902cf88145c41d172 - return Common::ES_ESP; - } - } else { - switch (size) { - case 248627: // 1fd585ac849d57305878c77b2f6c74ff - return Common::DE_DEU; - case 257460: // 04cf6a6ba6f57e517bc40eb81862cfb0 - return Common::FR_FRA; - case 231402: // 93d13fcede954c78e65435592182a4db - return Common::IT_ITA; - case 228772: // 5d9ad90d3a88ea012d25d61791895ebe - return Common::PT_BRA; - case 229884: // d890074bc15c6135868403e73c5f4f36 - return Common::ES_ESP; - } - } - } - - return Common::UNK_LANG; -} - - -static void computeGameSettingsFromMD5(const FSList &fslist, const GameFilenamePattern *gfp, const MD5Table *md5Entry, DetectorResult &dr) { - dr.language = md5Entry->language; - dr.extra = md5Entry->extra; - - // Compute the precise game settings using gameVariantsTable. - for (const GameSettings *g = gameVariantsTable; g->gameid; ++g) { - if (g->gameid[0] == 0 || !scumm_stricmp(md5Entry->gameid, g->gameid)) { - // The gameid either matches, or is empty. The latter indicates - // a generic entry, currently used for some generic HE settings. - if (g->variant == 0 || !scumm_stricmp(md5Entry->variant, g->variant)) { - // Perfect match found, use it and stop the loop - dr.game = *g; - dr.game.gameid = md5Entry->gameid; - - // Set the platform value. The value from the MD5 record has - // highest priority; if missing (i.e. set to unknown) we try - // to use that from the filename pattern record instead. - if (md5Entry->platform != Common::kPlatformUnknown) { - dr.game.platform = md5Entry->platform; - } else if (gfp->platform != Common::kPlatformUnknown) { - dr.game.platform = gfp->platform; - } - - // HACK: Special case to distinguish the V1 demo from the full version - // (since they have identical MD5): - if (dr.game.id == GID_MANIAC && !strcmp(gfp->pattern, "%02d.MAN")) { - dr.extra = "V1 Demo"; - } - - // HACK: If 'Demo' occurs in the extra string, set the GF_DEMO flag, - // required by some game demos (e.g. Dig, FT and COMI). - if (dr.extra && strstr(dr.extra, "Demo")) { - dr.game.features |= GF_DEMO; - } - - // HACK: Detect COMI & Dig languages - if (dr.language == UNK_LANG && (dr.game.id == GID_CMI || dr.game.id == GID_DIG)) { - dr.language = detectLanguage(fslist, dr.game.id); - } - break; - } - } - } -} - -static void detectGames(const FSList &fslist, Common::List<DetectorResult> &results, const char *gameid) { - DescMap fileMD5Map; - DetectorResult dr; - - for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) { - if (!file->isDirectory()) { - DetectorDesc d; - d.node = *file; - d.md5Entry = 0; - fileMD5Map[file->name()] = d; - } - } - - // Iterate over all filename patterns. - for (const GameFilenamePattern *gfp = gameFilenamesTable; gfp->gameid; ++gfp) { - // If a gameid was specified, we only try to detect that specific game, - // so we can just skip over everything with a differing gameid. - if (gameid && scumm_stricmp(gameid, gfp->gameid)) - continue; - - // Generate the detectname corresponding to the gfp. If the file doesn't - // exist in the directory we are looking at, we can skip to the next - // one immediately. - Common::String file(generateFilenameForDetection(gfp->pattern, gfp->genMethod)); - if (!fileMD5Map.contains(file)) - continue; - - // Reset the DetectorResult variable - dr.fp.pattern = gfp->pattern; - dr.fp.genMethod = gfp->genMethod; - dr.game.gameid = 0; - dr.language = gfp->language; - dr.md5.clear(); - dr.extra = 0; - - // ____ _ _ - // | _ \ __ _ _ __| |_ / | - // | |_) / _` | '__| __| | | - // | __/ (_| | | | |_ | | - // |_| \__,_|_| \__| |_| - // - // PART 1: Trying to find an exact match using MD5. - // - // - // Background: We found a valid detection file. Check if its MD5 - // checksum occurs in our MD5 table. If it does, try to use that - // to find an exact match. - // - // We only do that if the MD5 hadn't already been computed (since - // we may look at some detection files multiple times). - // - DetectorDesc &d = fileMD5Map[file]; - if (d.md5.empty()) { - char md5str[32+1]; - if (Common::md5_file_string(d.node, md5str, kMD5FileSizeLimit)) { - - d.md5 = md5str; - d.md5Entry = findInMD5Table(md5str); - - dr.md5 = d.md5; - - if (d.md5Entry) { - // Exact match found. Compute the precise game settings. - computeGameSettingsFromMD5(fslist, gfp, d.md5Entry, dr); - - // Sanity check: We *should* have found a matching gameid / variant at this point. - // If not, then there's a bug in our data tables... - assert(dr.game.gameid != 0); - - // Add it to the list of detected games - results.push_back(dr); - } - } - } - - // If an exact match for this file has already been found, don't bother - // looking at it anymore. - if (d.md5Entry) - continue; - - - // ____ _ ____ - // | _ \ __ _ _ __| |_ |___ \ * - // | |_) / _` | '__| __| __) | - // | __/ (_| | | | |_ / __/ - // |_| \__,_|_| \__| |_____| - // - // PART 2: Fuzzy matching for files with unknown MD5. - // - - - // We loop over the game variants matching the gameid associated to - // the gfp record. We then try to decide for each whether it could be - // appropriate or not. - dr.md5 = d.md5; - for (const GameSettings *g = gameVariantsTable; g->gameid; ++g) { - // Skip over entries with a different gameid. - if (g->gameid[0] == 0 || scumm_stricmp(gfp->gameid, g->gameid)) - continue; - - dr.game = *g; - dr.extra = g->variant; // FIXME: We (ab)use 'variant' for the 'extra' description for now. - - if (gfp->platform != Common::kPlatformUnknown) - dr.game.platform = gfp->platform; - - - // If a variant has been specified, use that! - if (gfp->variant) { - if (!scumm_stricmp(gfp->variant, g->variant)) { - // perfect match found - results.push_back(dr); - break; - } - continue; - } - - - // Add the game/variant to the candidates list if it is consistent - // with the file(s) we are seeing. - if (testGame(g, fileMD5Map, file)) - results.push_back(dr); - } - } -} - -static bool testGame(const GameSettings *g, const DescMap &fileMD5Map, const Common::String &file) { - const DetectorDesc &d = fileMD5Map[file]; - - // At this point, we know that the gameid matches, but no variant - // was specified, yet there are multiple ones. So we try our best - // to distinguish between the variants. - // To do this, we take a close look at the detection file and - // try to filter out some cases. - - Common::File tmp; - if (!tmp.open(d.node)) { - warning("SCUMM detectGames: failed to open '%s' for read access", d.node.path().c_str()); - return false; - } - - if (file == "maniac1.d64" || file == "maniac1.dsk" || file == "zak1.d64") { - // TODO - } else if (file == "00.LFL") { - // Used in V1, V2, V3 games. - if (g->version > 3) - return false; - - // Read a few bytes to narrow down the game. - byte buf[6]; - tmp.read(buf, 6); - - if (buf[0] == 0xbc && buf[1] == 0xb9) { - // The NES version of MM - if (g->id == GID_MANIAC && g->platform == Common::kPlatformNES) { - // perfect match - return true; - } - } else if ((buf[0] == 0xCE && buf[1] == 0xF5) || // PC - (buf[0] == 0xCD && buf[1] == 0xFE)) { // Commodore 64 - // Could be V0 or V1. - // Candidates: maniac classic, zak classic - - if (g->version >= 2) - return false; - - // Zak has 58.LFL, Maniac doesn't have it. - const bool has58LFL = fileMD5Map.contains("58.LFL"); - if (g->id == GID_MANIAC && !has58LFL) { - } else if (g->id == GID_ZAK && has58LFL) { - } else - return false; - } else if (buf[0] == 0xFF && buf[1] == 0xFE) { - // GF_OLD_BUNDLE: could be V2 or old V3. - // Note that GF_OLD_BUNDLE is true if and only if GF_OLD256 is false. - // Candidates: maniac enhanced, zak enhanced, indy3ega, loom - - if (g->version != 2 && g->version != 3 || (g->features & GF_OLD256)) - return false; - - /* We distinguish the games by the presence/absence of - certain files. In the following, '+' means the file - present, '-' means the file is absent. - - maniac: -58.LFL, -84.LFL,-86.LFL, -98.LFL - - zak: +58.LFL, -84.LFL,-86.LFL, -98.LFL - zakdemo: +58.LFL, -84.LFL,-86.LFL, -98.LFL - - loom: +58.LFL, -84.LFL,+86.LFL, -98.LFL - loomdemo: -58.LFL, +84.LFL,-86.LFL, -98.LFL - - indy3: +58.LFL, +84.LFL,+86.LFL, +98.LFL - indy3demo: -58.LFL, +84.LFL,-86.LFL, +98.LFL - */ - const bool has58LFL = fileMD5Map.contains("58.LFL"); - const bool has84LFL = fileMD5Map.contains("84.LFL"); - const bool has86LFL = fileMD5Map.contains("86.LFL"); - const bool has98LFL = fileMD5Map.contains("98.LFL"); - - if (g->id == GID_INDY3 && has98LFL && has84LFL) { - } else if (g->id == GID_ZAK && !has98LFL && !has86LFL && !has84LFL && has58LFL) { - } else if (g->id == GID_MANIAC && !has98LFL && !has86LFL && !has84LFL && !has58LFL) { - } else if (g->id == GID_LOOM && !has98LFL && (has86LFL != has84LFL)) { - } else - return false; - } else if (buf[4] == '0' && buf[5] == 'R') { - // newer V3 game - // Candidates: indy3, indy3Towns, zakTowns, loomTowns - - if (g->version != 3 || !(g->features & GF_OLD256)) - return false; - - /* - Considering that we know about *all* TOWNS versions, and - know their MD5s, we could simply rely on this and if we find - something which has an unknown MD5, assume that it is an (so - far unknown) version of Indy3. However, there are also fan - translations of the TOWNS versions, so we can't do that. - - But we could at least look at the resource headers to distinguish - TOWNS versions from regular games: - - Indy3: - _numGlobalObjects 1000 - _numRooms 99 - _numCostumes 129 - _numScripts 139 - _numSounds 84 - - Indy3Towns, ZakTowns, ZakLoom demo: - _numGlobalObjects 1000 - _numRooms 99 - _numCostumes 199 - _numScripts 199 - _numSounds 199 - - Assuming that all the town variants look like the latter, we can - do the check like this: - if (numScripts == 139) - assume Indy3 - else if (numScripts == 199) - assume towns game - else - unknown, do not accept it - */ - - // We now try to exclude various possibilities by the presence of certain - // LFL files. Note that we only exclude something based on the *presence* - // of a LFL file here; compared to checking for the absence of files, this - // has the advantage that we are less likely to accidentally exclude demos - // (which, after all, are usually missing many LFL files present in the - // full version of the game). - - // No version of Indy3 has 05.LFL but MM, Loom and Zak all have it - if (g->id == GID_INDY3 && fileMD5Map.contains("05.LFL")) - return false; - - // All versions of Indy3 have 93.LFL, but no other game - if (g->id != GID_INDY3 && fileMD5Map.contains("93.LFL")) - return false; - - // No version of Loom has 48.LFL - if (g->id == GID_LOOM && fileMD5Map.contains("48.LFL")) - return false; - - // No version of Zak has 60.LFL, but most (non-demo) versions of Indy3 have it - if (g->id == GID_ZAK && fileMD5Map.contains("60.LFL")) - return false; - - // All versions of Indy3 and ZakTOWNS have 98.LFL, but no other game - if (g->id == GID_LOOM && fileMD5Map.contains("98.LFL")) - return false; - - - } else { - // TODO: Unknown file header, deal with it. Maybe an unencrypted - // variant... - // Anyway, we don't know to deal with the file, so we - // just skip it. - } - } else if (file == "000.LFL") { - // Used in V4 - // Candidates: monkeyEGA, pass, monkeyVGA, loomcd - - if (g->version != 4) - return false; - - /* - For all of them, we have: - _numGlobalObjects 1000 - _numRooms 99 - _numCostumes 199 - _numScripts 199 - _numSounds 199 - - Any good ideas to distinguish those? Maybe by the presence / absence - of some files? - At least PASS and the monkeyEGA demo differ by 903.LFL missing... - And the count of DISK??.LEC files differs depending on what version - you have (4 or 8 floppy versions). - loomcd of course shipped on only one "disc". - - pass: 000.LFL, 901.LFL, 902.LFL, 904.LFL, disk01.lec - monkeyEGA: 000.LFL, 901-904.LFL, DISK01-09.LEC - monkeyEGA DEMO: 000.LFL, 901.LFL, 902.LFL, 904.LFL, disk01.lec - monkeyVGA: 000.LFL, 901-904.LFL, DISK01-04.LEC - loomcd: 000.LFL, 901-904.LFL, DISK01.LEC - */ - - const bool has903LFL = fileMD5Map.contains("903.LFL"); - const bool hasDisk02 = fileMD5Map.contains("DISK02.LEC"); - - // There is not much we can do based on the presence / absence - // of files. Only that if 903.LFL is present, it can't be PASS; - // and if DISK02.LEC is present, it can't be LoomCD - if (g->id == GID_PASS && !has903LFL && !hasDisk02) { - } else if (g->id == GID_LOOM && has903LFL && !hasDisk02) { - } else if (g->id == GID_MONKEY_VGA) { - } else if (g->id == GID_MONKEY_EGA) { - } else - return false; - } else { - // Must be a V5+ game - if (g->version < 5) - return false; - - // So at this point the gameid is determined, but not necessarily - // the variant! - - // TODO: Add code that handles this, at least for the non-HE games. - // Note sure how realistic it is to correctly detect HE-game - // variants, would require me to look at a sufficiently large - // sample collection of HE games (assuming I had the time :). - - // TODO: For Mac versions in container file, we can sometimes - // distinguish the demo from the regular version by looking - // at the content of the container file and then looking for - // the *.000 file in there. - } - - return true; -} - - } // End of namespace Scumm -#pragma mark - -#pragma mark --- Plugin code --- -#pragma mark - - - -using namespace Scumm; - -GameList Engine_SCUMM_gameIDList() { - const PlainGameDescriptor *g = gameDescriptions; - GameList games; - while (g->gameid) { - games.push_back(GameDescriptor(g->gameid, g->description)); - g++; - } - return games; -} - -GameDescriptor Engine_SCUMM_findGameID(const char *gameid) { - // First search the list of supported game IDs. - const PlainGameDescriptor *g = gameDescriptions; - while (g->gameid) { - if (0 == scumm_stricmp(gameid, g->gameid)) - return GameDescriptor(g->gameid, g->description); - g++; - } - - // If we didn't find the gameid in the main list, check if it - // is an obsolete game id. - GameDescriptor gs; - const ObsoleteGameID *o = obsoleteGameIDsTable; - while (o->from) { - if (0 == scumm_stricmp(gameid, o->from)) { - gs["gameid"] = gameid; - gs["description"] = "Obsolete game ID"; - return gs; - } - o++; - } - return gs; -} - - -GameList Engine_SCUMM_detectGames(const FSList &fslist) { - GameList detectedGames; - Common::List<DetectorResult> results; - - detectGames(fslist, results, 0); - - // TODO: We still don't handle the FM-TOWNS demos (like zakloom) very well. - // In particular, they are detected as ZakTowns, which is bad. - - for (Common::List<DetectorResult>::iterator x = results.begin(); x != results.end(); ++x) { - GameDescriptor dg(x->game.gameid, findDescriptionFromGameID(x->game.gameid), - x->language, x->game.platform); - dg.updateDesc(x->extra); // Append additional information, if set, to the description. - - // Compute and set the preferred target name for this game. - // Based on generateComplexID() in advancedDetector.cpp. - Common::String res(x->game.gameid); - - if (x->game.preferredTag) { - res = res + "-" + x->game.preferredTag; - } - - if (x->game.features & GF_DEMO) { - res = res + "-demo"; - } - - // Append the platform, if a non-standard one has been specified. - if (x->game.platform != Common::kPlatformPC && x->game.platform != Common::kPlatformUnknown) { - // HACK: For CoMI, it's pointless to encode the fact that it's for Windows - if (x->game.id != GID_CMI) - res = res + "-" + Common::getPlatformAbbrev(x->game.platform); - } - - // Append the language, if a non-standard one has been specified - if (x->language != Common::EN_ANY && x->language != Common::UNK_LANG) { - res = res + "-" + Common::getLanguageCode(x->language); - } - - dg["preferredtarget"] = res; - - detectedGames.push_back(dg); - } - - return detectedGames; -} - -/** - * Create a ScummEngine instance, based on the given detector data. - * - * This is heavily based on our MD5 detection scheme. - */ -PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) { - assert(syst); - assert(engine); - const char *gameid = ConfMan.get("gameid").c_str(); - - // We start by checking whether the specified game ID is obsolete. - // If that is the case, we automatically upgrade the target to use - // the correct new game ID (and platform, if specified). - for (const ObsoleteGameID *o = obsoleteGameIDsTable; o->from; ++o) { - if (!scumm_stricmp(gameid, o->from)) { - // Match found, perform upgrade - gameid = o->to; - ConfMan.set("gameid", o->to); - - if (o->platform != Common::kPlatformUnknown) - ConfMan.set("platform", Common::getPlatformCode(o->platform)); - - warning("Target upgraded from game ID %s to %s", o->from, o->to); - ConfMan.flushToDisk(); - break; - } - } - - // Fetch the list of files in the current directory - FSList fslist; - FilesystemNode dir(ConfMan.get("path")); - if (!dir.listDir(fslist, FilesystemNode::kListFilesOnly)) { - return kInvalidPathError; - } - - // Invoke the detector, but fixed to the specified gameid. - Common::List<DetectorResult> results; - detectGames(fslist, results, gameid); - - // Unable to locate game data - if (results.empty()) { - return kNoGameDataFoundError; - } - - // No unique match found. If a platform override is present, try to - // narrow down the list a bit more. - if (results.size() > 1 && ConfMan.hasKey("platform")) { - Common::Platform platform = Common::parsePlatform(ConfMan.get("platform")); - for (Common::List<DetectorResult>::iterator x = results.begin(); x != results.end(); ) { - if (x->game.platform != platform) { - x = results.erase(x); - } else { - ++x; - } - } - } - - // If we narrowed it down too much, abort - if (results.empty()) { - warning("Engine_SCUMM_create: Game data inconsistent with platform override"); - return kNoGameDataFoundError; - } - - // Still no unique match found -> print a warning - if (results.size() > 1) { - warning("Engine_SCUMM_create: No unique game candidate found, using first one"); - } - - // Simply use the first match - DetectorResult res(*(results.begin())); - debug(1, "Using gameid %s, variant %s, extra %s", res.game.gameid, res.game.variant, res.extra); - - // Print the MD5 of the game; either verbose using printf, in case of an - // unknown MD5, or with a medium debug level in case of a known MD5 (for - // debugging purposes). - if (!findInMD5Table(res.md5.c_str())) { - printf("Your game version appears to be unknown. Please, report the following\n"); - printf("data to the ScummVM team along with name of the game you tried to add\n"); - printf("and its version/language/etc.:\n"); - - printf(" SCUMM gameid '%s', file '%s', MD5 '%s'\n\n", - res.game.gameid, - generateFilenameForDetection(res.fp.pattern, res.fp.genMethod).c_str(), - res.md5.c_str()); - } else { - debug(1, "Using MD5 '%s'", res.md5.c_str()); - } - - // Check for a user override of the platform. We allow the user to override - // the platform, to make it possible to add games which are not yet in - // our MD5 database but require a specific platform setting. - // TODO: Do we really still need / want the platform override ? - if (ConfMan.hasKey("platform")) - res.game.platform = Common::parsePlatform(ConfMan.get("platform")); - - // Language override - if (ConfMan.hasKey("language")) - res.language = Common::parseLanguage(ConfMan.get("language")); - - // V3 FM-TOWNS games *always* should use the corresponding music driver, - // anything else makes no sense for them. - // TODO: Maybe allow the null driver, too? - if (res.game.platform == Common::kPlatformFMTowns && res.game.version == 3) - res.game.midi = MDT_TOWNS; - - // Finally, we have massaged the GameDescriptor to our satisfaction, and can - // instantiate the appropriate game engine. Hooray! - switch (res.game.version) { - case 0: - *engine = new ScummEngine_v0(syst, res); - break; - case 1: - case 2: - *engine = new ScummEngine_v2(syst, res); - break; - case 3: - if ((res.game.features & GF_OLD256) || res.game.platform == Common::kPlatformPCEngine) - *engine = new ScummEngine_v3(syst, res); - else - *engine = new ScummEngine_v3old(syst, res); - break; - case 4: - *engine = new ScummEngine_v4(syst, res); - break; - case 5: - *engine = new ScummEngine_v5(syst, res); - break; - case 6: - switch (res.game.heversion) { -#ifndef DISABLE_HE - case 200: - *engine = new ScummEngine_vCUPhe(syst, res); - break; - case 100: - *engine = new ScummEngine_v100he(syst, res); - break; - case 99: - *engine = new ScummEngine_v99he(syst, res); - break; - case 98: - case 95: - case 90: - *engine = new ScummEngine_v90he(syst, res); - break; - case 85: - case 80: - *engine = new ScummEngine_v80he(syst, res); - break; - case 73: - case 72: - *engine = new ScummEngine_v72he(syst, res); - break; - case 71: - *engine = new ScummEngine_v71he(syst, res); - break; - case 70: - *engine = new ScummEngine_v70he(syst, res); - break; -#endif -#ifndef PALMOS_68K - case 61: - *engine = new ScummEngine_v60he(syst, res); - break; -#endif - default: - *engine = new ScummEngine_v6(syst, res); - } - break; -#ifndef DISABLE_SCUMM_7_8 - case 7: - *engine = new ScummEngine_v7(syst, res); - break; - case 8: - *engine = new ScummEngine_v8(syst, res); - break; -#endif - default: - error("Engine_SCUMM_create(): Unknown version of game engine"); - } - - return kNoError; -} - -REGISTER_PLUGIN(SCUMM, "Scumm Engine", - "LucasArts SCUMM Games (C) LucasArts\n" - "Humongous SCUMM Games (C) Humongous" ); - -#ifdef PALMOS_68K -#include "scumm_globals.h" - -_GINIT(Scumm_md5table) -_GSETPTR(md5table, GBVARS_MD5TABLE_INDEX, MD5Table, GBVARS_SCUMM) -_GEND - -_GRELEASE(Scumm_md5table) -_GRELEASEPTR(GBVARS_MD5TABLE_INDEX, GBVARS_SCUMM) -_GEND - #endif diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h index 772414d649..bfcdaf2960 100644 --- a/engines/scumm/dialogs.h +++ b/engines/scumm/dialogs.h @@ -27,7 +27,7 @@ #include "gui/options.h" #include "gui/widget.h" -#include "scumm/plugin.h" +#include "scumm/detection.h" #ifndef DISABLE_HELP #include "scumm/help.h" #endif diff --git a/engines/scumm/file.h b/engines/scumm/file.h index cc0ba926e9..0c78a5c5c2 100644 --- a/engines/scumm/file.h +++ b/engines/scumm/file.h @@ -25,7 +25,7 @@ #include "common/file.h" -#include "scumm/plugin.h" +#include "scumm/detection.h" namespace Scumm { diff --git a/engines/scumm/he/logic_he.h b/engines/scumm/he/logic_he.h index e0f70ff52a..1f2303da1f 100644 --- a/engines/scumm/he/logic_he.h +++ b/engines/scumm/he/logic_he.h @@ -40,11 +40,11 @@ public: int getFromArray(int arg0, int idx2, int idx1); void putInArray(int arg0, int idx2, int idx1, int val); - void beforeBootScript(void) {}; - void initOnce() {}; - void startOfFrame() {}; - void endOfFrame() {}; - void processKeyStroke(int keyPressed) {}; + void beforeBootScript(void) {} + void initOnce() {} + void startOfFrame() {} + void endOfFrame() {} + void processKeyStroke(int keyPressed) {} virtual int versionID(); virtual int32 dispatch(int op, int numArgs, int32 *args); diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h index c04055962e..411dd375e2 100644 --- a/engines/scumm/he/resource_he.h +++ b/engines/scumm/he/resource_he.h @@ -118,10 +118,10 @@ public: void setCursor(int id); - virtual int extractResource(int id, byte **buf) { return 0; }; + virtual int extractResource(int id, byte **buf) { return 0; } virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, int *hotspot_x, int *hotspot_y, int *keycolor, - byte **palette, int *palSize) { return 0; }; + byte **palette, int *palSize) { return 0; } enum { MAX_CACHED_CURSORS = 10 @@ -154,7 +154,7 @@ public: class Win32ResExtractor : public ResExtractor { public: Win32ResExtractor(ScummEngine_v70he *scumm); - ~Win32ResExtractor() {}; + ~Win32ResExtractor() {} int extractResource(int id, byte **data); void setCursor(int id); int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 54feafb115..d31d3afd85 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -145,8 +145,18 @@ void ScummEngine::parseEvents() { // possible to a bug in sdl-common.cpp if (event.kbd.ascii >= 512) debugC(DEBUG_GENERAL, "keyPressed > 512 (%d)", event.kbd.ascii); - else + else { _keyDownMap[event.kbd.ascii] = false; + + // Due to some weird bug with capslock key pressed + // generated keydown event is for lower letter but + // keyup is for upper letter + // On most (all?) keyboards it is safe to assume that + // both upper and lower letters are unpressed on keyup event + // + // Fixes bug #1709430: "FT: CAPSLOCK + V enables cheating for all fights" + _keyDownMap[toupper(event.kbd.ascii)] = false; + } break; diff --git a/engines/scumm/intern.h b/engines/scumm/intern.h index 796867a116..3d3a07a2ed 100644 --- a/engines/scumm/intern.h +++ b/engines/scumm/intern.h @@ -972,6 +972,7 @@ protected: virtual const char *getOpcodeDesc(byte i); virtual void printString(int m, const byte *msg); + virtual void CHARSET_1(); virtual void scummLoop_handleSaveLoad(); diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index cb5d041aa7..d7b858a312 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -11,6 +11,7 @@ MODULE_OBJS := \ costume.o \ cursor.o \ debugger.o \ + detection.o \ dialogs.o \ file.o \ gfx.o \ @@ -34,7 +35,6 @@ MODULE_OBJS := \ player_v2.o \ player_v2a.o \ player_v3a.o \ - plugin.o \ resource_v2.o \ resource_v3.o \ resource_v4.o \ diff --git a/engines/scumm/player_v2a.cpp b/engines/scumm/player_v2a.cpp index e1f36464bb..5957e2378f 100644 --- a/engines/scumm/player_v2a.cpp +++ b/engines/scumm/player_v2a.cpp @@ -63,7 +63,7 @@ static uint32 GetCRC (byte *data, int len) class V2A_Sound { public: V2A_Sound() : _id(0), _mod(NULL) { } - virtual ~V2A_Sound() {}; + virtual ~V2A_Sound() {} virtual void start(Player_MOD *mod, int id, const byte *data) = 0; virtual bool update() = 0; virtual void stop() = 0; diff --git a/engines/scumm/resource_v2.cpp b/engines/scumm/resource_v2.cpp index 08393da708..6a4f1ea30b 100644 --- a/engines/scumm/resource_v2.cpp +++ b/engines/scumm/resource_v2.cpp @@ -93,7 +93,7 @@ void ScummEngine_v2::readClassicIndexFile() { for (i = 0; i < _numRooms; i++) { _res->roomoffs[rtRoom][i] = _fileHandle->readUint16LE(); if (_res->roomoffs[rtRoom][i] == 0xFFFF) - _res->roomoffs[rtRoom][i] = RES_INVALID_OFFSET; + _res->roomoffs[rtRoom][i] = (uint32)RES_INVALID_OFFSET; } for (i = 0; i < _numCostumes; i++) { @@ -102,7 +102,7 @@ void ScummEngine_v2::readClassicIndexFile() { for (i = 0; i < _numCostumes; i++) { _res->roomoffs[rtCostume][i] = _fileHandle->readUint16LE(); if (_res->roomoffs[rtCostume][i] == 0xFFFF) - _res->roomoffs[rtCostume][i] = RES_INVALID_OFFSET; + _res->roomoffs[rtCostume][i] = (uint32)RES_INVALID_OFFSET; } for (i = 0; i < _numScripts; i++) { @@ -111,7 +111,7 @@ void ScummEngine_v2::readClassicIndexFile() { for (i = 0; i < _numScripts; i++) { _res->roomoffs[rtScript][i] = _fileHandle->readUint16LE(); if (_res->roomoffs[rtScript][i] == 0xFFFF) - _res->roomoffs[rtScript][i] = RES_INVALID_OFFSET; + _res->roomoffs[rtScript][i] = (uint32)RES_INVALID_OFFSET; } for (i = 0; i < _numSounds; i++) { @@ -120,7 +120,7 @@ void ScummEngine_v2::readClassicIndexFile() { for (i = 0; i < _numSounds; i++) { _res->roomoffs[rtSound][i] = _fileHandle->readUint16LE(); if (_res->roomoffs[rtSound][i] == 0xFFFF) - _res->roomoffs[rtSound][i] = RES_INVALID_OFFSET; + _res->roomoffs[rtSound][i] = (uint32)RES_INVALID_OFFSET; } } diff --git a/engines/scumm/resource_v3.cpp b/engines/scumm/resource_v3.cpp index 1ac159c9a5..2a4add52f3 100644 --- a/engines/scumm/resource_v3.cpp +++ b/engines/scumm/resource_v3.cpp @@ -54,7 +54,7 @@ void ScummEngine_v3old::readResTypeList(int id) { for (i = 0; i < num; i++) { _res->roomoffs[id][i] = _fileHandle->readUint16LE(); if (_res->roomoffs[id][i] == 0xFFFF) - _res->roomoffs[id][i] = RES_INVALID_OFFSET; + _res->roomoffs[id][i] = (uint32)RES_INVALID_OFFSET; } } diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 7df428529a..242b7c9f51 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -834,6 +834,8 @@ void ScummEngine::saveOrLoad(Serializer *s) { MKLINE(StringTab, _default.overhead, sleByte, VER(8)), MKLINE(StringTab, no_talk_anim, sleByte, VER(8)), MKLINE(StringTab, _default.no_talk_anim, sleByte, VER(8)), + MKLINE(StringTab, wrapping, sleByte, VER(71)), + MKLINE(StringTab, _default.wrapping, sleByte, VER(71)), MKEND() }; @@ -1150,6 +1152,17 @@ void ScummEngine::saveOrLoad(Serializer *s) { if (_imuse && (_saveSound || !_saveTemporaryState)) { _imuse->save_or_load(s, this); } + + // + // Save/load the charset renderer state + // + if (s->getVersion() >= VER(72)) { + if (s->isSaving()) { + s->saveByte(_charset->getCurID()); + } else { + _charset->setCurID(s->loadByte()); + } + } } void ScummEngine_v0::saveOrLoad(Serializer *s) { diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index e98704bc2b..0c4bc14001 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 70 +#define CURRENT_VER 72 /** * An auxillary macro, used to specify savegame versions. We use this instead diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 2c562f0470..fca3228696 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -870,6 +870,11 @@ enum StringIds { }; void ScummEngine_v5::o5_saveLoadVars() { + // The KIXX XL release of Monkey Island 2 (Amiga disk) used this opcode + // as dummy, in order to remove copy protection and keep level selection. + if (_game.version == 5) + return; + if (fetchScriptByte() == 1) saveVars(); else diff --git a/engines/scumm/script_v8.cpp b/engines/scumm/script_v8.cpp index 17b494250e..011c41856a 100644 --- a/engines/scumm/script_v8.cpp +++ b/engines/scumm/script_v8.cpp @@ -488,7 +488,7 @@ void ScummEngine_v8::decodeParseString(int m, int n) { _string[m].charset = pop(); break; case 0xCE: // SO_PRINT_LEFT - _string[m].center = false; + _string[m].wrapping = false; _string[m].overhead = false; break; case 0xCF: // SO_PRINT_OVERHEAD @@ -503,7 +503,8 @@ void ScummEngine_v8::decodeParseString(int m, int n) { _scriptPointer += resStrLen(_scriptPointer) + 1; break; case 0xD2: // SO_PRINT_WRAP Set print wordwrap - //debug(0, "decodeParseString: SO_PRINT_WRAP"); + _string[m].wrapping = true; + _string[m].overhead = false; break; default: error("decodeParseString: default case 0x%x", b); diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 791c1d4579..05d18f8a90 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Sun Apr 08 01:14:52 2007 + This file was generated by the md5table tool on Sun May 13 00:46:42 2007 DO NOT EDIT MANUALLY! */ @@ -155,6 +155,7 @@ static const MD5Table md5table[] = { { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh }, { "3a5ec90d556d4920976c5578bfbfaf79", "maniac", "NES", "extracted", -1, Common::DE_DEU, Common::kPlatformNES }, { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC }, + { "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows }, { "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformPC }, { "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, { "3de99ef0523f8ca7958faa3afccd035a", "spyfox", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, @@ -403,6 +404,7 @@ static const MD5Table md5table[] = { { "b23f7cd7c304d7dff08e92a96120d5b4", "zak", "V1", "V1", -1, Common::EN_ANY, Common::kPlatformPC }, { "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformPC }, { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC }, + { "b47be81e39a9710f6f595f7b527b60f8", "puttrace", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows }, { "b5298a5c15ffbe8b381d51ea4e26d35c", "freddi4", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "b597e0403cc0002f69170e6caba7edd9", "indy3", "EGA", "EGA Demo", 5361, Common::EN_ANY, Common::kPlatformPC }, { "b628506f7def772e40de0aa5440fb8e1", "activity", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows }, @@ -443,6 +445,7 @@ static const MD5Table md5table[] = { { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh }, { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC }, { "cd424f143a141bc59226ad83a6e40f51", "maze", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, + { "cd46c9f122272d02bbf79332ff521898", "loom", "EGA", "EGA", 5748, Common::RU_RUS, Common::kPlatformPC }, { "cd9c05e755d7bf8e9b9590ad1ebe273e", "dig", "Demo", "Demo", 45156007, Common::EN_ANY, Common::kPlatformMacintosh }, { "cdd760228cf1010c2903f37e788ea31c", "zak", "V2", "V2", 1916, Common::DE_DEU, Common::kPlatformPC }, { "ce2304f3919e1dcfcc512a81d7b603e0", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, @@ -484,6 +487,7 @@ static const MD5Table md5table[] = { { "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformPC }, { "da669b20271b85182e9c17a2a37ea02e", "monkey2", "", "", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "db21a6e338fe3b70c2723b6530865bf2", "PuttTime", "HE 85", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, + { "db74136c20557eca6ed3411bff39f7a1", "puttcircus", "", "", -1, Common::EN_GRB, Common::kPlatformWindows }, { "dbf4d59d70b826733f379f998354d350", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "dcf0119a90451a7d6e0f1920931ba130", "freddi4", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "dd30a53035393baa5a5e222e716559af", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAtariST }, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 9ff08d7e5b..5da8ddf8fa 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -24,7 +24,7 @@ #include "common/stdafx.h" #include "common/config-manager.h" -#include "common/fs.h" +//#include "common/fs.h" #include "common/md5.h" #include "common/events.h" #include "common/system.h" @@ -1553,6 +1553,39 @@ void ScummEngine::setupMusic(int midi) { _musicType = MDT_MIDI; break; } + + if ((_game.id == GID_MONKEY_EGA || (_game.id == GID_LOOM && _game.version == 3)) + && (_game.platform == Common::kPlatformPC) && _musicType == MDT_MIDI) { + Common::String fileName; + bool missingFile = false; + if (_game.id == GID_LOOM) { + Common::File f; + // The Roland Update does have an 85.LFL, but we don't + // test for it since the demo doesn't have it. + for (char c = '2'; c <= '4'; c++) { + fileName = "8"; + fileName += c; + fileName += ".LFL"; + if (!Common::File::exists(fileName)) { + missingFile = true; + break; + } + } + } else if (_game.id == GID_MONKEY_EGA) { + fileName = "DISK09.LEC"; + if (!Common::File::exists(fileName)) { + missingFile = true; + } + } + + if (missingFile) { + GUI::MessageDialog dialog( + "Native MIDI support requires the Roland Upgrade from LucasArts,\n" + "but " + fileName + " is missing. Using Adlib instead.", "Ok"); + dialog.runModal(); + _musicType = MDT_ADLIB; + } + } // DOTT + SAM use General MIDI, so they shouldn't use GS settings if ((_game.id == GID_TENTACLE) || (_game.id == GID_SAMNMAX)) diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 90cb14de1f..33df01be1d 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -32,7 +32,7 @@ #include "graphics/surface.h" #include "scumm/gfx.h" -#include "scumm/plugin.h" +#include "scumm/detection.h" #include "scumm/script.h" #include "sound/mididrv.h" @@ -243,6 +243,7 @@ struct StringSlot { bool center; bool overhead; bool no_talk_anim; + bool wrapping; }; struct StringTab : StringSlot { @@ -1169,7 +1170,7 @@ protected: virtual void printString(int m, const byte *msg); virtual bool handleNextCharsetCode(Actor *a, int *c); - void CHARSET_1(); + virtual void CHARSET_1(); void drawString(int a, const byte *msg); void debugMessage(const byte *msg); void showMessageDialog(const byte *msg); diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp index 79930160a9..0b5a1450e5 100644 --- a/engines/scumm/smush/smush_player.cpp +++ b/engines/scumm/smush/smush_player.cpp @@ -82,7 +82,7 @@ public: StringResource() : _nbStrings(0), _lastId(-1) { - }; + } ~StringResource() { for (int32 i = 0; i < _nbStrings; i++) { delete []_strings[i].string; diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index 9f29418ca6..c54eb25db5 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -1221,7 +1221,7 @@ int ScummEngine::readSoundResource(int type, int idx) { debugC(DEBUG_SOUND, "FMUS file %s", buffer); if (dmuFile.open(buffer) == false) { error("Can't open music file %s*", buffer); - _res->roomoffs[type][idx] = RES_INVALID_OFFSET; + _res->roomoffs[type][idx] = (uint32)RES_INVALID_OFFSET; return 0; } dmuFile.seek(4, SEEK_SET); @@ -1245,7 +1245,7 @@ int ScummEngine::readSoundResource(int type, int idx) { } error("Unrecognized base tag 0x%08x in sound %d", basetag, idx); } - _res->roomoffs[type][idx] = RES_INVALID_OFFSET; + _res->roomoffs[type][idx] = (uint32)RES_INVALID_OFFSET; return 0; } @@ -2107,7 +2107,7 @@ int ScummEngine::readSoundResourceSmallHeader(int type, int idx) { _fileHandle->read(_res->createResource(type, idx, ro_size - 4), ro_size - 4); return 1; } - _res->roomoffs[type][idx] = RES_INVALID_OFFSET; + _res->roomoffs[type][idx] = (uint32)RES_INVALID_OFFSET; return 0; } diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp index 432cd7f1c9..b255737fa3 100644 --- a/engines/scumm/string.cpp +++ b/engines/scumm/string.cpp @@ -437,7 +437,7 @@ void ScummEngine::CHARSET_1() { if (getTalkingActor() != 0xFF) a = derefActorSafe(getTalkingActor(), "CHARSET_1"); - if (a && _string[0].overhead != 0) { + if (a && _string[0].overhead) { int s; _string[0].xpos = a->getPos().x - virtscr[0].xstart; @@ -490,8 +490,7 @@ void ScummEngine::CHARSET_1() { return; if ((_game.version <= 6 && _haveMsg == 1) || - (_game.version == 7 && _haveMsg != 1) || - (_game.version == 8 && VAR(VAR_HAVE_MSG))) { + (_game.version == 7 && _haveMsg != 1)) { if (_game.heversion >= 60) { if (_sound->isSoundRunning(1) == 0) @@ -644,6 +643,164 @@ void ScummEngine::CHARSET_1() { #endif } +#ifndef DISABLE_SCUMM_7_8 +void ScummEngine_v8::CHARSET_1() { + byte subtitleBuffer[2048]; + byte *subtitleLine = subtitleBuffer; + Common::Point subtitlePos; + + processSubtitleQueue(); + + if (!_haveMsg) + return; + + Actor *a = NULL; + if (getTalkingActor() != 0xFF) + a = derefActorSafe(getTalkingActor(), "CHARSET_1"); + + StringTab saveStr = _string[0]; + if (a && _string[0].overhead) { + int s; + + _string[0].xpos = a->getPos().x - virtscr[0].xstart; + s = a->_scalex * a->_talkPosX / 255; + _string[0].xpos += (a->_talkPosX - s) / 2 + s; + + _string[0].ypos = a->getPos().y - a->getElevation() - _screenTop; + s = a->_scaley * a->_talkPosY / 255; + _string[0].ypos += (a->_talkPosY - s) / 2 + s; + } + + _charset->setColor(_charsetColor); + + if (a && a->_charset) + _charset->setCurID(a->_charset); + else + _charset->setCurID(_string[0].charset); + + if (_talkDelay) + return; + + if (VAR(VAR_HAVE_MSG)) { + if ((_sound->_sfxMode & 2) == 0) { + stopTalk(); + } + return; + } + + if (a && !_string[0].no_talk_anim) { + a->runActorTalkScript(a->_talkStartFrame); + } + + if (!_keepText) { + clearSubtitleQueue(); + _nextLeft = _string[0].xpos; + _nextTop = _string[0].ypos + _screenTop; + } + + _charset->_disableOffsX = _charset->_firstChar = !_keepText; + + _talkDelay = VAR(VAR_DEFAULT_TALK_DELAY); + for (int i = _charsetBufPos; _charsetBuffer[i]; ++i) { + _talkDelay += VAR(VAR_CHARINC); + } + + if (_string[0].wrapping) { + _charset->addLinebreaks(0, _charsetBuffer, _charsetBufPos, _screenWidth - 20); + + struct { int pos, w; } substring[10]; + int count = 0; + int maxLineWidth = 0; + int lastPos = 0; + int code = 0; + while (handleNextCharsetCode(a, &code)) { + if (code == 13 || code == 0) { + *subtitleLine++ = '\0'; + assert(count < 10); + substring[count].w = _charset->getStringWidth(0, subtitleBuffer + lastPos); + if (maxLineWidth < substring[count].w) { + maxLineWidth = substring[count].w; + } + substring[count].pos = lastPos; + ++count; + lastPos = subtitleLine - subtitleBuffer; + } else { + *subtitleLine++ = code; + *subtitleLine = '\0'; + } + if (code == 0) { + break; + } + } + + int h = count * _charset->getFontHeight(); + h += _charset->getFontHeight() / 2; + subtitlePos.y = _string[0].ypos; + if (subtitlePos.y + h > _screenHeight - 10) { + subtitlePos.y = _screenHeight - 10 - h; + } + if (subtitlePos.y < 10) { + subtitlePos.y = 10; + } + + for (int i = 0; i < count; ++i) { + subtitlePos.x = _string[0].xpos; + if (_string[0].center) { + if (subtitlePos.x + maxLineWidth / 2 > _screenWidth - 10) { + subtitlePos.x = _screenWidth - 10 - maxLineWidth / 2; + } + if (subtitlePos.x - maxLineWidth / 2 < 10) { + subtitlePos.x = 10 + maxLineWidth / 2; + } + subtitlePos.x -= substring[i].w / 2; + } else { + if (subtitlePos.x + maxLineWidth > _screenWidth - 10) { + subtitlePos.x = _screenWidth - 10 - maxLineWidth; + } + if (subtitlePos.x - maxLineWidth < 10) { + subtitlePos.x = 10; + } + } + if (subtitlePos.y < _screenHeight - 10) { + addSubtitleToQueue(subtitleBuffer + substring[i].pos, subtitlePos, _charsetColor, _charset->getCurID()); + } + subtitlePos.y += _charset->getFontHeight(); + } + } else { + int code = 0; + subtitlePos.y = _string[0].ypos; + if (subtitlePos.y < 10) { + subtitlePos.y = 10; + } + while (handleNextCharsetCode(a, &code)) { + if (code == 13 || code == 0) { + subtitlePos.x = _string[0].xpos; + if (_string[0].center) { + subtitlePos.x -= _charset->getStringWidth(0, subtitleBuffer) / 2; + } + if (subtitlePos.x < 10) { + subtitlePos.x = 10; + } + if (subtitlePos.y < _screenHeight - 10) { + addSubtitleToQueue(subtitleBuffer, subtitlePos, _charsetColor, _charset->getCurID()); + subtitlePos.y += _charset->getFontHeight(); + } + subtitleLine = subtitleBuffer; + } else { + *subtitleLine++ = code; + } + *subtitleLine = '\0'; + if (code == 0) { + break; + } + } + } + _haveMsg = 2; + _keepText = false; + _string[0] = saveStr; +} +#endif + void ScummEngine::drawString(int a, const byte *msg) { byte buf[270]; byte *space; @@ -1073,6 +1230,14 @@ void ScummEngine_v7::loadLanguageBundle() { ScummFile file; int32 size; + // if game is manually set to English, don't try to load localized text + if ((_language == Common::EN_ANY) || (_language == Common::EN_USA) || (_language == Common::EN_GRB)) { + warning("Language file is forced to be ignored"); + + _existLanguageFile = false; + return; + } + if (_game.id == GID_DIG) { openFile(file, "language.bnd"); } else if (_game.id == GID_CMI) { diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index 7bd12fd9c9..7c73b42b1f 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -707,22 +707,11 @@ void ScummEngine::resetScummVars() { default: if ((_game.id == GID_MONKEY_EGA || _game.id == GID_MONKEY_VGA || (_game.id == GID_LOOM && _game.version == 3)) && (_game.platform == Common::kPlatformPC)) { - if (_game.id == GID_LOOM) { - char buf[50]; - Common::File f; - for (int i = 82; i < 85; i++) { - sprintf(buf, "%d.LFL", i); - if (!Common::File::exists(buf)) - error("Native MIDI support requires Roland patch from LucasArts, but %s is missing", buf); - } - } else if (_game.id == GID_MONKEY_EGA) { - if (!Common::File::exists("DISK09.LEC")) - error("Native MIDI support requires Roland patch from LucasArts, but DISK09.LEC is missing"); - } VAR(VAR_SOUNDCARD) = 4; } else { VAR(VAR_SOUNDCARD) = 3; } + break; } if (_game.platform == Common::kPlatformFMTowns) diff --git a/engines/sky/control.h b/engines/sky/control.h index 4143772495..efccd268f4 100644 --- a/engines/sky/control.h +++ b/engines/sky/control.h @@ -133,10 +133,10 @@ struct AllocedMem { class ConResource { public: ConResource(void *pSpData, uint32 pNSprites, uint32 pCurSprite, uint16 pX, uint16 pY, uint32 pText, uint8 pOnClick, OSystem *system, uint8 *screen); - virtual ~ConResource(void) {}; - void setSprite(void *pSpData) { _spriteData = (dataFileHeader*)pSpData; }; - void setText(uint32 pText) { if (pText) _text = pText + 0x7000; else _text = 0; }; - void setXY(uint16 x, uint16 y) { _x = x; _y = y; }; + virtual ~ConResource(void) {} + void setSprite(void *pSpData) { _spriteData = (dataFileHeader*)pSpData; } + void setText(uint32 pText) { if (pText) _text = pText + 0x7000; else _text = 0; } + void setXY(uint16 x, uint16 y) { _x = x; _y = y; } bool isMouseOver(uint32 mouseX, uint32 mouseY); virtual void drawToScreen(bool doMask); diff --git a/engines/sky/disk.h b/engines/sky/disk.h index 99cb105740..df0b8e380f 100644 --- a/engines/sky/disk.h +++ b/engines/sky/disk.h @@ -54,7 +54,7 @@ public: void fnCacheChip(uint16 *fList); void fnCacheFiles(void); void fnFlushBuffers(void); - uint32 *giveLoadedFilesList(void) { return _loadedFilesList; }; + uint32 *giveLoadedFilesList(void) { return _loadedFilesList; } void refreshFilesList(uint32 *list); protected: diff --git a/engines/sky/logic.h b/engines/sky/logic.h index 53752ca88f..d1189bbef0 100644 --- a/engines/sky/logic.h +++ b/engines/sky/logic.h @@ -143,7 +143,7 @@ public: Sound *skySound); ~Logic(void); void engine(); - void useControlInstance(Control *control) { _skyControl = control; }; + void useControlInstance(Control *control) { _skyControl = control; } uint16 mouseScript(uint32 scrNum, Compact *scriptComp); diff --git a/engines/sky/music/musicbase.h b/engines/sky/music/musicbase.h index 1f2bd58740..1adb03fc9c 100644 --- a/engines/sky/music/musicbase.h +++ b/engines/sky/music/musicbase.h @@ -39,7 +39,7 @@ typedef struct { class ChannelBase { public: - virtual ~ChannelBase() {}; + virtual ~ChannelBase() {} virtual uint8 process(uint16 aktTime) = 0; virtual void updateVolume(uint16 pVolume) = 0; virtual bool isActive(void) = 0; diff --git a/engines/sky/screen.h b/engines/sky/screen.h index 872d6cf613..15223b0c3e 100644 --- a/engines/sky/screen.h +++ b/engines/sky/screen.h @@ -71,14 +71,14 @@ public: void startSequence(uint16 fileNum); void startSequenceItem(uint16 itemNum); void stopSequence(void); - bool sequenceRunning(void) { return _seqInfo.running; }; + bool sequenceRunning(void) { return _seqInfo.running; } void waitForSequence(void); - uint32 seqFramesLeft(void) { return _seqInfo.framesLeft; }; - uint8 *giveCurrent(void) { return _currentScreen; }; + uint32 seqFramesLeft(void) { return _seqInfo.framesLeft; } + uint8 *giveCurrent(void) { return _currentScreen; } void halvePalette(void); //- regular screen.asm routines - void forceRefresh(void) { memset(_gameGrid, 0x80, GRID_X * GRID_Y); }; + void forceRefresh(void) { memset(_gameGrid, 0x80, GRID_X * GRID_Y); } void fnFadeUp(uint32 palNum, uint32 scroll); void fnFadeDown(uint32 scroll); void fnDrawScreen(uint32 palette, uint32 scroll); diff --git a/engines/sky/sound.h b/engines/sky/sound.h index b515e0e8a4..4d7456195e 100644 --- a/engines/sky/sound.h +++ b/engines/sky/sound.h @@ -70,7 +70,7 @@ public: void playSound(uint16 sound, uint16 volume, uint8 channel); void fnStartFx(uint32 sound, uint8 channel); bool startSpeech(uint16 textNum); - bool speechFinished(void) { return !_mixer->isSoundHandleActive(_ingameSpeech); }; + bool speechFinished(void) { return !_mixer->isSoundHandleActive(_ingameSpeech); } void fnPauseFx(void); void fnUnPauseFx(void); void fnStopFx(void); diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp index 5a381e7393..c80614d2d4 100644 --- a/engines/sword1/animation.cpp +++ b/engines/sword1/animation.cpp @@ -25,6 +25,7 @@ #include "sword1/sword1.h" #include "sword1/animation.h" #include "sword1/credits.h" +#include "sword1/text.h" #include "sound/vorbis.h" #include "common/config-manager.h" @@ -62,11 +63,13 @@ static const char *sequenceList[20] = { // Basic movie player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer::MoviePlayer(Screen *scr, Audio::Mixer *snd, OSystem *sys) - : _scr(scr), _snd(snd), _system(sys) { +MoviePlayer::MoviePlayer(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) + : _screen(screen), _textMan(textMan), _snd(snd), _system(system) { _bgSoundStream = NULL; _ticks = 0; - _frameBuffer = NULL; + _textSpriteBuf = NULL; + _black = 1; + _white = 255; _currentFrame = 0; _forceFrame = false; _framesSkipped = 0; @@ -78,15 +81,36 @@ MoviePlayer::~MoviePlayer(void) { void MoviePlayer::updatePalette(byte *pal, bool packed) { byte palette[4 * 256]; byte *p = palette; + + uint32 maxWeight = 0; + uint32 minWeight = 0xFFFFFFFF; + for (int i = 0; i < 256; i++) { - *p++ = *pal++; - *p++ = *pal++; - *p++ = *pal++; + int r = *pal++; + int g = *pal++; + int b = *pal++; + if (!packed) - *p++ = *pal++; - else - *p++ = 0; + pal++; + + uint32 weight = 3 * r * r + 6 * g * g + 2 * b * b; + + if (weight >= maxWeight) { + _white = i; + maxWeight = weight; + } + + if (weight <= minWeight) { + _black = i; + minWeight = i; + } + + *p++ = r; + *p++ = g; + *p++ = b; + *p++ = 0; } + _system->setPalette(palette, 0, 256); _forceFrame = true; } @@ -148,16 +172,58 @@ bool MoviePlayer::syncFrame(void) { * @param id the id of the file */ bool MoviePlayer::load(uint32 id) { + Common::File f; + char fileName[20]; + _id = id; _bgSoundStream = NULL; + + if (SwordEngine::_systemVars.showText) { + sprintf(fileName, "%s.txt", sequenceList[id]); + if (f.open(fileName)) { + char line[120]; + int lineNo = 0; + int lastEnd = -1; + + _movieTexts.clear(); + while (f.readLine(line, sizeof(line))) { + lineNo++; + if (line[0] == '#' || line[0] == 0) { + continue; + } + + char *ptr = line; + + // TODO: Better error handling + int startFrame = strtoul(ptr, &ptr, 10); + int endFrame = strtoul(ptr, &ptr, 10); + + while (*ptr && isspace(*ptr)) + ptr++; + + if (startFrame > endFrame) { + warning("%s:%d: startFrame (%d) > endFrame (%d)", fileName, lineNo, startFrame, endFrame); + continue; + } + + if (startFrame <= lastEnd) { + warning("%s:%d startFrame (%d) <= lastEnd (%d)", fileName, lineNo, startFrame, lastEnd); + continue; + } + + _movieTexts.push_back(new MovieText(startFrame, endFrame, ptr)); + lastEnd = endFrame; + } + } + } + if (SwordEngine::_systemVars.cutscenePackVersion == 1) { if ((id == SEQ_INTRO) || (id == SEQ_FINALE) || (id == SEQ_HISTORY) || (id == SEQ_FERRARI)) { #ifdef USE_VORBIS // these sequences are language specific - char sndName[20]; - sprintf(sndName, "%s.snd", sequenceList[id]); + sprintf(fileName, "%s.snd", sequenceList[id]); Common::File *oggSource = new Common::File(); - if (oggSource->open(sndName)) { + if (oggSource->open(fileName)) { SplittedAudioStream *sStream = new SplittedAudioStream(); uint32 numSegs = oggSource->readUint32LE(); // number of audio segments, either 1 or 2. // for each segment and each of the 7 languages, we've got fileoffset and size @@ -170,13 +236,13 @@ bool MoviePlayer::load(uint32 id) { Common::MemoryReadStream *stream = oggSource->readStream(segSize); Audio::AudioStream *apStream = Audio::makeVorbisStream(stream, true); if (!apStream) - error("Can't create Vorbis Stream from file %s", sndName); + error("Can't create Vorbis Stream from file %s", fileName); sStream->appendStream(apStream); } free(header); _bgSoundStream = sStream; } else - warning("Sound file \"%s\" not found", sndName); + warning("Sound file \"%s\" not found", fileName); delete oggSource; #endif initOverlays(id); @@ -186,7 +252,7 @@ bool MoviePlayer::load(uint32 id) { } void MoviePlayer::play(void) { - _scr->clearScreen(); + _screen->clearScreen(); _framesSkipped = 0; _ticks = _system->getMillis(); _bgSoundStream = Audio::AudioStream::openStreamFile(sequenceList[_id]); @@ -197,6 +263,24 @@ void MoviePlayer::play(void) { bool terminated = false; Common::EventManager *eventMan = _system->getEventManager(); while (!terminated && decodeFrame()) { + if (!_movieTexts.empty()) { + if (_currentFrame == _movieTexts[0]->_startFrame) { + _textMan->makeTextSprite(2, (uint8 *)_movieTexts[0]->_text, 600, LETTER_COL); + + FrameHeader *frame = _textMan->giveSpriteData(2); + _textWidth = frame->width; + _textHeight = frame->height; + _textX = 320 - _textWidth / 2; + _textY = 420 - _textHeight; + _textSpriteBuf = (byte *)calloc(_textHeight, _textWidth); + } + if (_currentFrame == _movieTexts[0]->_endFrame) { + _textMan->releaseText(2); + free(_textSpriteBuf); + _textSpriteBuf = NULL; + delete _movieTexts.remove_at(0); + } + } processFrame(); if (syncFrame()) updateScreen(); @@ -221,6 +305,11 @@ void MoviePlayer::play(void) { } } } + + while (!_movieTexts.empty()) { + delete _movieTexts.remove_at(_movieTexts.size() - 1); + } + while (_snd->isSoundHandleActive(_bgSoundHandle)) _system->delayMillis(100); @@ -301,14 +390,13 @@ int SplittedAudioStream::readBuffer(int16 *buffer, const int numSamples) { // Movie player for the new DXA movies /////////////////////////////////////////////////////////////////////////////// -MoviePlayerDXA::MoviePlayerDXA(Screen *src, Audio::Mixer *snd, OSystem *sys) - : MoviePlayer(src, snd, sys) { +MoviePlayerDXA::MoviePlayerDXA(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) + : MoviePlayer(screen, textMan, snd, system) { debug(0, "Creating DXA cutscene player"); } MoviePlayerDXA::~MoviePlayerDXA(void) { closeFile(); - // free(_frameBuffer); } bool MoviePlayerDXA::load(uint32 id) { @@ -348,13 +436,51 @@ bool MoviePlayerDXA::decodeFrame(void) { } void MoviePlayerDXA::processFrame(void) { - // TODO + // TODO: Handle the advanced cutscene packs. Do they really exist? + + // We cannot draw the text to _drawBuffer, sinzce ethat's one of the + // decoder's internal buffers. Instead, we copy part of _drawBuffer + // to the text sprite. + + if (_textSpriteBuf) { + memset(_textSpriteBuf, 0, _textWidth * _textHeight); + + // FIXME: This is inefficient + int x, y; + + for (y = _textY; y < _textY + _textHeight; y++) { + for (x = _textX; x < _textX + _textWidth; x++) { + if (x >= _frameX && x <= _frameX + _frameWidth && y >= _frameY && y <= _frameY + _frameHeight) { + _textSpriteBuf[(y - _textY) * _textWidth + x - _textX] = _drawBuffer[(y - _frameY) * _frameWidth + x - _frameX]; + } + } + } + + byte *src = (byte *)_textMan->giveSpriteData(2) + sizeof(FrameHeader); + byte *dst = _textSpriteBuf; + + for (y = 0; y < _textHeight; y++) { + for (x = 0; x < _textWidth; x++) { + switch (src[x]) { + case BORDER_COL: + dst[x] = _black; + break; + case LETTER_COL: + dst[x] = _white; + break; + } + } + src += _textWidth; + dst += _textWidth; + } + } } void MoviePlayerDXA::updateScreen(void) { - // Using _drawBuffer directly should work, as long as we don't do any - // post-processing of the frame. _system->copyRectToScreen(_drawBuffer, _frameWidth, _frameX, _frameY, _frameWidth, _frameHeight); + if (_textSpriteBuf) { + _system->copyRectToScreen(_textSpriteBuf, _textWidth, _textX, _textY, _textWidth, _textHeight); + } _system->updateScreen(); } @@ -366,8 +492,8 @@ void MoviePlayerDXA::updateScreen(void) { // Movie player for the old MPEG movies /////////////////////////////////////////////////////////////////////////////// -MoviePlayerMPEG::MoviePlayerMPEG(Screen *src, Audio::Mixer *snd, OSystem *sys) - : MoviePlayer(src, snd, sys) { +MoviePlayerMPEG::MoviePlayerMPEG(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) + : MoviePlayer(screen, textMan, snd, system) { #ifdef BACKEND_8BIT debug(0, "Creating MPEG cutscene player (8-bit)"); #else @@ -399,7 +525,7 @@ void MoviePlayerMPEG::insertOverlay(OverlayColor *buf, uint8 *ovl, OverlayColor bool MoviePlayerMPEG::load(uint32 id) { if (MoviePlayer::load(id)) { - _anim = new AnimationState(this, _scr, _system); + _anim = new AnimationState(this, _screen, _system); return _anim->init(sequenceList[id]); } return false; @@ -454,8 +580,8 @@ void MoviePlayerMPEG::processFrame(void) { #endif } -AnimationState::AnimationState(MoviePlayer *player, Screen *scr, OSystem *sys) - : BaseAnimationState(sys, 640, 400), _player(player), _scr(scr) { +AnimationState::AnimationState(MoviePlayer *player, Screen *screen, OSystem *system) + : BaseAnimationState(system, 640, 400), _player(player), _screen(screen) { } AnimationState::~AnimationState(void) { @@ -472,7 +598,7 @@ void AnimationState::drawYUV(int width, int height, byte *const *dat) { _frameHeight = height; #ifdef BACKEND_8BIT - _scr->plotYUV(_lut, width, height, dat); + _screen->plotYUV(_lut, width, height, dat); #else plotYUV(width, height, dat); #endif @@ -499,7 +625,7 @@ Audio::AudioStream *AnimationState::createAudioStream(const char *name, void *ar // Factory function for creating the appropriate cutscene player /////////////////////////////////////////////////////////////////////////////// -MoviePlayer *makeMoviePlayer(uint32 id, Screen *scr, Audio::Mixer *snd, OSystem *sys) { +MoviePlayer *makeMoviePlayer(uint32 id, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system) { #if defined(USE_ZLIB) || defined(USE_MPEG2) char filename[20]; #endif @@ -508,7 +634,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, Screen *scr, Audio::Mixer *snd, OSystem snprintf(filename, sizeof(filename), "%s.dxa", sequenceList[id]); if (Common::File::exists(filename)) { - return new MoviePlayerDXA(scr, snd, sys); + return new MoviePlayerDXA(screen, textMan, snd, system); } #endif @@ -516,7 +642,7 @@ MoviePlayer *makeMoviePlayer(uint32 id, Screen *scr, Audio::Mixer *snd, OSystem snprintf(filename, sizeof(filename), "%s.mp2", sequenceList[id]); if (Common::File::exists(filename)) { - return new MoviePlayerMPEG(scr, snd, sys); + return new MoviePlayerMPEG(screen, textMan, snd, system); } #endif diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h index 34f05d0a11..4e76c200c5 100644 --- a/engines/sword1/animation.h +++ b/engines/sword1/animation.h @@ -58,9 +58,24 @@ enum { #define INTRO_LOGO_OVLS 12 #define INTRO_TEXT_OVLS 8 +class MovieText { +public: + uint16 _startFrame; + uint16 _endFrame; + char *_text; + MovieText(int startFrame, int endFrame, char *text) { + _startFrame = startFrame; + _endFrame = endFrame; + _text = strdup(text); + } + ~MovieText() { + free(_text); + } +}; + class MoviePlayer { public: - MoviePlayer(Screen *scr, Audio::Mixer *snd, OSystem *sys); + MoviePlayer(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system); virtual ~MoviePlayer(void); virtual bool load(uint32 id); void play(void); @@ -68,13 +83,17 @@ public: private: bool checkSkipFrame(void); protected: - Screen *_scr; + Screen *_screen; + Text *_textMan; Audio::Mixer *_snd; OSystem *_system; + Common::Array<MovieText *> _movieTexts; + byte *_textSpriteBuf; + int _textX, _textY, _textWidth, _textHeight; + byte _black, _white; uint32 _id; - byte *_frameBuffer; uint _currentFrame; int _framesSkipped; bool _forceFrame; @@ -100,7 +119,7 @@ class MoviePlayerDXA : public MoviePlayer, ::Graphics::DXAPlayer { protected: virtual void setPalette(byte *pal); public: - MoviePlayerDXA(Screen *scr, Audio::Mixer *snd, OSystem *sys); + MoviePlayerDXA(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system); virtual ~MoviePlayerDXA(void); bool load(uint32 id); protected: @@ -117,10 +136,10 @@ protected: class AnimationState : public Graphics::BaseAnimationState { private: MoviePlayer *_player; - Screen *_scr; + Screen *_screen; public: - AnimationState(MoviePlayer *player, Screen *scr, OSystem *sys); + AnimationState(MoviePlayer *player, Screen *screen, OSystem *system); ~AnimationState(void); OverlayColor *giveRgbBuffer(void); @@ -137,7 +156,7 @@ protected: class MoviePlayerMPEG : public MoviePlayer { public: - MoviePlayerMPEG(Screen *scr, Audio::Mixer *snd, OSystem *sys); + MoviePlayerMPEG(Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system); virtual ~MoviePlayerMPEG(void); bool load(uint32 id); protected: @@ -173,7 +192,7 @@ private: FileQueue *_queue; }; -MoviePlayer *makeMoviePlayer(uint32 id, Screen *scr, Audio::Mixer *snd, OSystem *sys); +MoviePlayer *makeMoviePlayer(uint32 id, Screen *screen, Text *textMan, Audio::Mixer *snd, OSystem *system); } // End of namespace Sword1 diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp index aeb9da700b..d8cc03bce5 100644 --- a/engines/sword1/control.cpp +++ b/engines/sword1/control.cpp @@ -327,7 +327,8 @@ uint8 Control::getClicks(uint8 mode, uint8 *retVal) { uint8 flag = 0; if (_keyPressed == 27) flag = kButtonCancel; - else if (_keyPressed == '\r' || _keyPressed == '\n') + // 3 is num keypad Enter on Macs. See FR #1273746 + else if (_keyPressed == '\r' || _keyPressed == '\n' || _keyPressed == 3) flag = kButtonOk; if (flag) { diff --git a/engines/sword1/credits.h b/engines/sword1/credits.h index 5a60cc320d..bce2678cd3 100644 --- a/engines/sword1/credits.h +++ b/engines/sword1/credits.h @@ -40,7 +40,7 @@ public: uint8 *fetchFile(uint32 fileId, uint32 *size = NULL); uint8 *decompressFile(uint32 fileId); void enterPath(uint32 id); - void backToRoot(void) { _bufPos = _buf; }; + void backToRoot(void) { _bufPos = _buf; } private: uint8 *_bufPos; uint8 *_buf; diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp index f0c4f18cc5..1f6a648a9e 100644 --- a/engines/sword1/logic.cpp +++ b/engines/sword1/logic.cpp @@ -957,7 +957,7 @@ int Logic::fnPlaySequence(Object *cpt, int32 id, int32 sequenceId, int32 d, int3 CreditsPlayer player(_system, _mixer); player.play(); } else { - MoviePlayer *player = makeMoviePlayer(sequenceId, _screen, _mixer, _system); + MoviePlayer *player = makeMoviePlayer(sequenceId, _screen, _textMan, _mixer, _system); if (player) { if (player->load(sequenceId)) player->play(); diff --git a/engines/sword1/screen.cpp b/engines/sword1/screen.cpp index a3045440f5..605e1127cf 100644 --- a/engines/sword1/screen.cpp +++ b/engines/sword1/screen.cpp @@ -136,6 +136,12 @@ void Screen::fnSetPalette(uint8 start, uint16 length, uint32 id, bool fadeUp) { uint8 *palData = (uint8*)_resMan->openFetchRes(id); if (start == 0) // force color 0 to black palData[0] = palData[1] = palData[2] = 0; + + if (SwordEngine::_systemVars.isMac) { // see bug #1701058 + if (start != 0 && start + length == 256) // and force color 255 to black as well + palData[(length-1)*3+0] = palData[(length-1)*3+1] = palData[(length-1)*3+2] = 0; + } + for (uint32 cnt = 0; cnt < length; cnt++) { _targetPalette[(start + cnt) * 4 + 0] = palData[cnt * 3 + 0] << 2; _targetPalette[(start + cnt) * 4 + 1] = palData[cnt * 3 + 1] << 2; @@ -359,7 +365,8 @@ void Screen::draw(void) { for (uint16 cnty = 0; cnty < _scrnSizeY; cnty++) for (uint16 cntx = 0; cntx < _scrnSizeX; cntx++) { if (*src) - *dest = *src; + if (!SwordEngine::_systemVars.isMac || *src != 255) // see bug #1701058 + *dest = *src; dest++; src++; } diff --git a/engines/sword1/sound.h b/engines/sword1/sound.h index ddd0f017f3..2542c02b9e 100644 --- a/engines/sword1/sound.h +++ b/engines/sword1/sound.h @@ -72,10 +72,10 @@ class Sound { public: Sound(const char *searchPath, Audio::Mixer *mixer, ResMan *pResMan); ~Sound(void); - void setSpeechVol(uint8 volL, uint8 volR) { _speechVolL = volL; _speechVolR = volR; }; - void setSfxVol(uint8 volL, uint8 volR) { _sfxVolL = volL; _sfxVolR = volR; }; - void giveSpeechVol(uint8 *volL, uint8 *volR) { *volL = _speechVolL; *volR = _speechVolR; }; - void giveSfxVol(uint8 *volL, uint8 *volR) { *volL = _sfxVolL; *volR = _sfxVolR; }; + void setSpeechVol(uint8 volL, uint8 volR) { _speechVolL = volL; _speechVolR = volR; } + void setSfxVol(uint8 volL, uint8 volR) { _sfxVolL = volL; _sfxVolR = volR; } + void giveSpeechVol(uint8 *volL, uint8 *volR) { *volL = _speechVolL; *volR = _speechVolR; } + void giveSfxVol(uint8 *volL, uint8 *volR) { *volL = _sfxVolL; *volR = _sfxVolR; } void newScreen(uint32 screen); void quitScreen(void); void closeCowSystem(void); diff --git a/engines/sword1/text.cpp b/engines/sword1/text.cpp index 3b28ed5691..f55eed52b0 100644 --- a/engines/sword1/text.cpp +++ b/engines/sword1/text.cpp @@ -34,9 +34,6 @@ namespace Sword1 { #define OVERLAP 3 #define SPACE ' ' -#define BORDER_COL 200 -#define LETTER_COL 193 -#define NO_COL 0 // sprite background - 0 for transparency #define MAX_LINES 30 @@ -49,14 +46,13 @@ Text::Text(ObjectMan *pObjMan, ResMan *pResMan, bool czechVersion) { _joinWidth = charWidth( SPACE ) - 2 * OVERLAP; _charHeight = _resMan->getUint16(_resMan->fetchFrame(_font, 0)->height); // all chars have the same height - _textBlocks[0] = _textBlocks[1] = NULL; + for (int i = 0; i < MAX_TEXT_OBS; i++) + _textBlocks[i] = NULL; } Text::~Text(void) { - if (_textBlocks[0]) - free(_textBlocks[0]); - if (_textBlocks[1]) - free(_textBlocks[1]); + for (int i = 0; i < MAX_TEXT_OBS; i++) + free(_textBlocks[i]); //_resMan->resClose(_fontId); => wiped automatically by _resMan->flush(); } @@ -175,14 +171,14 @@ FrameHeader *Text::giveSpriteData(uint32 textTarget) { // textTarget is the resource ID of the Compact linking the textdata. // that's 0x950000 for slot 0 and 0x950001 for slot 1. easy, huh? :) textTarget &= ITM_ID; - assert(textTarget <= 1); + assert(textTarget < MAX_TEXT_OBS); return _textBlocks[textTarget]; } void Text::releaseText(uint32 id) { id &= ITM_ID; - assert(id <= 1); + assert(id < MAX_TEXT_OBS); if (_textBlocks[id]) { free(_textBlocks[id]); _textBlocks[id] = NULL; diff --git a/engines/sword1/text.h b/engines/sword1/text.h index c5d10fbf0c..dc3f48eb77 100644 --- a/engines/sword1/text.h +++ b/engines/sword1/text.h @@ -28,7 +28,11 @@ namespace Sword1 { -#define MAX_TEXT_OBS 2 +#define MAX_TEXT_OBS 3 + +#define BORDER_COL 200 +#define LETTER_COL 193 +#define NO_COL 0 // sprite background - 0 for transparency class ObjectMan; class ResMan; @@ -44,10 +48,10 @@ public: ~Text(void); FrameHeader *giveSpriteData(uint32 textTarget); uint32 lowTextManager(uint8 *text, int32 width, uint8 pen); + void makeTextSprite(uint8 slot, uint8 *text, uint16 maxWidth, uint8 pen); void releaseText(uint32 id); private: - void makeTextSprite(uint8 slot, uint8 *text, uint16 maxWidth, uint8 pen); uint16 analyzeSentence(uint8 *text, uint16 maxWidth, LineInfo *info); uint16 charWidth(uint8 ch); uint16 copyChar(uint8 ch, uint8 *sprPtr, uint16 sprWidth, uint8 pen); diff --git a/engines/sword2/screen.cpp b/engines/sword2/screen.cpp index cd02af76fa..603a4d4d90 100644 --- a/engines/sword2/screen.cpp +++ b/engines/sword2/screen.cpp @@ -798,7 +798,7 @@ struct CreditsLine { CreditsLine() { str = NULL; sprite = NULL; - }; + } ~CreditsLine() { free(str); diff --git a/engines/touche/plugin.cpp b/engines/touche/detection.cpp index cff91ecd83..cff91ecd83 100644 --- a/engines/touche/plugin.cpp +++ b/engines/touche/detection.cpp diff --git a/engines/touche/graphics.cpp b/engines/touche/graphics.cpp index 686b60d285..32daa98cbe 100644 --- a/engines/touche/graphics.cpp +++ b/engines/touche/graphics.cpp @@ -31,11 +31,15 @@ void Graphics::setupFont(Common::Language language) { switch (language) { case Common::FR_FRA: case Common::DE_DEU: - _fontOffs = _locFontOffs; - _fontSize = _locFontSize; - _fontData = _locFontData; + _fontOffs = _freGerFontOffs; + _fontSize = _freGerFontSize; + _fontData = _freGerFontData; break; case Common::ES_ESP: + _fontOffs = _spaFontOffs; + _fontSize = _spaFontSize; + _fontData = _spaFontData; + break; case Common::IT_ITA: case Common::EN_ANY: default: diff --git a/engines/touche/graphics.h b/engines/touche/graphics.h index 55d2090bf2..71b77dc22c 100644 --- a/engines/touche/graphics.h +++ b/engines/touche/graphics.h @@ -47,13 +47,20 @@ public: private: + /* font data for english version */ static const uint16 _engFontOffs[]; static const int _engFontSize; static const uint8 _engFontData[]; - static const uint16 _locFontOffs[]; - static const int _locFontSize; - static const uint8 _locFontData[]; + /* font data for french and german versions */ + static const uint16 _freGerFontOffs[]; + static const int _freGerFontSize; + static const uint8 _freGerFontData[]; + + /* font data for spanish version */ + static const uint16 _spaFontOffs[]; + static const int _spaFontSize; + static const uint8 _spaFontData[]; static const uint16 *_fontOffs; static int _fontSize; diff --git a/engines/touche/module.mk b/engines/touche/module.mk index 1c68d1b7c3..c1bc0b5719 100644 --- a/engines/touche/module.mk +++ b/engines/touche/module.mk @@ -1,9 +1,9 @@ MODULE := engines/touche MODULE_OBJS := \ + detection.o \ graphics.o \ midi.o \ - plugin.o \ opcodes.o \ resource.o \ saveload.o \ diff --git a/engines/touche/resource.cpp b/engines/touche/resource.cpp index 1d57a5b036..92a83cdd7f 100644 --- a/engines/touche/resource.cpp +++ b/engines/touche/resource.cpp @@ -193,8 +193,8 @@ uint32 ToucheEngine::res_getDataOffset(ResourceType type, int num, uint32 *size) const ResourceData *rd = NULL; for (unsigned int i = 0; i < ARRAYSIZE(dataTypesTable); ++i) { - rd = &dataTypesTable[i]; - if (rd->type == type) { + if (dataTypesTable[i].type == type) { + rd = &dataTypesTable[i]; break; } } diff --git a/engines/touche/staticres.cpp b/engines/touche/staticres.cpp index 1104ec6b5f..8a68bbe049 100644 --- a/engines/touche/staticres.cpp +++ b/engines/touche/staticres.cpp @@ -450,7 +450,7 @@ const uint8 Graphics::_engFontData[] = { 0x00, 0x35, 0xF0, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00 }; -const uint16 Graphics::_locFontOffs[] = { +const uint16 Graphics::_freGerFontOffs[] = { 0x0000, 0x0007, 0x0024, 0x0043, 0x0072, 0x00AD, 0x00E0, 0x0113, 0x0124, 0x0141, 0x015E, 0x0191, 0x01C4, 0x01E3, 0x01F8, 0x0215, 0x0232, 0x0269, 0x0286, 0x02BD, 0x02F4, 0x032B, 0x0362, 0x0399, 0x03D0, 0x0407, 0x043E, 0x045B, 0x047C, 0x0495, @@ -473,9 +473,9 @@ const uint16 Graphics::_locFontOffs[] = { 0x0000, 0x0000, 0x0000, 0x1920 }; -const int Graphics::_locFontSize = ARRAYSIZE(Graphics::_locFontOffs); +const int Graphics::_freGerFontSize = ARRAYSIZE(Graphics::_freGerFontOffs); -const uint8 Graphics::_locFontData[] = { +const uint8 Graphics::_freGerFontData[] = { 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D, 0x05, 0x3C, 0x03, 0xD7, 0x0D, 0xD7, 0xCD, 0xD7, 0xCD, 0xD7, 0xCD, 0xD7, 0xC3, 0xD7, 0xC0, 0xD7, 0xC0, 0x3F, 0xC0, 0xD7, 0x00, 0xD7, 0xC0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x07, 0x09, 0x3C, 0x3C, 0x00, 0x0C, 0xD7, 0xD7, 0x00, 0x37, 0xD7, @@ -885,6 +885,444 @@ const uint8 Graphics::_locFontData[] = { 0xC0, 0x00, 0x00, }; +const uint16 Graphics::_spaFontOffs[] = { + 0x0000, 0x0007, 0x0024, 0x0043, 0x0072, 0x00AD, 0x00E0, 0x0113, 0x0124, 0x0141, + 0x015E, 0x0191, 0x01C4, 0x01E3, 0x01F8, 0x0215, 0x0232, 0x0269, 0x0286, 0x02BD, + 0x02F4, 0x032B, 0x0362, 0x0399, 0x03D0, 0x0407, 0x043E, 0x045B, 0x047C, 0x0495, + 0x04C0, 0x04D9, 0x0510, 0x054B, 0x0582, 0x05B9, 0x05F0, 0x0627, 0x065E, 0x0695, + 0x06CC, 0x0703, 0x0720, 0x0757, 0x078E, 0x07C5, 0x07FC, 0x0833, 0x086A, 0x08A1, + 0x08D8, 0x090F, 0x0946, 0x097D, 0x09B4, 0x09EB, 0x0A3C, 0x0A73, 0x0AAA, 0x0AE1, + 0x0B00, 0x0B1D, 0x0B3C, 0x0B77, 0x0BAE, 0x0BBF, 0x0BF6, 0x0C2D, 0x0C64, 0x0C9B, + 0x0CD2, 0x0CEF, 0x0D32, 0x0D69, 0x0D86, 0x0DA9, 0x0DE0, 0x0DFD, 0x0E34, 0x0E6B, + 0x0EA2, 0x0EE5, 0x0F28, 0x0F45, 0x0F7C, 0x0F99, 0x0FD0, 0x1007, 0x103E, 0x1075, + 0x10B8, 0x10EF, 0x110E, 0x112F, 0x114E, 0x1171, 0x117C, 0x11BF, 0x11F6, 0x122D, + 0x1264, 0x129B, 0x12D2, 0x1309, 0x134C, 0x1383, 0x13BA, 0x13F1, 0x1428, 0x1445, + 0x1462, 0x1499, 0x14A4, 0x14DB, 0x1512, 0x1549, 0x1580, 0x15B7, 0x15EE, 0x1625, + 0x165C, 0x1667, 0x169E, 0x16D5, 0x16E0, 0x16EB, 0x1722, 0x172D, 0x1738, 0x176F, + 0x178C, 0x17C3, 0x17FA, 0x1831, 0x1868, 0x1873, 0x187E, 0x18B5, 0x18C0, 0x18CB, + 0x18D6, 0x18E1, 0x18FE, 0x1929, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x1954 +}; + +const int Graphics::_spaFontSize = ARRAYSIZE(Graphics::_spaFontOffs); + +const uint8 Graphics::_spaFontData[] = { + 0x01, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0D, 0x05, 0x3C, 0x03, 0xD7, 0x0D, 0xD7, 0xCD, + 0xD7, 0xCD, 0xD7, 0xCD, 0xD7, 0xC3, 0xD7, 0xC0, 0xD7, 0xC0, 0x3F, 0xC0, 0xD7, 0x00, 0xD7, 0xC0, + 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x07, 0x09, 0x3C, 0x3C, 0x00, 0x0C, 0xD7, 0xD7, 0x00, 0x37, 0xD7, + 0xD7, 0xC0, 0xF7, 0xD7, 0xD7, 0xC3, 0x55, 0xD7, 0xD7, 0xC0, 0xDF, 0x3F, 0xFF, 0xC3, 0xDF, 0x0F, + 0x0F, 0x0D, 0x55, 0x02, 0x0B, 0x0B, 0x00, 0xC3, 0x00, 0x03, 0x03, 0x7D, 0xC0, 0x0D, 0x0F, 0x7D, + 0xF0, 0x0D, 0x35, 0x55, 0x70, 0x35, 0x0D, 0xF7, 0xFC, 0xDD, 0x3D, 0xF7, 0xF0, 0xDD, 0xD5, 0x55, + 0xC0, 0x35, 0x37, 0xDF, 0xF0, 0x3D, 0x37, 0xDF, 0xC0, 0xDD, 0x0F, 0xFF, 0x00, 0x35, 0x03, 0x0C, + 0x00, 0x0D, 0x02, 0x0E, 0x09, 0x03, 0x00, 0x00, 0xF0, 0x0D, 0xC0, 0x03, 0x5C, 0x0D, 0xF0, 0x0D, + 0xF7, 0x35, 0x5C, 0x0D, 0xF7, 0xDD, 0xF7, 0x03, 0x5F, 0xDD, 0xFF, 0xC0, 0xFD, 0x35, 0x5F, 0x00, + 0x37, 0x3D, 0xF7, 0x00, 0xDF, 0xDD, 0xF7, 0xC3, 0x7F, 0x35, 0x5F, 0xC0, 0xFC, 0x0D, 0xFF, 0x00, + 0x30, 0x0D, 0xFC, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x02, 0x0C, 0x0C, + 0x0F, 0x00, 0x00, 0x00, 0x35, 0xC0, 0xC0, 0x00, 0xDF, 0x73, 0x70, 0x03, 0xDF, 0x7D, 0xFC, 0x0D, + 0x35, 0xF7, 0xF0, 0x37, 0x0F, 0xDF, 0xC0, 0x37, 0x03, 0x7D, 0x70, 0x0D, 0x0D, 0xF7, 0xDC, 0x37, + 0x37, 0xF7, 0xDF, 0x37, 0x0F, 0xCD, 0x7F, 0x0D, 0x03, 0x03, 0xFC, 0x03, 0x00, 0x00, 0xF0, 0x00, + 0x02, 0x0C, 0x0B, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xD7, 0x0F, 0xC0, 0x00, 0xD7, 0x35, + 0x70, 0x00, 0xD7, 0xDF, 0xDC, 0x00, 0xD7, 0xDF, 0xFF, 0xC0, 0xFF, 0x35, 0x7D, 0x70, 0x3F, 0xDF, + 0xF7, 0xFC, 0x00, 0xDF, 0xDF, 0xF0, 0x00, 0x35, 0x7F, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x00, 0x03, + 0xF0, 0x00, 0x00, 0x01, 0x07, 0x05, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC3, 0xD7, 0xC3, 0xD7, 0xCD, + 0xFF, 0xCD, 0x3F, 0x0D, 0x01, 0x0D, 0x06, 0x03, 0x00, 0x0D, 0xC3, 0x37, 0xF0, 0x37, 0xC0, 0xDF, + 0xC0, 0xDF, 0x00, 0xDF, 0x00, 0xDF, 0x00, 0x37, 0x00, 0x37, 0xC0, 0x0D, 0xC3, 0x03, 0xF0, 0x00, + 0xC0, 0x01, 0x0D, 0x06, 0x30, 0x00, 0xDC, 0x00, 0x37, 0x00, 0x37, 0xC0, 0x0D, 0xC0, 0x0D, 0xF0, + 0x0D, 0xF3, 0x0D, 0xF0, 0x37, 0xF0, 0x37, 0xC0, 0xDF, 0xC0, 0x3F, 0x00, 0x0C, 0x00, 0x02, 0x0C, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x03, 0x0F, 0x7C, 0x00, + 0x0D, 0x37, 0x77, 0x00, 0x0D, 0x3D, 0x5F, 0xC0, 0xFD, 0xD5, 0xD5, 0xC3, 0x55, 0x3D, 0x5F, 0xF0, + 0xFD, 0x37, 0x77, 0xC0, 0x3D, 0x0F, 0x7F, 0xC0, 0x0D, 0x03, 0xFF, 0x00, 0x03, 0x00, 0x30, 0x00, + 0x00, 0x02, 0x0C, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, + 0x03, 0x70, 0x00, 0x00, 0x03, 0x7C, 0x00, 0x00, 0x3F, 0x7F, 0x00, 0x00, 0xD5, 0x55, 0xC0, 0x00, + 0x3F, 0x7F, 0xF0, 0x00, 0x0F, 0x7F, 0xC0, 0x3C, 0x03, 0x7C, 0x00, 0xD7, 0x00, 0xFC, 0x00, 0xD7, + 0x00, 0x30, 0x03, 0x5F, 0x01, 0x0E, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0F, 0x00, 0x35, 0xC0, 0x35, 0xF0, 0xD7, 0xF0, 0x3F, + 0xC0, 0x0F, 0x00, 0x01, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3F, 0xC0, 0xD5, 0x70, 0x3F, 0xFC, 0x0F, 0xF0, 0x01, 0x0D, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x3C, 0x03, 0xD7, 0x0D, 0xD7, + 0xCD, 0x3F, 0xC3, 0x0F, 0x00, 0x01, 0x0D, 0x08, 0x00, 0x00, 0x00, 0x30, 0x00, 0xDC, 0x03, 0x7F, + 0x03, 0x7C, 0x0D, 0xFC, 0x0D, 0xF0, 0x37, 0xF0, 0x37, 0xC0, 0xDF, 0xC0, 0xDF, 0x00, 0x3F, 0x00, + 0x0C, 0x00, 0x02, 0x0D, 0x09, 0x0F, 0xF0, 0x00, 0x0F, 0x35, 0x5C, 0x00, 0xF5, 0xD7, 0xD7, 0x03, + 0x55, 0xD7, 0xD7, 0xC0, 0xF5, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, + 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0x35, 0x5F, 0xC0, + 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x01, 0x0D, 0x07, 0x03, 0xC0, 0x3D, 0x70, + 0xD5, 0x7C, 0x3D, 0x7C, 0x0D, 0x7C, 0x0D, 0x7C, 0x0D, 0x7C, 0x0D, 0x7C, 0x0D, 0x7C, 0x0D, 0x7C, + 0x0D, 0x7C, 0x03, 0xFC, 0x00, 0xF0, 0x02, 0x0D, 0x09, 0x0F, 0xF0, 0x00, 0x0F, 0x35, 0x5C, 0x00, + 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, 0x3F, 0x3F, 0xD7, 0xC0, 0x0F, 0x0F, 0x5F, 0xC0, + 0x0D, 0x0D, 0x7F, 0x00, 0x03, 0x35, 0xFC, 0x00, 0x00, 0xD7, 0xF0, 0x00, 0x3C, 0xD7, 0xFC, 0x00, + 0xD7, 0xD5, 0x57, 0x00, 0x35, 0x3F, 0xFF, 0xC0, 0x0F, 0x0F, 0xFF, 0x00, 0x03, 0x02, 0x0D, 0x09, + 0x0F, 0xF0, 0x00, 0x00, 0x35, 0x5C, 0x00, 0x00, 0xD7, 0xD7, 0x00, 0x03, 0x3F, 0xD7, 0xC0, 0x0D, + 0x0F, 0xD7, 0xC0, 0x0D, 0x0D, 0x5F, 0xC0, 0x35, 0x03, 0xD7, 0x00, 0x35, 0x00, 0xD7, 0xC0, 0xD7, + 0x3C, 0xD7, 0xC0, 0xD5, 0xD7, 0xD7, 0xC0, 0x3F, 0x35, 0x5F, 0xC0, 0x0F, 0x0F, 0xFF, 0x00, 0x00, + 0x03, 0xFC, 0x00, 0x00, 0x02, 0x0D, 0x09, 0x00, 0x3C, 0x00, 0x3F, 0x00, 0xD7, 0x00, 0xD5, 0x03, + 0x57, 0xC0, 0xD7, 0x0D, 0x57, 0xC0, 0xD7, 0x0D, 0x57, 0xC0, 0xD7, 0x35, 0xD7, 0xC0, 0xD5, 0x35, + 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0x3F, 0xD5, 0x57, 0xC0, 0x3F, 0x3F, 0xD7, 0xC0, 0xD7, 0x0F, + 0xD7, 0xC0, 0x35, 0x00, 0x3F, 0xC0, 0x0F, 0x00, 0x0F, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x3F, 0xFC, + 0x00, 0x0F, 0xD5, 0x57, 0x00, 0x35, 0xD7, 0xFF, 0xC0, 0xD7, 0xD7, 0xFF, 0x00, 0xD7, 0xD7, 0xF0, + 0x00, 0xD7, 0xD5, 0x5C, 0x00, 0xD5, 0xD7, 0xD7, 0x00, 0xD7, 0x3F, 0xD7, 0xC0, 0xD7, 0x3F, 0xD7, + 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, 0xFC, + 0x00, 0x03, 0x02, 0x0D, 0x09, 0x0F, 0xF0, 0x00, 0x3F, 0x35, 0x5C, 0x00, 0xD5, 0xD7, 0xD7, 0x00, + 0x3F, 0xD7, 0xFF, 0xC0, 0x0F, 0xD7, 0xFF, 0x00, 0x03, 0xD5, 0x5C, 0x00, 0x0D, 0xD7, 0xD7, 0x00, + 0x0D, 0xD7, 0xD7, 0xC0, 0x0D, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0x35, 0x5F, 0xC0, + 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x3F, 0xFC, 0x00, 0x0F, + 0xD5, 0x57, 0x00, 0x35, 0x3F, 0xD7, 0xC0, 0xD7, 0x0F, 0x5F, 0xC0, 0xD7, 0x03, 0x5F, 0x00, 0xD7, + 0x0D, 0x7F, 0x00, 0x35, 0x0D, 0x7C, 0x00, 0xD7, 0x0D, 0x7C, 0x00, 0xD7, 0x35, 0xFC, 0x00, 0xD7, + 0x35, 0xF0, 0x00, 0xD7, 0x35, 0xF0, 0x00, 0x35, 0x0F, 0xF0, 0x00, 0x0F, 0x03, 0xC0, 0x00, 0x03, + 0x02, 0x0D, 0x09, 0x0F, 0xF0, 0x00, 0x0F, 0x35, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, + 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0xD7, 0xD7, 0xD7, 0x00, 0x35, 0xD7, + 0xD7, 0xC0, 0x0F, 0xD7, 0xD7, 0xC0, 0x3F, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0x35, 0x0F, + 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x0F, 0xF0, 0x00, 0x00, 0x35, 0x5C, + 0x00, 0x00, 0xD7, 0xD7, 0x00, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xC0, 0xF0, 0xD7, 0xD7, + 0xC3, 0x5C, 0x35, 0x57, 0xC3, 0x5F, 0x0F, 0xD7, 0xC0, 0xFF, 0x3F, 0xD7, 0xC0, 0xFC, 0xD7, 0xD7, + 0xC3, 0x5C, 0x35, 0x5F, 0xC3, 0x5F, 0x0F, 0xFF, 0x00, 0xFF, 0x03, 0xFC, 0x00, 0x3C, 0x01, 0x0D, + 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xD7, 0x03, 0xD7, 0xC3, 0x3F, + 0xC0, 0x3F, 0x00, 0xD7, 0x03, 0xD7, 0xC3, 0x3F, 0xC0, 0x0F, 0x03, 0x01, 0x0F, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC0, 0x3F, 0xC0, 0x3F, 0x00, + 0xD7, 0x00, 0xD7, 0xC0, 0x37, 0xC0, 0xDF, 0xC0, 0x3F, 0x00, 0x0C, 0x00, 0x01, 0x0B, 0x07, 0x00, + 0x00, 0x00, 0xC0, 0x03, 0x70, 0x0D, 0xFC, 0x37, 0xF0, 0xDF, 0xC0, 0x37, 0x00, 0x0D, 0xC0, 0x03, + 0x70, 0x00, 0xFC, 0x00, 0x30, 0x02, 0x0A, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, + 0x00, 0x00, 0x03, 0x70, 0x3F, 0xFC, 0x00, 0xDC, 0xD5, 0x57, 0x00, 0x37, 0x3F, 0xFF, 0xC0, 0x0D, + 0x3F, 0xFF, 0x00, 0x37, 0xD5, 0x57, 0x00, 0xDF, 0x3F, 0xFF, 0xC3, 0x7F, 0x0F, 0xFF, 0x00, 0xFC, + 0x01, 0x0B, 0x07, 0x00, 0x00, 0x30, 0x00, 0xDC, 0x00, 0x37, 0x00, 0x0D, 0xC0, 0x03, 0x70, 0x0D, + 0xFC, 0x37, 0xF0, 0xDF, 0xC0, 0x3F, 0x00, 0x0C, 0x00, 0x02, 0x0D, 0x09, 0x0F, 0xF0, 0x00, 0x00, + 0x35, 0x5C, 0x00, 0x00, 0xD7, 0xD7, 0x00, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0x3F, 0xD7, 0xC0, 0x00, + 0x0F, 0x5F, 0xC0, 0x00, 0x0D, 0x7F, 0x00, 0x00, 0x0D, 0x7C, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, + 0x0D, 0x70, 0x00, 0x00, 0x0D, 0x7C, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, + 0x02, 0x0E, 0x0D, 0x03, 0xFF, 0xC0, 0x00, 0x0D, 0x55, 0x70, 0x00, 0x37, 0xFF, 0xDC, 0x00, 0xDF, + 0xFF, 0xF7, 0x00, 0xDF, 0xD5, 0xF7, 0xC0, 0xDF, 0x7D, 0xF7, 0xC0, 0xDF, 0x7D, 0xF7, 0xC0, 0xDF, + 0x7D, 0xF7, 0xC0, 0xDF, 0x75, 0xDF, 0xC0, 0xDF, 0xDD, 0x7F, 0x00, 0x37, 0xFF, 0xFC, 0x00, 0x0D, + 0x5C, 0xF0, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x00, 0x02, 0x0D, 0x0B, 0x00, 0xF0, + 0x00, 0x3F, 0x03, 0x5C, 0x00, 0xD5, 0x03, 0x5F, 0x00, 0xD7, 0x0D, 0x57, 0x00, 0xD7, 0x0D, 0x57, + 0xC0, 0xD7, 0x0D, 0xF7, 0xC0, 0xD5, 0x35, 0xF5, 0xC0, 0xD7, 0x35, 0xF5, 0xF0, 0xD7, 0x35, 0x55, + 0xF0, 0xD7, 0xD7, 0xFD, 0x70, 0xD7, 0xD7, 0xFD, 0x7C, 0xD5, 0x3F, 0xC3, 0xFC, 0x3F, 0x0F, 0x00, + 0xF0, 0x0F, 0x02, 0x0D, 0x0B, 0x3F, 0xFF, 0x00, 0x03, 0xD5, 0x55, 0xC0, 0x0D, 0xD7, 0xFD, 0x70, + 0x35, 0xD7, 0xFD, 0x7C, 0xD7, 0xD7, 0xFD, 0x7C, 0xD7, 0xD5, 0x55, 0xFC, 0xD7, 0xD7, 0xFD, 0x70, + 0xD7, 0xD7, 0xFD, 0x7C, 0xD7, 0xD7, 0xCD, 0x7C, 0xD7, 0xD7, 0xFD, 0x7C, 0x35, 0xD5, 0x55, 0xFC, + 0x0D, 0x3F, 0xFF, 0xF0, 0x03, 0x0F, 0xFF, 0xC0, 0x00, 0x02, 0x0D, 0x0A, 0x03, 0xFC, 0x00, 0x0F, + 0x0D, 0x57, 0x00, 0x35, 0x35, 0xF5, 0xC0, 0x35, 0xD7, 0xFD, 0xF0, 0x35, 0xD7, 0xC3, 0xF0, 0x35, + 0xD7, 0xC0, 0xC0, 0x35, 0xD7, 0xC0, 0x00, 0x35, 0xD7, 0xC3, 0x00, 0x35, 0xD7, 0xCD, 0xC0, 0x35, + 0x35, 0xF5, 0xF0, 0x35, 0x0D, 0x57, 0xF0, 0x35, 0x03, 0xFF, 0xC0, 0x0F, 0x00, 0xFF, 0x00, 0x03, + 0x02, 0x0D, 0x0B, 0x3F, 0xFC, 0x00, 0x03, 0xD5, 0x57, 0x00, 0x0D, 0xD7, 0xF5, 0xC0, 0x0D, 0xD7, + 0xFD, 0x70, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, + 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xF5, 0xFC, 0x0D, 0xD5, 0x57, 0xF0, 0x0D, 0x3F, + 0xFF, 0xC0, 0x03, 0x0F, 0xFF, 0x00, 0x00, 0x02, 0x0D, 0x0A, 0x3F, 0xFF, 0x00, 0x0F, 0xD5, 0x55, + 0xC0, 0x35, 0xD7, 0xFF, 0xF0, 0x35, 0xD7, 0xFF, 0xC0, 0x35, 0xD7, 0xFC, 0x00, 0x35, 0xD5, 0x57, + 0x00, 0x35, 0xD7, 0xFF, 0xC0, 0x35, 0xD7, 0xFF, 0x00, 0x35, 0xD7, 0xC0, 0x00, 0x35, 0xD7, 0xFF, + 0x00, 0x35, 0xD5, 0x55, 0xC0, 0x35, 0x3F, 0xFF, 0xF0, 0x0F, 0x0F, 0xFF, 0xC0, 0x03, 0x02, 0x0D, + 0x0A, 0x3F, 0xFF, 0x00, 0x03, 0xD5, 0x55, 0xC0, 0x0D, 0xD7, 0xFF, 0xF0, 0x35, 0xD7, 0xFF, 0xC0, + 0xD7, 0xD7, 0xFC, 0x00, 0xD7, 0xD5, 0x57, 0x00, 0xD7, 0xD7, 0xFF, 0xC0, 0xD7, 0xD7, 0xFF, 0x00, + 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0x35, 0xD7, 0xC0, 0x00, 0x0D, 0x3F, 0xC0, 0x00, + 0x03, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x0D, 0x0B, 0x03, 0xFF, 0x00, 0x03, 0x0D, 0x55, 0xC0, 0x0D, + 0x35, 0xFD, 0x70, 0x0D, 0xD7, 0xFF, 0x7C, 0x0D, 0xD7, 0xC0, 0xFC, 0x0D, 0xD7, 0xFF, 0xF0, 0x0D, + 0xD7, 0xD5, 0x70, 0x0D, 0xD7, 0xFD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0x35, 0xFD, 0x7C, 0x0D, + 0x0D, 0x57, 0x7C, 0x0D, 0x03, 0xFF, 0xFC, 0x03, 0x00, 0xFF, 0x30, 0x00, 0x02, 0x0D, 0x0B, 0x3C, + 0x03, 0xC0, 0x03, 0xD7, 0x0D, 0x70, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, + 0xFD, 0x7C, 0x0D, 0xD5, 0x55, 0x7C, 0x0D, 0xD7, 0xFD, 0x7C, 0x0D, 0xD7, 0xFD, 0x7C, 0x0D, 0xD7, + 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0x3F, 0xC3, 0xFC, 0x03, 0x0F, + 0x00, 0xF0, 0x00, 0x01, 0x0D, 0x05, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, + 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC3, 0xD7, 0xC3, 0xD7, 0xC0, 0x3F, 0xC0, 0x0F, 0x00, + 0x02, 0x0D, 0x09, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0x00, 0xD7, 0xC0, 0xD7, 0x00, + 0xD7, 0xC0, 0xD7, 0x00, 0xD7, 0xC0, 0xD5, 0x00, 0xD7, 0xC0, 0xD5, 0x00, 0xD7, 0xC0, 0xD5, 0x3C, + 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0xD7, 0x0F, + 0xFF, 0x00, 0x3F, 0x03, 0xFC, 0x00, 0x0F, 0x02, 0x0D, 0x0B, 0x3C, 0x0F, 0x00, 0x0F, 0xD7, 0x35, + 0xC0, 0x35, 0xD7, 0xD7, 0xF0, 0x35, 0xD7, 0x5F, 0xC0, 0x35, 0xD5, 0x7F, 0x00, 0x35, 0xD5, 0xFC, + 0x00, 0x35, 0xD5, 0x70, 0x00, 0x35, 0xD7, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0x35, 0xD7, 0xF5, + 0xC0, 0x35, 0xD7, 0xCD, 0x70, 0x35, 0x3F, 0xC3, 0xFC, 0x0F, 0x0F, 0x00, 0xF0, 0x03, 0x02, 0x0D, + 0x0A, 0x3C, 0x00, 0x00, 0x3C, 0xD7, 0x00, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xC0, 0x00, + 0xD5, 0xD7, 0xC0, 0x00, 0xD5, 0xD7, 0xC0, 0x00, 0xD5, 0xD7, 0xC0, 0x00, 0xD5, 0xD7, 0xC0, 0x00, + 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xFF, 0x00, 0xD7, 0xD5, 0x55, 0xC0, 0xD7, 0x3F, 0xFF, 0xF0, + 0x3F, 0x0F, 0xFF, 0xC0, 0x0F, 0x02, 0x0D, 0x0D, 0x3C, 0x00, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0x00, + 0xD7, 0xC0, 0xD7, 0xC0, 0xD5, 0xC3, 0x57, 0xC0, 0xD5, 0xF3, 0x57, 0xC0, 0xD5, 0x7D, 0x57, 0xC0, + 0xD5, 0x7D, 0x57, 0xC0, 0xD7, 0x55, 0xD7, 0xC0, 0xD7, 0x55, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0xD7, 0xD7, 0xC0, 0x3F, 0xFF, 0xFF, 0xC0, 0x0F, 0x0F, 0x0F, 0x00, 0x02, 0x0D, 0x0B, 0x3C, + 0x03, 0xC0, 0x00, 0xD7, 0x0D, 0x70, 0x00, 0xD5, 0xCD, 0x7C, 0x03, 0xD5, 0x7D, 0x7C, 0x0D, 0xD5, + 0x7D, 0x7C, 0x0D, 0xD7, 0x5D, 0x7C, 0x0D, 0xD7, 0x5D, 0x7C, 0x0D, 0xD7, 0xD5, 0x7C, 0x0D, 0xD7, + 0xD5, 0x7C, 0x0D, 0xD7, 0xF5, 0x7C, 0x03, 0xD7, 0xCD, 0x7C, 0x00, 0x3F, 0xC3, 0xFC, 0x00, 0x0F, + 0x00, 0xF0, 0x00, 0x02, 0x0D, 0x0B, 0x03, 0xFC, 0x00, 0x03, 0x0D, 0x57, 0x00, 0x0D, 0x35, 0xF5, + 0xC0, 0x0D, 0xD7, 0xFD, 0x70, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, + 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0x35, 0xF5, 0xFC, 0x0D, 0x0D, 0x57, + 0xF0, 0x0D, 0x03, 0xFF, 0xC0, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x02, 0x0D, 0x0B, 0x3F, 0xFF, 0x00, + 0x00, 0xD5, 0x55, 0xC0, 0x03, 0xD7, 0xFD, 0x70, 0x0D, 0xD7, 0xFD, 0x7C, 0x35, 0xD7, 0xCD, 0x7C, + 0x35, 0xD7, 0xFD, 0x7C, 0x35, 0xD5, 0x55, 0xFC, 0x35, 0xD7, 0xFF, 0xF0, 0x35, 0xD7, 0xFF, 0xC0, + 0x35, 0xD7, 0xC0, 0x00, 0x0D, 0xD7, 0xC0, 0x00, 0x03, 0x3F, 0xC0, 0x00, 0x00, 0x0F, 0x00, 0x00, + 0x00, 0x02, 0x0D, 0x0B, 0x03, 0xFC, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x00, 0x35, 0xF5, 0xC0, 0x00, + 0xD7, 0xFD, 0x70, 0x00, 0xD7, 0xCD, 0x7C, 0x00, 0xD7, 0xCD, 0x7C, 0x00, 0xD7, 0xCD, 0x7C, 0x00, + 0xD7, 0xFD, 0x7C, 0x00, 0xD7, 0xD5, 0x7C, 0x00, 0x35, 0xF5, 0xFC, 0x00, 0x0D, 0x55, 0x70, 0x00, + 0x03, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x02, 0x0D, 0x0C, 0x3F, 0xFF, 0x00, 0x00, 0xD5, + 0x55, 0xC0, 0x03, 0xD7, 0xFD, 0x70, 0x0D, 0xD7, 0xFD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, + 0xFD, 0x7C, 0x03, 0xD5, 0x55, 0xFC, 0x00, 0xD7, 0xFD, 0x70, 0x03, 0xD7, 0xFD, 0x7C, 0x0D, 0xD7, + 0xCD, 0x7C, 0x0D, 0xD7, 0xC3, 0x5C, 0x03, 0x3F, 0xC0, 0xFF, 0x00, 0x0F, 0x00, 0x3C, 0x00, 0x02, + 0x0D, 0x0A, 0x0F, 0xFC, 0x00, 0x3F, 0x35, 0x57, 0x00, 0xD5, 0xD7, 0xF5, 0xC0, 0x3F, 0xD7, 0xF5, + 0xF0, 0x0F, 0xD7, 0xCF, 0xF0, 0x03, 0x35, 0x7F, 0xC0, 0x03, 0x0F, 0x57, 0x00, 0x03, 0x3F, 0xF5, + 0xC0, 0x03, 0xD7, 0x35, 0xF0, 0x03, 0xD7, 0xF5, 0xF0, 0x03, 0x35, 0x57, 0xF0, 0x03, 0x0F, 0xFF, + 0xC0, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x02, 0x0D, 0x0B, 0x3F, 0xFF, 0xC0, 0x0F, 0xD5, 0x55, 0x70, + 0x35, 0x3F, 0x5F, 0xFC, 0x35, 0x0F, 0x5F, 0xF0, 0x35, 0x03, 0x5F, 0x00, 0x35, 0x03, 0x5F, 0x00, + 0x35, 0x03, 0x5F, 0x00, 0x35, 0x03, 0x5F, 0x00, 0x35, 0x03, 0x5F, 0x00, 0x35, 0x03, 0x5F, 0x00, + 0x0D, 0x03, 0x5F, 0x00, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x02, 0x0D, 0x0B, + 0x3C, 0x03, 0xC0, 0x0F, 0xD7, 0x0D, 0x70, 0x35, 0xD7, 0xCD, 0x7C, 0x35, 0xD7, 0xCD, 0x7C, 0x0D, + 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x0D, 0xD7, 0xCD, 0x7C, 0x03, 0xD7, 0xCD, 0x7C, 0x03, + 0xD7, 0xCD, 0x7C, 0x03, 0x35, 0xF5, 0xFC, 0x00, 0x0D, 0x57, 0xF0, 0x00, 0x03, 0xFF, 0xC0, 0x00, + 0x00, 0xFF, 0x00, 0x00, 0x02, 0x0D, 0x0B, 0x3C, 0x03, 0xC0, 0x3C, 0xD7, 0x0D, 0x70, 0xD7, 0xD7, + 0xCD, 0x7C, 0xD7, 0x35, 0xF5, 0xFC, 0xD7, 0x35, 0xF5, 0xF0, 0x35, 0x35, 0xF5, 0xF0, 0x35, 0x0D, + 0xF7, 0xF0, 0x0D, 0x0D, 0x57, 0xC0, 0x0D, 0x0D, 0x57, 0xC0, 0x03, 0x03, 0x5F, 0xC0, 0x03, 0x03, + 0x5F, 0x00, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x03, 0x0D, 0x11, 0x3C, 0x03, + 0xC0, 0x3C, 0x03, 0xC0, 0xD7, 0x0D, 0x70, 0xD7, 0x0D, 0x70, 0xD7, 0xCD, 0x7C, 0xD7, 0xCD, 0x7C, + 0xD7, 0xCD, 0x7C, 0xD7, 0xC3, 0x5C, 0x35, 0xF5, 0x5F, 0x5F, 0xC0, 0xD7, 0x35, 0xF5, 0x5F, 0x5F, + 0x00, 0x35, 0x0D, 0x77, 0xDD, 0x7F, 0x00, 0x35, 0x0D, 0x57, 0xD5, 0x7C, 0x00, 0xD7, 0x03, 0x5F, + 0xF5, 0xFC, 0x03, 0x5F, 0x03, 0x5F, 0x35, 0xF0, 0x0D, 0x7F, 0x03, 0x5F, 0x35, 0xF0, 0x0D, 0x7C, + 0x00, 0xFF, 0x0F, 0xF0, 0x03, 0xFC, 0x00, 0x3C, 0x03, 0xC0, 0x00, 0xF0, 0x02, 0x0D, 0x0C, 0x3C, + 0x00, 0xF0, 0x0F, 0xD7, 0x03, 0x5C, 0x35, 0xD7, 0xC3, 0x5F, 0x35, 0x35, 0xCD, 0x7F, 0x0D, 0x0D, + 0x75, 0xFC, 0x03, 0x03, 0x57, 0xF0, 0x00, 0x03, 0x57, 0xC0, 0x00, 0x0D, 0x75, 0xC0, 0x00, 0x35, + 0xFD, 0x70, 0x00, 0xD7, 0xF3, 0x5C, 0x00, 0xD7, 0xC3, 0x5F, 0x00, 0x3F, 0xC0, 0xFF, 0x00, 0x0F, + 0x00, 0x3C, 0x00, 0x02, 0x0D, 0x0D, 0x3C, 0x00, 0x3C, 0x03, 0xD7, 0x00, 0xD7, 0x0D, 0xD7, 0xC0, + 0xD7, 0xC3, 0x35, 0xC3, 0x5F, 0xC0, 0x0D, 0x7D, 0x7F, 0x00, 0x03, 0x55, 0xFC, 0x00, 0x00, 0xD7, + 0xF0, 0x00, 0x00, 0xD7, 0xC0, 0x00, 0x00, 0xD7, 0xC0, 0x03, 0x00, 0xD7, 0xC0, 0x0D, 0x00, 0xD7, + 0xC0, 0x0D, 0x00, 0x3F, 0xC0, 0x03, 0x00, 0x0F, 0x00, 0x00, 0x02, 0x0D, 0x0C, 0x3F, 0xFF, 0xF0, + 0x00, 0xD5, 0x55, 0x5C, 0x00, 0x3F, 0xFF, 0x5F, 0x00, 0x0F, 0xFD, 0x7F, 0x00, 0x00, 0x35, 0xFC, + 0x00, 0x00, 0xD7, 0xF0, 0x00, 0x03, 0x5F, 0xC0, 0x00, 0x0D, 0x7F, 0x00, 0x00, 0x35, 0xFC, 0x00, + 0x00, 0xD7, 0xFF, 0xF0, 0x00, 0xD5, 0x55, 0x5C, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFC, + 0x00, 0x01, 0x0E, 0x06, 0x3F, 0x00, 0xD5, 0xC3, 0xDF, 0xF3, 0xDF, 0xC0, 0xDF, 0x00, 0xDF, 0x00, + 0xDF, 0x00, 0xDF, 0x00, 0xDF, 0x00, 0xDF, 0x00, 0xDF, 0x00, 0xD5, 0xC0, 0x3F, 0xF0, 0x0F, 0xC0, + 0x01, 0x0D, 0x08, 0x30, 0x00, 0xDC, 0x00, 0xDF, 0x00, 0x37, 0x00, 0x37, 0xC0, 0x0D, 0xC0, 0x0D, + 0xF0, 0x03, 0x70, 0x03, 0x7C, 0x00, 0xDC, 0x00, 0xDF, 0x00, 0x3F, 0x00, 0x0C, 0x01, 0x0E, 0x06, + 0x3F, 0x00, 0xD5, 0xC0, 0x3D, 0xF0, 0x0D, 0xF0, 0x0D, 0xF0, 0x0D, 0xF0, 0x0D, 0xF0, 0x0D, 0xF0, + 0x0D, 0xF0, 0x0D, 0xF0, 0x3D, 0xF0, 0xD5, 0xF0, 0x3F, 0xF0, 0x0F, 0xC0, 0x02, 0x0E, 0x0A, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x0D, + 0x5C, 0x00, 0x00, 0x37, 0x77, 0x00, 0x00, 0xDF, 0x7D, 0xC0, 0x00, 0x3F, 0x7F, 0xF0, 0x00, 0x0F, + 0x7C, 0xC0, 0x00, 0x03, 0x7C, 0x00, 0x03, 0x03, 0x7C, 0x00, 0x0D, 0x03, 0x7C, 0x00, 0x03, 0x00, + 0xFC, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x02, 0x0D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, + 0xF0, 0x00, 0xD5, 0x55, 0x5C, 0x00, 0x3F, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFC, 0x00, 0x01, 0x07, + 0x04, 0x0C, 0x00, 0x37, 0x00, 0xD7, 0x00, 0xD7, 0x00, 0xD7, 0x03, 0xDC, 0x0D, 0x30, 0x03, 0x02, + 0x0D, 0x09, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, 0xD7, 0x0F, 0xF0, + 0x00, 0xD7, 0x35, 0x5C, 0x00, 0xD5, 0xD7, 0xD7, 0x00, 0xD7, 0x3D, 0x57, 0xC0, 0xD7, 0x35, 0xD7, + 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x57, 0xC0, 0xD5, 0x0F, 0xFF, + 0xC0, 0x3F, 0x03, 0xFF, 0x00, 0x0F, 0x02, 0x0D, 0x09, 0x3C, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x00, + 0x00, 0xD7, 0xC0, 0x00, 0x00, 0xD7, 0xF0, 0x00, 0x0F, 0xD5, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, + 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0xD5, 0x5F, 0xC0, 0x35, 0x3F, 0xFF, 0x00, 0x0F, 0x0F, 0xFC, 0x00, 0x03, 0x02, 0x0D, 0x09, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0F, 0xF0, 0x00, 0x3F, + 0x35, 0x5C, 0x00, 0xD5, 0xD7, 0xD7, 0x03, 0x5F, 0xD7, 0xFF, 0xC3, 0x5F, 0xD7, 0xCF, 0x03, 0x5F, + 0xD7, 0xFC, 0x03, 0x5F, 0xD7, 0xD7, 0x03, 0x5F, 0x35, 0x5F, 0xC0, 0xD5, 0x0F, 0xFF, 0x00, 0x3F, + 0x03, 0xFC, 0x00, 0x0F, 0x02, 0x0D, 0x09, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, + 0xD7, 0xC0, 0x00, 0x0F, 0xD7, 0xC0, 0x0F, 0x35, 0x57, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, + 0xD7, 0xC0, 0xD5, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, + 0x57, 0xC0, 0x35, 0x0F, 0xFF, 0xC0, 0x0F, 0x03, 0xFF, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x00, 0x00, + 0x00, 0x0F, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0xD7, 0x0F, 0xF0, 0x00, 0xD7, 0x35, 0x5C, + 0x03, 0x55, 0xD7, 0xD7, 0x00, 0xD7, 0xD5, 0x57, 0xC0, 0xD7, 0xD7, 0xFF, 0xC0, 0xD7, 0xD7, 0xFF, + 0x00, 0xD7, 0xD7, 0xD7, 0x00, 0xD7, 0x35, 0x5F, 0xC0, 0xD7, 0x0F, 0xFF, 0x00, 0x3F, 0x03, 0xFC, + 0x00, 0x0F, 0x01, 0x0D, 0x07, 0x03, 0xC0, 0x0D, 0x70, 0x35, 0xFC, 0x35, 0xF0, 0xD5, 0x70, 0x35, + 0xFC, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x0F, 0xF0, 0x03, 0xC0, 0x02, + 0x10, 0x09, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0xD7, 0x00, 0x00, 0x00, 0xD7, 0x0F, 0xFC, + 0x00, 0xD7, 0x35, 0x57, 0x00, 0xD5, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, + 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x57, 0xC0, 0xD7, 0x3F, 0xD7, + 0xC0, 0x3F, 0xD7, 0xD7, 0xC0, 0x0F, 0x35, 0x5F, 0xC0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x03, 0xFC, + 0x00, 0x00, 0x02, 0x0D, 0x09, 0x3C, 0x00, 0x00, 0x3C, 0xD7, 0x00, 0x00, 0xD7, 0xD7, 0xC0, 0x00, + 0xD7, 0xD7, 0xF0, 0x00, 0x3F, 0xD5, 0x5C, 0x00, 0xD7, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0x3F, 0xFF, 0xC0, 0x3F, 0x0F, 0x0F, 0x00, 0x0F, 0x01, 0x0D, 0x05, 0x3C, 0x00, 0xD7, 0x00, + 0xD7, 0xC0, 0x3F, 0xC0, 0xD7, 0x00, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, + 0xD7, 0xC0, 0x3F, 0xC0, 0x0F, 0x00, 0x01, 0x10, 0x06, 0x0F, 0x00, 0x35, 0xC0, 0x35, 0xF0, 0x0F, + 0xF0, 0x35, 0xC0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, + 0xF0, 0x35, 0xF0, 0xD7, 0xF0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x0D, 0x09, 0x3C, 0x00, 0x00, 0xF0, + 0xD7, 0x00, 0x03, 0x5C, 0xD7, 0xC0, 0x03, 0x5F, 0xD7, 0xFC, 0x03, 0x5F, 0xD7, 0xD7, 0x03, 0x5F, + 0xD7, 0x5F, 0xC3, 0x5F, 0xD5, 0x7F, 0x03, 0x5F, 0xD5, 0xFC, 0x03, 0x5F, 0xD5, 0x70, 0x03, 0x5F, + 0xD7, 0x5C, 0x03, 0x5F, 0xD7, 0xD7, 0x03, 0x5F, 0x3F, 0xFF, 0xC0, 0xFF, 0x0F, 0x0F, 0x00, 0x3C, + 0x01, 0x0D, 0x05, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, + 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x0D, 0x0D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF0, 0x00, + 0xD5, 0x55, 0x5C, 0x00, 0xD7, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0x3F, 0xFF, 0xFF, 0xC0, + 0x0F, 0x0F, 0x0F, 0x00, 0x02, 0x0D, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x3F, 0xF0, 0x00, 0x0F, 0xD5, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, + 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, + 0xD7, 0xC0, 0x35, 0x3F, 0xFF, 0xC0, 0x0F, 0x0F, 0x0F, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x3F, 0x35, 0x5C, + 0x00, 0xD5, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, + 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0xD5, 0x0F, 0xFF, 0x00, 0xD7, 0x03, 0xFC, + 0x00, 0xD7, 0x02, 0x10, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xF0, 0x00, 0x0F, 0xD5, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD5, 0x5F, 0xC0, + 0x35, 0xD7, 0xFF, 0x00, 0x0F, 0xD7, 0xFC, 0x00, 0x03, 0xD7, 0xC0, 0x00, 0x00, 0x3F, 0xC0, 0x00, + 0x00, 0x0F, 0x00, 0x00, 0x00, 0x02, 0x10, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFC, 0x00, 0x3F, 0x35, 0x57, 0x00, 0xD5, 0xD7, 0xD7, 0xC0, 0xD5, + 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, + 0x35, 0x57, 0xC0, 0xD7, 0x0F, 0xD7, 0xC0, 0x3F, 0x03, 0xD7, 0xC0, 0x0F, 0x00, 0xD7, 0xC0, 0x00, + 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x01, 0x0D, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3F, 0xC0, 0xD5, 0x70, 0xD5, 0xFC, 0xD7, 0xF0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, + 0xC0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x0D, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x00, 0x00, 0x00, 0xD7, 0x0F, 0xF0, 0x00, 0xD7, 0x35, 0x5C, 0x03, 0x55, 0xD7, 0xD7, 0x00, 0xD7, + 0xD7, 0xFF, 0xC0, 0xD7, 0x35, 0x5F, 0x00, 0xD7, 0x3F, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, + 0x35, 0x5F, 0xC0, 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x01, 0x0D, 0x07, 0x00, + 0x00, 0x0F, 0x00, 0x35, 0xC0, 0x35, 0xF0, 0xD5, 0x70, 0x35, 0xFC, 0x35, 0xF0, 0x35, 0xF0, 0x35, + 0xF0, 0x35, 0xF0, 0x0D, 0x70, 0x03, 0xFC, 0x00, 0xF0, 0x02, 0x0D, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0xF0, 0xD7, 0xD7, 0x03, 0x5C, + 0xD7, 0xD7, 0xC3, 0x5F, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0x35, + 0xD7, 0xD7, 0xC0, 0x0D, 0x35, 0x57, 0xC0, 0x0D, 0x0F, 0xFF, 0xC0, 0x03, 0x03, 0xFF, 0x00, 0x00, + 0x02, 0x0D, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, + 0x03, 0xC0, 0x3C, 0xD7, 0x0D, 0x70, 0xD7, 0xD7, 0xCD, 0x7C, 0xD7, 0x35, 0xF5, 0xFC, 0x35, 0x35, + 0xF5, 0xF0, 0x35, 0x0D, 0x57, 0xF0, 0x35, 0x03, 0x5F, 0xC0, 0x0D, 0x03, 0x5F, 0x00, 0x0D, 0x00, + 0xFF, 0x00, 0x03, 0x00, 0x3C, 0x00, 0x00, 0x02, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x03, 0xD7, 0x3C, 0xD7, 0x0D, 0xD7, 0xD7, + 0xD7, 0xC3, 0x35, 0xD7, 0x5F, 0xC0, 0x35, 0xD7, 0x5F, 0x00, 0x35, 0x55, 0x5F, 0x00, 0x0D, 0x7D, + 0x7F, 0x03, 0x0D, 0x7D, 0x7C, 0x0D, 0x03, 0xFF, 0xFC, 0x03, 0x00, 0xF0, 0xF0, 0x00, 0x02, 0x0D, + 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x03, 0xC0, + 0x3C, 0xD7, 0x0D, 0x70, 0xD7, 0x35, 0xF5, 0xFC, 0xD7, 0x0D, 0x57, 0xF0, 0x35, 0x03, 0x5F, 0xC0, + 0x35, 0x0D, 0x57, 0x00, 0x0D, 0x35, 0xF5, 0xC0, 0x0D, 0xD7, 0xFD, 0x70, 0x03, 0x3F, 0xC3, 0xFC, + 0x03, 0x0F, 0x00, 0xF0, 0x0D, 0x02, 0x10, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3C, 0x03, 0xC0, 0x0F, 0xD7, 0x0D, 0x70, 0x35, 0xD7, 0xCD, 0x7C, 0x0F, + 0x35, 0xF5, 0xFC, 0x03, 0x35, 0xF5, 0xF0, 0x03, 0x0D, 0x57, 0xF0, 0x0D, 0x0D, 0x57, 0xC0, 0x35, + 0x03, 0x5F, 0xC0, 0x35, 0x03, 0x5F, 0x00, 0x0F, 0x0D, 0x7F, 0x00, 0x03, 0x35, 0xFC, 0x00, 0x00, + 0x0F, 0xF0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x02, 0x0D, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0xD5, 0x57, 0x00, 0x00, 0x3F, + 0xD7, 0xC0, 0x00, 0x0F, 0x5F, 0xC0, 0x00, 0x0D, 0x7F, 0x00, 0x00, 0x35, 0xFC, 0x00, 0x00, 0xD7, + 0xFC, 0x00, 0x00, 0xD5, 0x57, 0x00, 0x00, 0x3F, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x01, + 0x0E, 0x07, 0x00, 0x00, 0x03, 0xC0, 0x0D, 0x70, 0x37, 0xFC, 0x37, 0xF0, 0x37, 0xC0, 0xDF, 0xC0, + 0xDF, 0x00, 0x37, 0x00, 0x37, 0xC0, 0x37, 0xC0, 0x0D, 0x70, 0x03, 0xFC, 0x00, 0xF0, 0x01, 0x0F, + 0x04, 0x30, 0x00, 0xDC, 0x0F, 0xDF, 0x35, 0xDF, 0x0F, 0xDF, 0x03, 0xDF, 0x03, 0xDF, 0x00, 0xDF, + 0x00, 0xDF, 0x03, 0xDF, 0x03, 0xDF, 0x0F, 0xDF, 0x35, 0xDF, 0x0F, 0x3F, 0x03, 0x0C, 0x00, 0x01, + 0x0E, 0x07, 0x00, 0x00, 0x3C, 0x00, 0xD7, 0x00, 0x3D, 0xC0, 0x0D, 0xF0, 0x0D, 0xF0, 0x03, 0x70, + 0x03, 0x7C, 0x0D, 0xFC, 0x0D, 0xF0, 0x3D, 0xF0, 0xD7, 0xF0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x08, + 0x0A, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x70, 0x0F, 0x00, 0x03, 0x70, 0x35, 0xC3, 0x00, + 0xC0, 0xDF, 0x7D, 0xC0, 0x00, 0x3F, 0xD7, 0xF0, 0x00, 0x0C, 0x3F, 0xC0, 0x00, 0x00, 0x0F, 0x00, + 0x00, 0x01, 0x04, 0x03, 0x30, 0x00, 0xDC, 0x00, 0xDC, 0x00, 0x30, 0x00, 0x02, 0x10, 0x0A, 0x03, + 0xFC, 0x00, 0x00, 0x0D, 0x57, 0x00, 0x00, 0x35, 0xF5, 0xC0, 0x00, 0xD7, 0xFD, 0xF0, 0x00, 0xD7, + 0xC3, 0xF0, 0x00, 0xD7, 0xC0, 0xC0, 0x00, 0xD7, 0xC0, 0x00, 0x00, 0xD7, 0xC3, 0x00, 0x00, 0xD7, + 0xCD, 0xC0, 0x00, 0x35, 0xF5, 0xF0, 0x00, 0x0D, 0x57, 0xF0, 0x00, 0x03, 0x7F, 0xC0, 0x00, 0x03, + 0xDF, 0x00, 0x00, 0x01, 0xDF, 0x00, 0x00, 0x03, 0x7C, 0x00, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x02, + 0x0D, 0x09, 0x0C, 0x0C, 0x00, 0x00, 0x37, 0x37, 0x00, 0x00, 0xD7, 0xD7, 0xC0, 0x03, 0x3F, 0xFF, + 0xC0, 0x00, 0x3F, 0x3F, 0x00, 0x03, 0xD7, 0xD7, 0x00, 0x0D, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, + 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0x35, 0x57, 0xC0, 0x0D, 0x0F, 0xFF, + 0xC0, 0x03, 0x03, 0xFF, 0x00, 0x00, 0x02, 0x0D, 0x09, 0x00, 0x30, 0x00, 0x03, 0x03, 0xDC, 0x00, + 0x0D, 0x0D, 0x7F, 0x00, 0x37, 0x03, 0xFC, 0x00, 0x0F, 0x0F, 0xF0, 0x00, 0x0F, 0x35, 0x5C, 0x00, + 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD5, 0x57, 0xC0, 0x3D, 0xD7, 0xFF, 0xC0, 0x35, 0xD7, 0xD7, 0x00, + 0xD7, 0x35, 0x5F, 0xC0, 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x02, 0x0D, 0x09, + 0x03, 0xC0, 0x00, 0x03, 0x0D, 0x70, 0x00, 0x0D, 0x37, 0xDC, 0x00, 0x35, 0x0F, 0xFF, 0x00, 0x0F, + 0x0F, 0xFC, 0x00, 0x03, 0x35, 0x5C, 0x00, 0x0D, 0xD7, 0xD7, 0x00, 0x35, 0x3D, 0x57, 0xC0, 0x0F, + 0x35, 0xD7, 0xC0, 0x0D, 0xD7, 0xD7, 0xC0, 0x35, 0x35, 0x57, 0xC0, 0x0D, 0x0F, 0xFF, 0xC0, 0x03, + 0x03, 0xFF, 0x00, 0x00, 0x02, 0x0D, 0x09, 0x0C, 0x0C, 0x00, 0x0C, 0x37, 0x37, 0x00, 0x37, 0xD7, + 0xD7, 0xC0, 0x0D, 0x3F, 0xFF, 0xC0, 0x03, 0x0F, 0xFF, 0x00, 0x3F, 0x35, 0x5C, 0x00, 0xD5, 0xD7, + 0xD7, 0x03, 0x5F, 0x3D, 0x57, 0xC0, 0xF5, 0x35, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC3, 0x5F, 0x35, + 0x57, 0xC0, 0xD5, 0x0F, 0xFF, 0xC0, 0x3F, 0x03, 0xFF, 0x00, 0x0F, 0x02, 0x0D, 0x09, 0x03, 0x00, + 0x00, 0x00, 0x0D, 0xF0, 0x00, 0x03, 0x03, 0x5C, 0x00, 0x0D, 0x00, 0xFF, 0x00, 0x03, 0x0F, 0xF0, + 0x00, 0x0F, 0x35, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0x3D, 0x57, 0xC0, 0x3D, 0x35, 0xD7, + 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x57, 0xC0, 0x35, 0x0F, 0xFF, 0xC0, 0x0F, 0x03, 0xFF, + 0x00, 0x03, 0x02, 0x0D, 0x09, 0x00, 0xC0, 0x00, 0x00, 0x03, 0x70, 0x00, 0x00, 0x0D, 0xDC, 0x00, + 0x00, 0x03, 0x7F, 0x00, 0x03, 0x0F, 0xFC, 0x00, 0x0D, 0x35, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, + 0x35, 0x3D, 0x57, 0xC0, 0x35, 0x35, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0x35, 0x57, 0xC0, + 0x0D, 0x0F, 0xFF, 0xC0, 0x03, 0x03, 0xFF, 0x00, 0x03, 0x02, 0x10, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x0F, 0xF0, 0x00, 0x03, 0x35, 0x5C, 0x00, 0x03, + 0xD7, 0xD7, 0x00, 0x0D, 0xD7, 0xFF, 0xC0, 0x35, 0xD7, 0xCF, 0x00, 0x35, 0xD7, 0xFC, 0x00, 0x35, + 0xD7, 0xD7, 0x00, 0x35, 0x35, 0x5F, 0xC0, 0x0D, 0x0D, 0xFF, 0x00, 0x03, 0x0F, 0x7C, 0x00, 0x00, + 0x07, 0x7C, 0x00, 0x00, 0x0D, 0xF0, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x02, 0x0D, 0x09, 0x03, + 0xC0, 0x00, 0x0C, 0x0D, 0x70, 0x00, 0x37, 0x37, 0xDC, 0x00, 0xD7, 0x0F, 0xFF, 0x00, 0x3F, 0x0F, + 0xFC, 0x00, 0x0F, 0x35, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD5, 0x57, 0xC0, 0xD5, 0xD7, + 0xFF, 0xC0, 0xD7, 0xD7, 0xD7, 0x00, 0xD7, 0x35, 0x5F, 0xC0, 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, + 0xFC, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x0C, 0x0C, 0x00, 0x03, 0x37, 0x37, 0x00, 0x0D, 0xD7, 0xD7, + 0xC0, 0x03, 0x3F, 0xFF, 0xC0, 0x00, 0x0F, 0xFF, 0x00, 0x03, 0x35, 0x5C, 0x00, 0x0D, 0xD7, 0xD7, + 0x00, 0x35, 0xD5, 0x57, 0xC0, 0x35, 0xD7, 0xFF, 0xC0, 0x35, 0xD7, 0xD7, 0x00, 0x35, 0x35, 0x5F, + 0xC0, 0x0D, 0x0F, 0xFF, 0x00, 0x03, 0x03, 0xFC, 0x00, 0x00, 0x02, 0x0D, 0x09, 0x0C, 0x00, 0x00, + 0x03, 0x37, 0xC0, 0x00, 0x0D, 0x0D, 0x70, 0x00, 0x35, 0x03, 0xFC, 0x00, 0x0F, 0x0F, 0xF0, 0x00, + 0x03, 0x35, 0x5C, 0x00, 0x03, 0xD7, 0xD7, 0x00, 0x03, 0xD5, 0x57, 0xC0, 0x03, 0xD7, 0xFF, 0xC0, + 0x03, 0xD7, 0xD7, 0x00, 0x03, 0x35, 0x5F, 0xC0, 0x03, 0x0F, 0xFF, 0x00, 0x00, 0x03, 0xFC, 0x00, + 0x00, 0x02, 0x0D, 0x09, 0x0C, 0x0C, 0x00, 0x03, 0x37, 0x37, 0x00, 0x0D, 0xD7, 0xD7, 0xC0, 0x37, + 0x3F, 0xFF, 0xC0, 0x0F, 0x0F, 0xCF, 0x00, 0x0F, 0x0D, 0x70, 0x00, 0x0D, 0x0D, 0x7C, 0x00, 0x0D, + 0x0D, 0x7C, 0x00, 0x0D, 0x0D, 0x7C, 0x00, 0x0D, 0x0D, 0x7C, 0x00, 0x0D, 0x0D, 0x7C, 0x00, 0x0D, + 0x03, 0xFC, 0x00, 0x03, 0x00, 0xF0, 0x00, 0x00, 0x01, 0x0D, 0x07, 0x0F, 0x00, 0x35, 0xC0, 0xDF, + 0x70, 0x3F, 0xFC, 0x3F, 0x30, 0x35, 0xC0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, 0xF0, 0x35, + 0xF0, 0x0F, 0xF0, 0x03, 0xC0, 0x01, 0x0D, 0x06, 0x30, 0x00, 0xDF, 0x00, 0x35, 0xC0, 0x0F, 0xF0, + 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0x3F, 0xC0, + 0x0F, 0x00, 0x02, 0x0D, 0x0B, 0x03, 0x03, 0x00, 0x03, 0x0D, 0xCD, 0xC0, 0x0D, 0x35, 0xF5, 0xF0, + 0x0D, 0x0F, 0xFF, 0xF0, 0x03, 0x03, 0x5F, 0x00, 0x00, 0x0D, 0x57, 0xC0, 0x00, 0x0D, 0xF7, 0xC0, + 0x00, 0x35, 0xF5, 0xC0, 0x00, 0x35, 0x55, 0xF0, 0x00, 0xD7, 0xFD, 0x70, 0x00, 0xD7, 0xFD, 0x7C, + 0x00, 0xFF, 0xFF, 0xFC, 0x00, 0x3F, 0xC3, 0xFC, 0x00, 0x01, 0x04, 0x03, 0x30, 0x00, 0xDC, 0x00, + 0xDC, 0x00, 0x30, 0x00, 0x02, 0x0D, 0x0A, 0x00, 0x30, 0x00, 0x00, 0x03, 0xDC, 0x00, 0x00, 0x0D, + 0x7F, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0xD5, 0x55, 0xC0, 0x00, 0xD7, 0xFF, 0xF0, 0x03, 0xD7, + 0xFF, 0xC0, 0x00, 0xD5, 0x57, 0x00, 0x00, 0xD7, 0xFF, 0xC0, 0x03, 0xD7, 0xFF, 0x00, 0x03, 0xD5, + 0x55, 0xC0, 0x00, 0x3F, 0xFF, 0xF0, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x02, 0x0D, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x3F, 0xC0, 0x35, 0x5C, + 0xD5, 0x70, 0xD7, 0xD7, 0x5F, 0x5C, 0x3D, 0x57, 0x55, 0x5F, 0x35, 0xD7, 0x5F, 0xFF, 0xD7, 0xD7, + 0x5F, 0xFC, 0xD7, 0xD7, 0x5F, 0x5C, 0x35, 0x55, 0x55, 0x7F, 0x0F, 0xFF, 0xFF, 0xFC, 0x03, 0xFF, + 0xFF, 0xF0, 0x02, 0x0D, 0x10, 0x00, 0x03, 0xFF, 0xF0, 0x00, 0x0D, 0x55, 0x5C, 0x00, 0x35, 0x7F, + 0xFF, 0x00, 0xD5, 0x7F, 0xFC, 0x00, 0xD5, 0x7F, 0xC0, 0x03, 0x5D, 0x55, 0x70, 0x0D, 0x7D, 0x7F, + 0xFC, 0x0D, 0x7D, 0x7F, 0xF0, 0x35, 0x55, 0x7C, 0x00, 0xD7, 0xFD, 0x7F, 0xF0, 0xD7, 0xFD, 0x55, + 0x5C, 0xFF, 0x0F, 0xFF, 0xFF, 0x3C, 0x03, 0xFF, 0xFC, 0x02, 0x0D, 0x09, 0x03, 0xC0, 0x00, 0x30, + 0x0D, 0x70, 0x00, 0xDC, 0x37, 0xDC, 0x03, 0x5F, 0x0F, 0xFF, 0x00, 0xFF, 0x0F, 0xFC, 0x00, 0x3F, + 0x35, 0x5C, 0x00, 0xD5, 0xD7, 0xD7, 0x03, 0x5F, 0xD7, 0xD7, 0xC3, 0x5F, 0xD7, 0xD7, 0xC3, 0x5F, + 0xD7, 0xD7, 0xC3, 0x5F, 0x35, 0x5F, 0xC0, 0xD5, 0x0F, 0xFF, 0x00, 0x3F, 0x03, 0xFC, 0x00, 0x0F, + 0x02, 0x0D, 0x09, 0x0C, 0x0C, 0x00, 0x0C, 0x37, 0x37, 0x00, 0x37, 0xD7, 0xD7, 0xC0, 0x0D, 0x3F, + 0xFF, 0xC0, 0x03, 0x0F, 0xFF, 0x00, 0x0F, 0x35, 0x5C, 0x00, 0x35, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, + 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0x35, 0x0F, + 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x0C, 0x00, 0x00, 0x03, 0x37, 0xC0, + 0x00, 0x0D, 0x0D, 0x70, 0x00, 0x37, 0x03, 0xFC, 0x00, 0x0F, 0x0F, 0xF0, 0x00, 0x3F, 0x35, 0x5C, + 0x00, 0xD7, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, + 0xC0, 0xD7, 0x35, 0x5F, 0xC0, 0x35, 0x0F, 0xFF, 0x00, 0x0F, 0x03, 0xFC, 0x00, 0x03, 0x02, 0x0D, + 0x09, 0x03, 0xC0, 0x00, 0x0C, 0x0D, 0x70, 0x00, 0x37, 0x37, 0xDC, 0x00, 0x0D, 0x0F, 0xFF, 0x00, + 0x03, 0x3F, 0x3C, 0x00, 0x3C, 0xD7, 0xD7, 0x00, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, + 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0xD7, 0xD7, 0xC0, 0xD7, 0x35, 0x57, 0xC0, 0x35, 0x0F, 0xFF, 0xC0, + 0x0F, 0x03, 0xFF, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x0C, 0x00, 0x00, 0x03, 0x37, 0xC0, 0x00, 0x0D, + 0x0D, 0x70, 0x00, 0x0D, 0x03, 0xFC, 0x00, 0x03, 0x3C, 0x3C, 0x00, 0x00, 0xD7, 0xD7, 0x00, 0x00, + 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0xD7, 0xD7, 0xC0, 0x00, + 0x35, 0x57, 0xC0, 0x00, 0x0F, 0xFF, 0xC0, 0x00, 0x03, 0xFF, 0x00, 0x00, 0x01, 0x04, 0x03, 0x30, + 0x00, 0xDC, 0x00, 0xDC, 0x00, 0x30, 0x00, 0x02, 0x0D, 0x0B, 0x03, 0x03, 0x00, 0x00, 0x0D, 0xCD, + 0xC0, 0x00, 0x35, 0xF5, 0xF0, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x0D, 0x57, 0xC0, 0x00, 0x35, 0xF5, + 0xC0, 0x00, 0xD7, 0xFD, 0x70, 0x00, 0xD7, 0xCD, 0x7C, 0x00, 0xD7, 0xCD, 0x7C, 0x00, 0x35, 0xF5, + 0xFC, 0x00, 0x0D, 0x57, 0xF0, 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x02, 0x0D, + 0x0B, 0x03, 0x03, 0x00, 0x00, 0x0D, 0xCD, 0xC0, 0x00, 0x35, 0xF5, 0xF0, 0x00, 0x3F, 0xFF, 0xF0, + 0x00, 0xD7, 0xCD, 0x70, 0x00, 0xD7, 0xCD, 0x7C, 0x00, 0xD7, 0xCD, 0x7C, 0x00, 0xD7, 0xCD, 0x7C, + 0x00, 0xD7, 0xFD, 0x7C, 0x00, 0xD5, 0x55, 0x7C, 0x00, 0x35, 0x55, 0xFC, 0x00, 0x0F, 0xFF, 0xF0, + 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x01, 0x04, 0x03, 0x30, 0x00, 0xDC, 0x03, 0xDC, 0x03, 0x30, 0x00, + 0x01, 0x04, 0x03, 0x30, 0x00, 0xDC, 0x00, 0xDC, 0x00, 0x30, 0x00, 0x02, 0x0D, 0x0E, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF3, 0xFC, 0x00, 0x35, 0x5D, + 0x57, 0x00, 0xD7, 0xD5, 0xF5, 0xC0, 0xD7, 0xD5, 0x55, 0xF0, 0xD7, 0xD5, 0xFF, 0xF0, 0xD7, 0xD5, + 0xFF, 0xC0, 0xD7, 0xD5, 0xF5, 0xC0, 0x35, 0x5D, 0x57, 0xF0, 0x3F, 0xFF, 0xFF, 0xC0, 0x0F, 0xFF, + 0xFF, 0x00, 0x01, 0x04, 0x03, 0x30, 0x30, 0xDC, 0xDC, 0xDC, 0xDC, 0x30, 0x30, 0x01, 0x04, 0x03, + 0x30, 0x00, 0xDC, 0x00, 0xDC, 0x00, 0x30, 0x00, 0x02, 0x0D, 0x09, 0x00, 0x30, 0x00, 0x03, 0x03, + 0xDC, 0x00, 0x3D, 0x0D, 0x7F, 0x00, 0xD7, 0x03, 0xFC, 0x00, 0x3F, 0x0F, 0xF0, 0x00, 0x3C, 0x35, + 0x5C, 0x00, 0xD7, 0xD7, 0xD7, 0x00, 0xD7, 0x3D, 0x57, 0xC0, 0xD7, 0x35, 0xD7, 0xC0, 0xD7, 0xD7, + 0xD7, 0xC0, 0xD7, 0x35, 0x57, 0xC0, 0xD7, 0x0F, 0xFF, 0xC0, 0x3F, 0x03, 0xFF, 0x00, 0x0F, 0x01, + 0x0D, 0x06, 0x03, 0x00, 0x3D, 0xC0, 0xD7, 0xF0, 0x3F, 0xC0, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC0, + 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x0D, 0x09, 0x00, + 0x30, 0x00, 0x00, 0x03, 0xDC, 0x00, 0x0F, 0x0D, 0x7F, 0x00, 0x35, 0x03, 0xFC, 0x00, 0x0F, 0x0F, + 0xF0, 0x00, 0xF0, 0x35, 0x5C, 0x03, 0x5F, 0xD7, 0xD7, 0x03, 0x5F, 0xD7, 0xD7, 0xC3, 0x5F, 0xD7, + 0xD7, 0xC3, 0x5F, 0xD7, 0xD7, 0xC3, 0x5F, 0x35, 0x5F, 0xC0, 0xD5, 0x0F, 0xFF, 0x00, 0x3F, 0x03, + 0xFC, 0x00, 0x0F, 0x02, 0x0D, 0x09, 0x00, 0x30, 0x00, 0x03, 0x03, 0xDC, 0x00, 0x0D, 0x0D, 0x7F, + 0x00, 0x37, 0x03, 0xFC, 0x00, 0x0F, 0x3C, 0x3C, 0x00, 0x0F, 0xD7, 0xD7, 0x00, 0x35, 0xD7, 0xD7, + 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0xD7, 0xD7, 0xC0, 0x35, 0x35, 0x57, + 0xC0, 0x35, 0x0F, 0xFF, 0xC0, 0x0F, 0x03, 0xFF, 0x00, 0x03, 0x02, 0x0D, 0x09, 0x0F, 0x0C, 0x00, + 0x0F, 0x35, 0xF7, 0x00, 0x35, 0xDF, 0x5F, 0xC0, 0xDF, 0x3F, 0xFF, 0x00, 0xFF, 0x3F, 0xFC, 0x03, + 0x5C, 0xD5, 0x5C, 0x03, 0x57, 0xD7, 0xD7, 0x03, 0x55, 0xD7, 0xD7, 0xC3, 0x5D, 0xD7, 0xD7, 0xC3, + 0x5F, 0xD7, 0xD7, 0xC3, 0x5F, 0xD7, 0xD7, 0xC3, 0x5F, 0x3F, 0xFF, 0xC0, 0xFF, 0x0F, 0x0F, 0x00, + 0x3C, 0x02, 0x0D, 0x0B, 0x03, 0xC3, 0x00, 0x00, 0x0D, 0x7D, 0xC0, 0x00, 0x37, 0xD7, 0xF0, 0x00, + 0x3F, 0xFF, 0xC0, 0x00, 0xD7, 0x0D, 0x70, 0x00, 0xD5, 0xCD, 0x7C, 0x00, 0xD5, 0x7D, 0x7C, 0x00, + 0xD7, 0x5D, 0x7C, 0x00, 0xD7, 0xD5, 0x7C, 0x00, 0xD7, 0xF5, 0x7C, 0x00, 0xD7, 0xCD, 0x7C, 0x00, + 0x3F, 0xC3, 0xFC, 0x00, 0x0F, 0x00, 0xF0, 0x00, 0x01, 0x04, 0x03, 0x30, 0x30, 0xDC, 0xDC, 0xDC, + 0xDC, 0x30, 0x30, 0x01, 0x04, 0x03, 0x30, 0x00, 0xDC, 0x00, 0xDC, 0x00, 0x30, 0x00, 0x02, 0x0D, + 0x09, 0x03, 0xC0, 0x00, 0x00, 0x0D, 0x70, 0x00, 0x00, 0x0D, 0x7C, 0x00, 0x00, 0x03, 0xFC, 0x00, + 0x00, 0x0D, 0x70, 0x00, 0x00, 0x0D, 0x7C, 0x00, 0x00, 0x35, 0xFC, 0x00, 0x00, 0xD7, 0xFC, 0x00, + 0x00, 0xD7, 0xD7, 0x00, 0x00, 0xD7, 0xD7, 0xC0, 0x00, 0x35, 0x5F, 0xC0, 0x00, 0x0F, 0xFF, 0x00, + 0x00, 0x03, 0xFC, 0x00, 0x00, 0x01, 0x04, 0x03, 0x30, 0x30, 0xDC, 0xDC, 0xDC, 0xDC, 0x30, 0x30, + 0x01, 0x04, 0x03, 0x30, 0x30, 0xDC, 0xDC, 0xDC, 0xDC, 0x30, 0x30, 0x01, 0x04, 0x03, 0x30, 0x30, + 0xDC, 0xDC, 0xDC, 0xDC, 0x30, 0x30, 0x01, 0x04, 0x03, 0x30, 0x03, 0xDC, 0x0D, 0xDC, 0x0D, 0x30, + 0x03, 0x01, 0x0D, 0x05, 0x3C, 0x00, 0xD7, 0x00, 0xD7, 0xC0, 0x3F, 0xC0, 0xD7, 0x00, 0xD7, 0xC0, + 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0xD7, 0xC0, 0x3F, 0xC0, 0x0F, 0x00, 0x02, 0x0A, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0C, 0x00, 0x00, 0x0D, 0xF7, 0x00, + 0x00, 0x37, 0xDF, 0xC0, 0x00, 0xDF, 0x7F, 0x00, 0x00, 0x37, 0xDC, 0x00, 0x00, 0x0D, 0xF7, 0x00, + 0x00, 0x03, 0xFF, 0xC0, 0x00, 0x00, 0xC3, 0x00, 0x00, 0x02, 0x0A, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0xC0, 0x00, 0x00, 0xDF, 0x70, 0x00, 0x00, 0x37, 0xDC, 0x00, 0x00, + 0x0D, 0xF7, 0x00, 0x00, 0x37, 0xDF, 0xC0, 0x00, 0xDF, 0x7F, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, + 0x0C, 0x30, 0x00, 0x00, 0x02, 0x10, 0x0B, 0x00, 0xFF, 0x00, 0x00, 0x03, 0x55, 0xC0, 0x00, 0x0D, + 0x7D, 0x70, 0x00, 0x0D, 0x7D, 0x7C, 0x00, 0x0D, 0x7D, 0x7C, 0x00, 0x0D, 0x75, 0xFC, 0x00, 0x0D, + 0x75, 0x70, 0x00, 0x0D, 0x7D, 0x7C, 0x00, 0x0D, 0x7D, 0x7C, 0x00, 0x0D, 0x7D, 0x7C, 0x00, 0x0D, + 0x55, 0xFC, 0x00, 0x0D, 0x7F, 0xF0, 0x00, 0x35, 0xFF, 0xC0, 0x00, 0x35, 0xF0, 0x00, 0x00, 0xD7, + 0xF0, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00 +}; + const uint16 *Graphics::_fontOffs = Graphics::_engFontOffs; int Graphics::_fontSize = Graphics::_engFontSize; diff --git a/engines/touche/ui.cpp b/engines/touche/ui.cpp index 997999eaf7..ba4dba9037 100644 --- a/engines/touche/ui.cpp +++ b/engines/touche/ui.cpp @@ -559,7 +559,19 @@ int ToucheEngine::displayQuitDialog() { ret = 1; } break; + case Common::DE_DEU: + if (event.kbd.ascii == 'j' || event.kbd.ascii == 'J') { + ret = 1; + } + break; + case Common::ES_ESP: + if (event.kbd.ascii == 's' || event.kbd.ascii == 'S') { + ret = 1; + } + break; default: + // According to cyx, the Italian version uses the same + // keys as the English one. if (event.kbd.ascii == 'y' || event.kbd.ascii == 'Y') { ret = 1; } diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index 06364b860a..397d74789f 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -24,8 +24,6 @@ #include "common/system.h" #include "common/stack.h" -DECLARE_SINGLETON(Graphics::CursorManager); - namespace Graphics { static bool g_initialized = false; diff --git a/graphics/font.h b/graphics/font.h index 4c271903c5..263bedd96d 100644 --- a/graphics/font.h +++ b/graphics/font.h @@ -81,7 +81,7 @@ public: class ScummFont : public Font { public: virtual int getFontHeight() const { return 8; } - virtual int getMaxCharWidth() const { return 8; }; + virtual int getMaxCharWidth() const { return 8; } virtual int getCharWidth(byte chr) const; virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const; @@ -126,7 +126,7 @@ public: ~NewFont(); virtual int getFontHeight() const { return desc.height; } - virtual int getMaxCharWidth() const { return desc.maxwidth; }; + virtual int getMaxCharWidth() const { return desc.maxwidth; } virtual int getCharWidth(byte chr) const; virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const; diff --git a/graphics/fontman.cpp b/graphics/fontman.cpp index 9b567c0be8..fad8654d02 100644 --- a/graphics/fontman.cpp +++ b/graphics/fontman.cpp @@ -22,8 +22,6 @@ #include "graphics/fontman.h" //#include "gui/consolefont.h" -DECLARE_SINGLETON(Graphics::FontManager); - namespace Graphics { #if !(defined(PALMOS_ARM) || defined(PALMOS_DEBUG) || defined(__GP32__)) diff --git a/graphics/iff.cpp b/graphics/iff.cpp new file mode 100644 index 0000000000..7ab34e2989 --- /dev/null +++ b/graphics/iff.cpp @@ -0,0 +1,312 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + +#include "graphics/iff.h" +#include "graphics/surface.h" + +#include "common/util.h" + + +namespace Common { + +// this really belongs to iff_container.cpp, but we don't want +// to put only this in a source file +char *ID2string(Common::IFF_ID id) { + static char str[] = "abcd"; + + str[0] = (char)(id >> 24 & 0xff); + str[1] = (char)(id >> 16 & 0xff); + str[2] = (char)(id >> 8 & 0xff); + str[3] = (char)(id >> 0 & 0xff); + + return str; +} + +} + + +namespace Graphics { + + +void fillBMHD(BMHD &bitmapHeader, Common::ReadStream &stream) { + + bitmapHeader.width = stream.readUint16BE(); + bitmapHeader.height = stream.readUint16BE(); + bitmapHeader.x = stream.readUint16BE(); + bitmapHeader.y = stream.readUint16BE(); + bitmapHeader.depth = stream.readByte(); + bitmapHeader.masking = stream.readByte(); + bitmapHeader.pack = stream.readByte(); + bitmapHeader.flags = stream.readByte(); + bitmapHeader.transparentColor = stream.readUint16BE(); + bitmapHeader.xAspect = stream.readByte(); + bitmapHeader.yAspect = stream.readByte(); + bitmapHeader.pageWidth = stream.readUint16BE(); + bitmapHeader.pageHeight = stream.readUint16BE(); + +} + + +ILBMDecoder::ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) { + if (_typeId != ID_ILBM) + error("unsupported IFF subtype '%s'", Common::ID2string(_typeId)); +} + +void ILBMDecoder::decode() { + + Common::IFFChunk *chunk; + while ((chunk = nextChunk()) != 0) { + switch (chunk->id) { + case ID_BMHD: + readBMHD(*chunk); + break; + + case ID_CMAP: + readCMAP(*chunk); + break; + + case ID_BODY: + readBODY(*chunk); + break; + } + } + + return; +} + +void ILBMDecoder::readBMHD(Common::IFFChunk &chunk) { + + fillBMHD(_bitmapHeader, chunk); + + _colorCount = 1 << _bitmapHeader.depth; + *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3); + _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); + +} + +void ILBMDecoder::readCMAP(Common::IFFChunk &chunk) { + if (*_colors == NULL) { + error("wrong input chunk sequence"); + } + for (uint32 i = 0; i < _colorCount; i++) { + (*_colors)[i * 3 + 0] = chunk.readByte(); + (*_colors)[i * 3 + 1] = chunk.readByte(); + (*_colors)[i * 3 + 2] = chunk.readByte(); + } +} + +void ILBMDecoder::readBODY(Common::IFFChunk& chunk) { + + switch (_bitmapHeader.pack) { + case 0: + error("unpacked ILBM files are not supported"); + break; + + case 1: { + uint32 scanWidth = _bitmapHeader.width >> 3; + byte *scan = (byte*)malloc(scanWidth); + byte *out = (byte*)_surface->pixels; + + PackBitsReadStream stream(chunk); + + for (uint32 i = 0; i < _bitmapHeader.height; i++) { + + for (uint32 j = 0; j < _bitmapHeader.depth; j++) { + stream.read(scan, scanWidth); + fillPlane(out, scan, scanWidth, j); + } + + out += _bitmapHeader.width; + } + break; + } + + } +} + +void ILBMDecoder::fillPlane(byte *out, byte* buf, uint32 width, uint32 plane) { + + byte src, idx, set; + byte mask = 1 << plane; + + for (uint32 j = 0; j < _bitmapHeader.width; j++) { + src = buf[j >> 3]; + idx = 7 - (j & 7); + set = src & (1 << idx); + + if (set) + out[j] |= mask; + } + +} + + + + +PBMDecoder::PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors) : IFFParser(input), _surface(&surface), _colors(&colors) { + if (_typeId != ID_PBM) + error("unsupported IFF subtype '%s'", Common::ID2string(_typeId)); +} + +void PBMDecoder::decode() { + + Common::IFFChunk *chunk; + while ((chunk = nextChunk()) != 0) { + switch (chunk->id) { + case ID_BMHD: + readBMHD(*chunk); + break; + + case ID_CMAP: + readCMAP(*chunk); + break; + + case ID_BODY: + readBODY(*chunk); + break; + } + } + + return; +} + +void PBMDecoder::readBMHD(Common::IFFChunk &chunk) { + + fillBMHD(_bitmapHeader, chunk); + + _colorCount = 1 << _bitmapHeader.depth; + *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3); + _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); + +} + +void PBMDecoder::readCMAP(Common::IFFChunk &chunk) { + if (*_colors == NULL) { + error("wrong input chunk sequence"); + } + for (uint32 i = 0; i < _colorCount; i++) { + (*_colors)[i * 3 + 0] = chunk.readByte(); + (*_colors)[i * 3 + 1] = chunk.readByte(); + (*_colors)[i * 3 + 2] = chunk.readByte(); + } +} + +void PBMDecoder::readBODY(Common::IFFChunk& chunk) { + + uint si = 0; + + switch (_bitmapHeader.pack) { + case 0: + while (!chunk.eos()) { + ((byte*)_surface->pixels)[si++] = chunk.readByte(); + } + break; + + case 1: { + PackBitsReadStream stream(chunk); + stream.read((byte*)_surface->pixels, _surface->w * _surface->h); + break; + } + + } +} + + + + + + +PackBitsReadStream::PackBitsReadStream(Common::ReadStream &input) : _input(&input), _wStoragePos(_storage), _rStoragePos(_storage) { +} + +PackBitsReadStream::~PackBitsReadStream() { +} + +bool PackBitsReadStream::eos() const { + return _input->eos() & (_rStoragePos == _wStoragePos); +} + +uint32 PackBitsReadStream::read(void *dataPtr, uint32 dataSize) { + _out = (byte*)dataPtr; + _outEnd = _out + dataSize; + + feed(); + unpack(); + return _fed + _unpacked; +} + +void PackBitsReadStream::store(byte b) { + if (_out < _outEnd) { + *_out++ = b; + _unpacked++; + _wStoragePos = _storage; + } else { + assert(_wStoragePos < _storage + 257); + *_wStoragePos++ = b; + } + + _rStoragePos = _storage; +} + +void PackBitsReadStream::feed() { + _fed = 0; + + int len = MIN(_wStoragePos - _rStoragePos, _outEnd - _out); + if (len == 0) return; + + for (int i = 0; i < len; i++) + *_out++ = *_rStoragePos++; + + _fed = len; +} + +void PackBitsReadStream::unpack() { + byte byteRun; + byte idx; + + uint32 i, j; + _unpacked = 0; + + while (_out < _outEnd && !_input->eos()) { + byteRun = _input->readByte(); + if (byteRun <= 127) { + i = byteRun + 1; + for (j = 0; j < i; j++) { + idx = _input->readByte(); + store(idx); + } + } else if (byteRun != 128) { + i = (256 - byteRun) + 1; + idx = _input->readByte(); + for (j = 0; j < i; j++) { + store(idx); + } + } + } +} + + +void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors) { + PBMDecoder decoder(input, surface, colors); + decoder.decode(); +} + +} diff --git a/graphics/iff.h b/graphics/iff.h new file mode 100644 index 0000000000..322c372592 --- /dev/null +++ b/graphics/iff.h @@ -0,0 +1,135 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + */ + + +#ifndef GRAPHICS_IFF_H +#define GRAPHICS_IFF_H + +#include "common/iff_container.h" + +namespace Graphics { + +struct Surface; + + +struct BMHD { + uint16 width, height; + uint16 x, y; + byte depth; + byte masking; + byte pack; + byte flags; + uint16 transparentColor; + byte xAspect, yAspect; + uint16 pageWidth, pageHeight; + + BMHD() { + memset(this, 0, sizeof(*this)); + } +}; + + +// handles ILBM subtype of IFF FORM files +// +class ILBMDecoder : public Common::IFFParser { + +protected: + void readBMHD(Common::IFFChunk &chunk); + void readCMAP(Common::IFFChunk &chunk); + void readBODY(Common::IFFChunk &chunk); + + BMHD _bitmapHeader; + uint32 _colorCount; + + Surface *_surface; + byte **_colors; + + void fillPlane(byte *out, byte* buf, uint32 width, uint32 plane); + +public: + ILBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors); + virtual ~ILBMDecoder() { } + void decode(); +}; + + +// handles PBM subtype of IFF FORM files +// +class PBMDecoder : public Common::IFFParser { + +protected: + void readBMHD(Common::IFFChunk &chunk); + void readCMAP(Common::IFFChunk &chunk); + void readBODY(Common::IFFChunk &chunk); + + BMHD _bitmapHeader; + uint32 _colorCount; + + Surface *_surface; + byte **_colors; + +public: + PBMDecoder(Common::ReadStream &input, Surface &surface, byte *&colors); + virtual ~PBMDecoder() { } + void decode(); +}; + +void decodePBM(Common::ReadStream &input, Surface &surface, byte *&colors); + + +/* + PackBits is a RLE compression algorithm introduced + by Apple. It is also used to encode ILBM and PBM + subtypes of IFF files, and some flavours of TIFF. + + The following implementation uses a static storage + and is buffered, that means you can't destroy the + input stream before you are done with it. +*/ +class PackBitsReadStream : public Common::ReadStream { + +protected: + Common::ReadStream *_input; + + byte _storage[257]; + byte *_wStoragePos; + byte *_rStoragePos; + + byte* _out; + byte* _outEnd; + int32 _fed; + int32 _unpacked; + + void store(byte b); + void feed(); + void unpack(); + +public: + PackBitsReadStream(Common::ReadStream &input); + ~PackBitsReadStream(); + + virtual bool eos() const; + uint32 read(void *dataPtr, uint32 dataSize); +}; + +} + +#endif diff --git a/graphics/ilbm.cpp b/graphics/ilbm.cpp deleted file mode 100644 index c237dd0f92..0000000000 --- a/graphics/ilbm.cpp +++ /dev/null @@ -1,482 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2005-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#include "common/stdafx.h" -#include "common/endian.h" -#include "common/stream.h" -#include "graphics/surface.h" -#include "graphics/ilbm.h" - -namespace Graphics { - -static char * ID2string(IFF_ID id) { - static char str[] = "abcd"; - - str[0] = (char)(id >> 24 & 0xff); - str[1] = (char)(id >> 16 & 0xff); - str[2] = (char)(id >> 8 & 0xff); - str[3] = (char)(id >> 0 & 0xff); - - return str; -} - -#define ID_FORM MKID_BE('FORM') -/* EA IFF 85 group identifier */ -#define ID_CAT MKID_BE('CAT ') -/* EA IFF 85 group identifier */ -#define ID_LIST MKID_BE('LIST') -/* EA IFF 85 group identifier */ -#define ID_PROP MKID_BE('PROP') -/* EA IFF 85 group identifier */ -#define ID_END MKID_BE('END ') -/* unofficial END-of-FORM identifier (see Amiga RKM Devices Ed.3 -page 376) */ -#define ID_ILBM MKID_BE('ILBM') -/* EA IFF 85 raster bitmap form */ -#define ID_DEEP MKID_BE('DEEP') -/* Chunky pixel image files (Used in TV Paint) */ -#define ID_RGB8 MKID_BE('RGB8') -/* RGB image forms, Turbo Silver (Impulse) */ -#define ID_RGBN MKID_BE('RGBN') -/* RGB image forms, Turbo Silver (Impulse) */ -#define ID_PBM MKID_BE('PBM ') -/* 256-color chunky format (DPaint 2 ?) */ -#define ID_ACBM MKID_BE('ACBM') -/* Amiga Contiguous Bitmap (AmigaBasic) */ - -/* generic */ - -#define ID_FVER MKID_BE('FVER') -/* AmigaOS version string */ -#define ID_JUNK MKID_BE('JUNK') -/* always ignore this chunk */ -#define ID_ANNO MKID_BE('ANNO') -/* EA IFF 85 Generic Annotation chunk */ -#define ID_AUTH MKID_BE('AUTH') -/* EA IFF 85 Generic Author chunk */ -#define ID_CHRS MKID_BE('CHRS') -/* EA IFF 85 Generic character string chunk */ -#define ID_NAME MKID_BE('NAME') -/* EA IFF 85 Generic Name of art, music, etc. chunk */ -#define ID_TEXT MKID_BE('TEXT') -/* EA IFF 85 Generic unformatted ASCII text chunk */ -#define ID_copy MKID_BE('(c) ') -/* EA IFF 85 Generic Copyright text chunk */ - -/* ILBM chunks */ - -#define ID_BMHD MKID_BE('BMHD') -/* ILBM BitmapHeader */ -#define ID_CMAP MKID_BE('CMAP') -/* ILBM 8bit RGB colormap */ -#define ID_GRAB MKID_BE('GRAB') -/* ILBM "hotspot" coordiantes */ -#define ID_DEST MKID_BE('DEST') -/* ILBM destination image info */ -#define ID_SPRT MKID_BE('SPRT') -/* ILBM sprite identifier */ -#define ID_CAMG MKID_BE('CAMG') -/* Amiga viewportmodes */ -#define ID_BODY MKID_BE('BODY') -/* ILBM image data */ -#define ID_CRNG MKID_BE('CRNG') -/* color cycling */ -#define ID_CCRT MKID_BE('CCRT') -/* color cycling */ -#define ID_CLUT MKID_BE('CLUT') -/* Color Lookup Table chunk */ -#define ID_DPI MKID_BE('DPI ') -/* Dots per inch chunk */ -#define ID_DPPV MKID_BE('DPPV') -/* DPaint perspective chunk (EA) */ -#define ID_DRNG MKID_BE('DRNG') -/* DPaint IV enhanced color cycle chunk (EA) */ -#define ID_EPSF MKID_BE('EPSF') -/* Encapsulated Postscript chunk */ -#define ID_CMYK MKID_BE('CMYK') -/* Cyan, Magenta, Yellow, & Black color map (Soft-Logik) */ -#define ID_CNAM MKID_BE('CNAM') -/* Color naming chunk (Soft-Logik) */ -#define ID_PCHG MKID_BE('PCHG') -/* Line by line palette control information (Sebastiano Vigna) */ -#define ID_PRVW MKID_BE('PRVW') -/* A mini duplicate ILBM used for preview (Gary Bonham) */ -#define ID_XBMI MKID_BE('XBMI') -/* eXtended BitMap Information (Soft-Logik) */ -#define ID_CTBL MKID_BE('CTBL') -/* Newtek Dynamic Ham color chunk */ -#define ID_DYCP MKID_BE('DYCP') -/* Newtek Dynamic Ham chunk */ -#define ID_SHAM MKID_BE('SHAM') -/* Sliced HAM color chunk */ -#define ID_ABIT MKID_BE('ABIT') -/* ACBM body chunk */ -#define ID_DCOL MKID_BE('DCOL') -/* unofficial direct color */ -#define ID_DPPS MKID_BE('DPPS') -/* ? */ -#define ID_TINY MKID_BE('TINY') -/* ? */ -#define ID_DPPV MKID_BE('DPPV') -/* ? */ - -void IFFDecoder::readBMHD() { - - _bitmapHeader.width = _chunk.readUint16(); - _bitmapHeader.height = _chunk.readUint16(); - _bitmapHeader.x = _chunk.readUint16(); - _bitmapHeader.y = _chunk.readUint16(); - - _bitmapHeader.depth = _chunk.readByte(); - _bitmapHeader.masking = _chunk.readByte(); - _bitmapHeader.pack = _chunk.readByte(); - _bitmapHeader.flags = _chunk.readByte(); - _bitmapHeader.transparentColor = _chunk.readUint16(); - _bitmapHeader.xAspect = _chunk.readByte(); - _bitmapHeader.yAspect = _chunk.readByte(); - _bitmapHeader.pageWidth = _chunk.readUint16(); - _bitmapHeader.pageHeight = _chunk.readUint16(); - - - _colorCount = 1 << _bitmapHeader.depth; - *_colors = (byte*)malloc(sizeof(**_colors) * _colorCount * 3); - _surface->create(_bitmapHeader.width, _bitmapHeader.height, 1); - -} - -void IFFDecoder::readCRNG() { -} - -void IFFDecoder::readCMAP() { - if (*_colors == NULL) { - error("wrong input chunk sequence"); - } - for (uint32 i = 0; i < _colorCount; i++) { - (*_colors)[i * 3 + 0] = _chunk.readByte(); - (*_colors)[i * 3 + 1] = _chunk.readByte(); - (*_colors)[i * 3 + 2] = _chunk.readByte(); - } -} - -IFFDecoder::IFFDecoder(Common::ReadStream &input) : _formChunk(&input), _chunk(&input), _colorCount(0) { - _formChunk.readHeader(); - if (_formChunk.id != ID_FORM) { - error("IFFDecoder input is not a FORM type IFF file"); - } -} - -void IFFDecoder::decode(Surface &surface, byte *&colors) { - _surface = &surface; - _colors = &colors; - *_colors = 0; - - if (!isTypeSupported(_formChunk.readUint32())) { - error( "IFFDecoder input is not a valid subtype"); - } - - while (!_formChunk.eos()) { - _formChunk.incBytesRead(8); - _chunk.readHeader(); - - switch (_chunk.id) { - case ID_BMHD: - readBMHD(); - break; - - case ID_CMAP: - readCMAP(); - break; - - case ID_BODY: - readBODY(); - break; - - case ID_CRNG: - readCRNG(); - break; - - case ID_GRAB: case ID_TINY: case ID_DPPS: case ID_DPPV: case ID_CAMG: - break; - - default: - error("unknown chunk : %s\n", ID2string(_chunk.id)); - } - - _chunk.feed(); - _formChunk.incBytesRead(_chunk.size); - } -} - -bool PBMDecoder::isTypeSupported(IFF_ID type) { - return type == ID_PBM; -} - -void PBMDecoder::readBODY() { - byte byteRun; - byte idx; - uint32 si = 0, i, j; - - if (_bitmapHeader.depth > 8) { - error("PBMDecoder depth > 8"); - } - - if ((_bitmapHeader.pack != 0) && (_bitmapHeader.pack != 1)) { - error("PBMDecoder unsupported pack"); - } - - switch (_bitmapHeader.pack) { - case 0: - while (!_chunk.eos()) { - idx = _chunk.readByte(); - ((byte*)_surface->pixels)[si++] = idx; - } - break; - case 1: - while (!_chunk.eos()) { - byteRun = _chunk.readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++){ - idx = _chunk.readByte(); - ((byte*)_surface->pixels)[si++] = idx; - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = _chunk.readByte(); - for (j = 0; j < i; j++) { - ((byte*)_surface->pixels)[si++] = idx; - } - } - } - break; - } - -} - - -bool ILBMDecoder::isTypeSupported(IFF_ID type) { - return type == ID_ILBM; -} - -void ILBMDecoder::expandLine(byte *buf, uint32 width) { - - byte byteRun; - byte idx; - - uint32 si = 0, i, j; - - while (si != width) { - byteRun = _chunk.readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++){ - idx = _chunk.readByte(); - buf[si++] = idx; - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = _chunk.readByte(); - for (j = 0; j < i; j++) { - buf[si++] = idx; - } - } - } - -} - -void ILBMDecoder::fillPlane(byte *out, byte* buf, uint32 width, uint32 plane) { - - byte src, idx, set; - byte mask = 1 << plane; - - for (uint32 j = 0; j < _bitmapHeader.width; j++) { - src = buf[j >> 3]; - idx = 7 - (j & 7); - set = src & (1 << idx); - - if (set) - out[j] |= mask; - } - -} - -void ILBMDecoder::readBODY() { - - if (_bitmapHeader.depth > 8) { - error("ILBMDecoder depth > 8"); - } - - if (_bitmapHeader.pack != 1) { - error("ILBMDecoder unsupported pack"); - } - - if (_bitmapHeader.masking == 1) { - error("ILBMDecoder mask not supported"); - } - - uint32 scanWidth = _bitmapHeader.width >> 3; - byte *scan = (byte*)malloc(scanWidth); - byte *out = (byte*)_surface->pixels; - - switch (_bitmapHeader.pack) { -// case 0: -// while (!_chunk.eos()) { -// idx = _chunk.readByte(); -// ((byte*)_surface->pixels)[si++] = idx; -// } -// break; - case 1: - for (uint32 line = 0; line < _bitmapHeader.height; line++) { - - for (uint32 plane = 0; plane < _bitmapHeader.depth; plane++) { - expandLine(scan, scanWidth); - fillPlane(out, scan, scanWidth, plane); - } - - out += _bitmapHeader.width; - } - break; - } - - free(scan); - -} - -void ILBMDecoder::readCRNG() { - // TODO: implement this. May require changing decode(), too, or adding - // another parameter to ILBMDecoder constructor -} - -ILBMDecoder::ILBMDecoder(Common::ReadStream &input) : IFFDecoder(input) { - -} - -ILBMDecoder::~ILBMDecoder() { - -} - - - -void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors) { - IFF_ID typeId; - BMHD bitmapHeader; - Chunk formChunk(&input); - Chunk chunk(&input); - uint32 colorCount = 0, i, j, si; - byte byteRun; - byte idx; - colors = 0; - si = 0; - - formChunk.readHeader(); - if (formChunk.id != ID_FORM) { - error("decodeILBM() input is not a FORM type IFF file"); - } - - typeId = formChunk.readUint32(); - if (typeId != ID_PBM) { - error( "decodeILBM() input is not an PBM "); - } - - while (!formChunk.eos()) { - formChunk.incBytesRead(8); - chunk.readHeader(); - - switch (chunk.id) { - case ID_BMHD: - bitmapHeader.width = chunk.readUint16(); - bitmapHeader.height = chunk.readUint16(); - bitmapHeader.x = chunk.readUint16(); - bitmapHeader.y = chunk.readUint16(); - - bitmapHeader.depth = chunk.readByte(); - if (bitmapHeader.depth > 8) { - error("decodeILBM() depth > 8"); - } - bitmapHeader.masking = chunk.readByte(); - bitmapHeader.pack = chunk.readByte(); - if ((bitmapHeader.pack != 0) && (bitmapHeader.pack != 1)) { - error("decodeILBM() unsupported pack"); - } - bitmapHeader.flags = chunk.readByte(); - bitmapHeader.transparentColor = chunk.readUint16(); - bitmapHeader.xAspect = chunk.readByte(); - bitmapHeader.yAspect = chunk.readByte(); - bitmapHeader.pageWidth = chunk.readUint16(); - bitmapHeader.pageHeight = chunk.readUint16(); - - - colorCount = 1 << bitmapHeader.depth; - colors = (byte*)malloc(sizeof(*colors) * colorCount * 3); - surface.create(bitmapHeader.width, bitmapHeader.height, 1); - break; - case ID_CMAP: - if (colors == NULL) { - error("wrong input chunk sequence"); - } - for (i = 0; i < colorCount; i++) { - colors[i * 3 + 0] = chunk.readByte(); - colors[i * 3 + 1] = chunk.readByte(); - colors[i * 3 + 2] = chunk.readByte(); - } - break; - - case ID_BODY: - switch (bitmapHeader.pack) { - case 0: - while (!chunk.eos()) { - idx = chunk.readByte(); - ((byte*)surface.pixels)[si++] = idx; - } - break; - case 1: - while (!chunk.eos()) { - byteRun = chunk.readByte(); - if (byteRun <= 127) { - i = byteRun + 1; - for (j = 0; j < i; j++){ - idx = chunk.readByte(); - ((byte*)surface.pixels)[si++] = idx; - } - } else if (byteRun != 128) { - i = (256 - byteRun) + 1; - idx = chunk.readByte(); - for (j = 0; j < i; j++) { - ((byte*)surface.pixels)[si++] = idx; - } - } - } - break; - } - break; - case ID_GRAB: case ID_CRNG: case ID_TINY: case ID_DPPS: - break; - default: - error("unknown chunk : %s\n", ID2string(chunk.id)); - } - - chunk.feed(); - formChunk.incBytesRead(chunk.size); - } -} - -} // End of namespace Graphics - diff --git a/graphics/ilbm.h b/graphics/ilbm.h deleted file mode 100644 index 8c50d9fe5e..0000000000 --- a/graphics/ilbm.h +++ /dev/null @@ -1,165 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2002-2006 The ScummVM project - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - */ - -#ifndef GRAPHICS_ILBM_H -#define GRAPHICS_ILBM_H - -namespace Graphics { - -void decodeILBM(Common::ReadStream &input, Surface &surface, byte *&colors); - -typedef uint32 IFF_ID; - -struct Chunk { - IFF_ID id; - uint32 size; - uint32 bytesRead; - Common::ReadStream *_input; - - Chunk(Common::ReadStream *input): _input(input) { - size = bytesRead = 0; - } - - void incBytesRead(uint32 inc) { - bytesRead += inc; - if (bytesRead > size) { - error("Chunk overead"); - } - } - - void readHeader() { - id = _input->readUint32BE(); - size = _input->readUint32BE(); - bytesRead = 0; - } - - bool eos() { - return (size - bytesRead) == 0; - } - - void feed() { - if (size % 2) { - size++; - } - while (!_input->eos() && !eos()) { - readByte(); - } - } - - byte readByte() { - incBytesRead(1); - return _input->readByte(); - } - - int8 readSByte() { - incBytesRead(1); - return _input->readSByte(); - } - - uint16 readUint16() { - incBytesRead(2); - return _input->readUint16BE(); - } - - uint32 readUint32() { - incBytesRead(4); - return _input->readUint32BE(); - } - - int16 readSint16() { - return (int16)readUint16(); - } - - int32 readSint32() { - return (int32)readUint32(); - } -}; - -struct BMHD { - uint16 width, height; - uint16 x, y; - byte depth; - byte masking; - byte pack; - byte flags; - uint16 transparentColor; - byte xAspect, yAspect; - uint16 pageWidth, pageHeight; - - BMHD() { - memset(this, 0, sizeof(*this)); - } -}; - -class IFFDecoder { -public: - IFFDecoder(Common::ReadStream &input); - virtual ~IFFDecoder() {} - - virtual void decode(Surface &surface, byte *&colors); - -protected: - Chunk _formChunk; - Chunk _chunk; - - IFF_ID _typeId; - BMHD _bitmapHeader; - uint32 _colorCount; - - Surface *_surface; - byte **_colors; - - virtual bool isTypeSupported(IFF_ID type) = 0; - virtual void readBODY() = 0; - - virtual void readBMHD(); - virtual void readCMAP(); - virtual void readCRNG(); -}; - -class PBMDecoder : public IFFDecoder { -public: - PBMDecoder(Common::ReadStream &input) : IFFDecoder(input) {} -protected: - bool isTypeSupported(IFF_ID type); - void readBODY(); -}; - - - -class ILBMDecoder : public IFFDecoder { - -protected: - bool isTypeSupported(IFF_ID type); - void readBODY(); - void readCRNG(); - void expandLine(byte *buf, uint32 width); - void fillPlane(byte *out, byte* buf, uint32 width, uint32 plane); - -public: - ILBMDecoder(Common::ReadStream &input); - ~ILBMDecoder(); -}; - -} // End of namespace Graphics - -#endif - diff --git a/graphics/imageman.cpp b/graphics/imageman.cpp index d4fc9da72d..1145dd262f 100644 --- a/graphics/imageman.cpp +++ b/graphics/imageman.cpp @@ -23,8 +23,6 @@ #include "graphics/imageman.h" #include "graphics/surface.h" -DECLARE_SINGLETON(Graphics::ImageManager); - namespace Graphics { ImageManager::ImageManager() : _surfaces() #ifdef USE_ZLIB diff --git a/graphics/module.mk b/graphics/module.mk index 44c118668f..4ab8b1450e 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -9,7 +9,7 @@ MODULE_OBJS := \ fonts/newfont_big.o \ fonts/newfont.o \ fonts/scummfont.o \ - ilbm.o \ + iff.o \ imagedec.o \ imageman.o \ mpeg_player.o \ diff --git a/graphics/mpeg_player.cpp b/graphics/mpeg_player.cpp index 4ecf5cb6a6..b1427522b0 100644 --- a/graphics/mpeg_player.cpp +++ b/graphics/mpeg_player.cpp @@ -380,10 +380,10 @@ void BaseAnimationState::buildLookup() { // would be done here. See the Berkeley mpeg_play sources. CR = CB = (i - 128); - Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR); - Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR); + Cr_r_tab[i] = (int16) ( (0.419 / 0.299) * CR) + 0 * 768 + 256; + Cr_g_tab[i] = (int16) (-(0.299 / 0.419) * CR) + 1 * 768 + 256; Cb_g_tab[i] = (int16) (-(0.114 / 0.331) * CB); - Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB); + Cb_b_tab[i] = (int16) ( (0.587 / 0.331) * CB) + 2 * 768 + 256; } // Set up entries 0-255 in rgb-to-pixel value tables. @@ -422,8 +422,6 @@ void BaseAnimationState::plotYUV(int width, int height, byte *const *dat) { } void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) { - OverlayColor *ptr = _overlay; - byte *lum = dat[0]; byte *cr = dat[2]; byte *cb = dat[1]; @@ -434,37 +432,37 @@ void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) { int16 crb_g; int16 cb_b; - OverlayColor *row1 = ptr; - OverlayColor *row2 = ptr + _movieWidth; + OverlayColor *row1 = _overlay; + OverlayColor *row2 = row1 + _movieWidth; - int x, y; + int x; - for (y = 0; y < height; y += 2) { + for (; height > 0; height -= 2) { OverlayColor *r1 = row1; OverlayColor *r2 = row2; - for (x = 0; x < width; x += 2) { - register byte L; + for (x = width; x > 0; x -= 2) { + register OverlayColor *L; - cr_r = 0 * 768 + 256 + _colorTab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + _colorTab[*cb + 3 * 256]; + cr_r = _colorTab[*cr + 0 * 256]; + crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; + cb_b = _colorTab[*cb + 3 * 256]; ++cr; ++cb; - L = *lum++; - *r1++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum++]; + *r1++ = L[cr_r] | L[crb_g] | L[cb_b]; + + L = &_rgbToPix[*lum++]; + *r1++ = L[cr_r] | L[crb_g] | L[cb_b]; - L = *lum++; - *r1++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; - // Now, do second row. - L = *lum2++; - *r2++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum2++]; + *r2++ = L[cr_r] | L[crb_g] | L[cb_b]; - L = *lum2++; - *r2++ = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum2++]; + *r2++ = L[cr_r] | L[crb_g] | L[cb_b]; } lum += width; @@ -475,8 +473,6 @@ void BaseAnimationState::plotYUV1x(int width, int height, byte *const *dat) { } void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) { - OverlayColor *ptr = _overlay; - byte *lum = dat[0]; byte *cr = dat[2]; byte *cb = dat[1]; @@ -487,44 +483,44 @@ void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) { int16 crb_g; int16 cb_b; - OverlayColor *row1 = ptr; - OverlayColor *row2 = ptr + 2 * 2 * _movieWidth; + OverlayColor *row1 = _overlay; + OverlayColor *row2 = row1 + 2 * 2 * _movieWidth; - int x, y; + int x; - for (y = 0; y < height; y += 2) { + for (; height > 0; height -= 2) { OverlayColor *r1 = row1; OverlayColor *r2 = row2; - for (x = 0; x < width; x += 2) { - register byte L; - register OverlayColor C; + for (x = width; x > 0; x -= 2) { + register OverlayColor *L; + register OverlayColor C; - cr_r = 0 * 768 + 256 + _colorTab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + _colorTab[*cb + 3 * 256]; + cr_r = _colorTab[*cr + 0 * 256]; + crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; + cb_b = _colorTab[*cb + 3 * 256]; ++cr; ++cb; - L = *lum++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r1++ = C; *r1++ = C; - L = *lum++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r1++ = C; *r1++ = C; - + // Now, do second row. - L = *lum2++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum2++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r2++ = C; *r2++ = C; - L = *lum2++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum2++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r2++ = C; *r2++ = C; } @@ -540,8 +536,6 @@ void BaseAnimationState::plotYUV2x(int width, int height, byte *const *dat) { } void BaseAnimationState::plotYUV3x(int width, int height, byte *const *dat) { - OverlayColor *ptr = _overlay; - byte *lum = dat[0]; byte *cr = dat[2]; byte *cb = dat[1]; @@ -552,47 +546,47 @@ void BaseAnimationState::plotYUV3x(int width, int height, byte *const *dat) { int16 crb_g; int16 cb_b; - OverlayColor *row1 = ptr; - OverlayColor *row2 = ptr + 3 * 3 * _movieWidth; + OverlayColor *row1 = _overlay; + OverlayColor *row2 = row1 + 3 * 3 * _movieWidth; - int x, y; + int x; - for (y = 0; y < height; y += 2) { + for (; height > 0; height -= 2) { OverlayColor *r1 = row1; OverlayColor *r2 = row2; - for (x = 0; x < width; x += 2) { - register byte L; - register OverlayColor C; + for (x = width; x > 0; x -= 2) { + register OverlayColor *L; + register OverlayColor C; - cr_r = 0 * 768 + 256 + _colorTab[*cr + 0 * 256]; - crb_g = 1 * 768 + 256 + _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; - cb_b = 2 * 768 + 256 + _colorTab[*cb + 3 * 256]; + cr_r = _colorTab[*cr + 0 * 256]; + crb_g = _colorTab[*cr + 1 * 256] + _colorTab[*cb + 2 * 256]; + cb_b = _colorTab[*cb + 3 * 256]; ++cr; ++cb; - L = *lum++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r1++ = C; *r1++ = C; *r1++ = C; - L = *lum++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r1++ = C; *r1++ = C; *r1++ = C; - + // Now, do second row. - L = *lum2++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum2++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r2++ = C; *r2++ = C; *r2++ = C; - L = *lum2++; - C = _rgbToPix[L + cr_r] | _rgbToPix[L + crb_g] | _rgbToPix[L + cb_b]; + L = &_rgbToPix[*lum2++]; + C = L[cr_r] | L[crb_g] | L[cb_b]; *r2++ = C; *r2++ = C; *r2++ = C; diff --git a/gui/KeysDialog.cpp b/gui/KeysDialog.cpp index d196eab1be..db70f0dbfb 100644 --- a/gui/KeysDialog.cpp +++ b/gui/KeysDialog.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2001-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -31,16 +31,6 @@ namespace GUI { -/* -using GUI::ListWidget; -using GUI::kListNumberingZero; -using GUI::WIDGET_CLEARBG; -using GUI::kListSelectionChangedCmd; -using GUI::kCloseCmd; -using GUI::StaticTextWidget; -using GUI::CommandSender; -*/ - enum { kMapCmd = 'map ', kOKCmd = 'ok ' @@ -60,7 +50,7 @@ KeysDialog::KeysDialog(const Common::String &title) _actionsList->setNumberingMode(kListNumberingZero); _actionTitle = new StaticTextWidget(this, "keysdialog_action", title); - _keyMapping = new StaticTextWidget(this, "keysdialog_mapping", ""); + _keyMapping = new StaticTextWidget(this, "keysdialog_mapping", "Select an action and click 'Map'"); _actionTitle->setFlags(WIDGET_CLEARBG); _keyMapping->setFlags(WIDGET_CLEARBG); @@ -82,26 +72,26 @@ void KeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { case kListSelectionChangedCmd: if (_actionsList->getSelected() >= 0) { - char selection[100]; + char selection[100]; #ifdef __SYMBIAN32__ - uint16 key = Actions::Instance()->getMapping(_actionsList->getSelected()); - - if (key != 0) { - // ScummVM mappings for F1-F9 are different from SDL so remap back to sdl - if (key >= 315 && key <= 323) { - key = key - 315 + SDLK_F1; - } + uint16 key = Actions::Instance()->getMapping(_actionsList->getSelected()); + + if (key != 0) { + // ScummVM mappings for F1-F9 are different from SDL so remap back to sdl + if (key >= 315 && key <= 323) { + key = key - 315 + SDLK_F1; } + } - if (key != 0) - sprintf(selection, "Associated key : %s", SDL_GetKeyName((SDLKey)key)); - else - sprintf(selection, "Associated key : none"); + if (key != 0) + sprintf(selection, "Associated key : %s", SDL_GetKeyName((SDLKey)key)); + else + sprintf(selection, "Associated key : none"); #else - sprintf(selection, "Associated key : %s", CEDevice::getKeyName(Actions::Instance()->getMapping((ActionType)(_actionsList->getSelected()))).c_str()); + sprintf(selection, "Associated key : %s", CEDevice::getKeyName(Actions::Instance()->getMapping((ActionType)(_actionsList->getSelected()))).c_str()); #endif - _keyMapping->setLabel(selection); - _keyMapping->draw(); + _keyMapping->setLabel(selection); + _keyMapping->draw(); } break; case kMapCmd: @@ -109,29 +99,29 @@ void KeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { _actionTitle->setLabel("Please select an action"); } else { - char selection[100]; + char selection[100]; - _actionSelected = _actionsList->getSelected(); + _actionSelected = _actionsList->getSelected(); #ifdef __SYMBIAN32__ - uint16 key = Actions::Instance()->getMapping(_actionSelected); - if (key != 0) { - // ScummVM mappings for F1-F9 are different from SDL so remap back to sdl - if (key >= 315 && key <= 323) { - key = key - 315 + SDLK_F1; - } - - sprintf(selection, "Associated key : %s", SDL_GetKeyName((SDLKey)key)); + uint16 key = Actions::Instance()->getMapping(_actionSelected); + if (key != 0) { + // ScummVM mappings for F1-F9 are different from SDL so remap back to sdl + if (key >= 315 && key <= 323) { + key = key - 315 + SDLK_F1; } - else - sprintf(selection, "Associated key : none"); + + sprintf(selection, "Associated key : %s", SDL_GetKeyName((SDLKey)key)); + } + else + sprintf(selection, "Associated key : none"); #else - sprintf(selection, "Associated key : %s", CEDevice::getKeyName(Actions::Instance()->getMapping((ActionType)_actionSelected)).c_str()); + sprintf(selection, "Associated key : %s", CEDevice::getKeyName(Actions::Instance()->getMapping((ActionType)_actionSelected)).c_str()); #endif - _actionTitle->setLabel("Press the key to associate"); - _keyMapping->setLabel(selection); - _keyMapping->draw(); - Actions::Instance()->beginMapping(true); - _actionsList->setEnabled(false); + _actionTitle->setLabel("Press the key to associate"); + _keyMapping->setLabel(selection); + _keyMapping->draw(); + Actions::Instance()->beginMapping(true); + _actionsList->setEnabled(false); } _actionTitle->draw(); break; @@ -147,9 +137,9 @@ void KeysDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { } void KeysDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers){ - if (!Actions::Instance()->mappingActive()) { - Dialog::handleKeyDown(ascii,keycode,modifiers); - } + if (!Actions::Instance()->mappingActive()) { + Dialog::handleKeyDown(ascii,keycode,modifiers); + } } void KeysDialog::handleKeyUp(uint16 ascii, int keycode, int modifiers) { diff --git a/gui/TabWidget.cpp b/gui/TabWidget.cpp index dbeebc772c..a6b4eee8fb 100644 --- a/gui/TabWidget.cpp +++ b/gui/TabWidget.cpp @@ -71,6 +71,7 @@ void TabWidget::init() { } TabWidget::~TabWidget() { + _firstWidget = 0; for (uint i = 0; i < _tabs.size(); ++i) { delete _tabs[i].firstWidget; _tabs[i].firstWidget = 0; diff --git a/gui/browser.cpp b/gui/browser.cpp index 536cccdb4e..2d27e1f1ee 100644 --- a/gui/browser.cpp +++ b/gui/browser.cpp @@ -25,9 +25,8 @@ #include "gui/ListWidget.h" #include "common/config-manager.h" -#include "common/fs.h" #include "common/system.h" -#include "common/func.h" +#include "common/algorithm.h" namespace GUI { diff --git a/gui/credits.h b/gui/credits.h index e63509e025..3fb6396b78 100644 --- a/gui/credits.h +++ b/gui/credits.h @@ -27,6 +27,7 @@ static const char *credits[] = { "\\C\\c0""", "\\C\\c1""AGI", "\\C\\c0""Stuart George", +"\\C\\c0""Filippos Karapetis", "\\C\\c0""Pawel Kolodziejski", "\\C\\c0""Eugene Sandulenko", "\\C\\c0""David Symonds", @@ -49,10 +50,15 @@ static const char *credits[] = { "\\C\\c0""Jonathan Gray", "\\C\\c0""", "\\C\\c1""Cinematique evo 1", +"\\C\\c0""Vincent Hamm", +"\\C\\c2""original CinE engine author", "\\C\\c0""Pawel Kolodziejski", "\\C\\c0""Gregory Montoir", "\\C\\c0""Eugene Sandulenko", "\\C\\c0""", +"\\C\\c1""Cinematique evo 2", +"\\C\\c0""Vincent Hamm", +"\\C\\c0""", "\\C\\c1""FOTAQ", "\\C\\c0""David Eriksson", "\\C\\c0""Gregory Montoir", @@ -74,8 +80,12 @@ static const char *credits[] = { "\\C\\c1""Lure", "\\C\\c0""Paul Gilbert", "\\C\\c0""", +"\\C\\c1""Parallaction", +"\\C\\c0""peres", +"\\C\\c0""", "\\C\\c1""SAGA", "\\C\\c0""Torbj\366rn Andersson", +"\\C\\c0""Filippos Karapetis", "\\C\\c0""Andrew Kurushin", "\\C\\c0""Eugene Sandulenko", "\\C\\c0""", @@ -153,8 +163,6 @@ static const char *credits[] = { "\\C\\c2""Help with GUI implementation", "\\C\\c0""Jamieson Christian", "\\C\\c2""iMUSE, MIDI, all things musical", -"\\C\\c0""Vincent Hamm", -"\\C\\c2""Co-Founder, original CinE engine author", "\\C\\c0""R\374diger Hanke", "\\C\\c2""Port: MorphOS", "\\C\\c0""Felix Jakschitsch", @@ -260,6 +268,8 @@ static const char *credits[] = { "\\C\\c2""Daily Linux builds", "\\C\\c0""Thomas Mayer", "\\C\\c2""PSP port contributions", +"\\C\\c0""n0p", +"\\C\\c2""Windows CE port aspect ratio correction scaler and right click input method", "\\C\\c0""Mikesch Nepomuk", "\\C\\c2""MI1 VGA floppy patches", "\\C\\c0""Nicolas Noble", @@ -276,6 +286,8 @@ static const char *credits[] = { "\\C\\c2""SDL-based OpenGL renderer", "\\C\\c0""Tim Phillips", "\\C\\c2""Initial MI1 CD music support", +"\\C\\c0""Robin Watts", +"\\C\\c2""ARM assembly routines for the Windows CE port", "\\C\\c0""", "\\C\\c0""And to all the contributors, users, and beta testers we've missed. Thanks!", "\\C\\c0""", diff --git a/gui/dialog.cpp b/gui/dialog.cpp index e48602a95f..c0c8d50430 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -65,11 +65,6 @@ Dialog::Dialog(const Common::String &name, bool dimsInactive_) } } -Dialog::~Dialog() { - delete _firstWidget; - _firstWidget = 0; -} - int Dialog::runModal() { // Open up open(); diff --git a/gui/dialog.h b/gui/dialog.h index 7fe33fe3f4..098cf88278 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -54,7 +54,6 @@ private: public: Dialog(int x, int y, int w, int h, bool dimsInactive = true); Dialog(const Common::String &name, bool dimsInactive = true); - virtual ~Dialog(); virtual int runModal(); diff --git a/gui/newgui.cpp b/gui/newgui.cpp index 6d153a6b77..bd7315add5 100644 --- a/gui/newgui.cpp +++ b/gui/newgui.cpp @@ -32,8 +32,6 @@ #include "common/config-manager.h" -DECLARE_SINGLETON(GUI::NewGui); - namespace GUI { /* @@ -134,6 +132,7 @@ bool NewGui::loadNewTheme(const Common::String &style) { } delete _theme; + _theme = 0; if (style.compareToIgnoreCase("classic (builtin)") == 0) { _theme = new ThemeClassic(_system, style); diff --git a/gui/object.cpp b/gui/object.cpp index c93ee4bc9a..ec3167c9a3 100644 --- a/gui/object.cpp +++ b/gui/object.cpp @@ -31,10 +31,8 @@ GuiObject::GuiObject(const Common::String &name) : _firstWidget(0) { } GuiObject::~GuiObject() { -/* TODO: Enable this at some point? Right now it causes crashes delete _firstWidget; _firstWidget = 0; -*/ } uint32 GuiObject::getMillis() { diff --git a/gui/options.cpp b/gui/options.cpp index 3ad861de7b..c010587300 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -29,7 +29,7 @@ #include "gui/PopUpWidget.h" #include "gui/TabWidget.h" -#include "common/fs.h" +//#include "common/fs.h" #include "common/config-manager.h" #include "common/system.h" diff --git a/gui/theme-config.cpp b/gui/theme-config.cpp index 8e538f2021..72e71a0414 100644 --- a/gui/theme-config.cpp +++ b/gui/theme-config.cpp @@ -1,5 +1,5 @@ /* ScummVM - Scumm Interpreter - * Copyright (C) 2006 The ScummVM project + * Copyright (C) 2006-2007 The ScummVM project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -284,14 +284,15 @@ const char *Theme::_defaultConfigINI = "gameoptions_ok=(prev.x2 + 10) prev.y prev.w prev.h\n" "\n" "### keys dialog\n" -"keysdialog=(w / 20) (h / 10) (w - w / 10) (h - h / 5)\n" +"keysdialog=(w / 20) (h / 10) (w - w / 10) (h - h / 4)\n" "set_parent=keysdialog\n" -"keysdialog_map=(parent.w - buttonWidth - 10) 20 buttonWidth buttonHeight\n" +"keysdialog_map=(parent.w - buttonWidth - 10) (10 + 2 * kLineHeight) buttonWidth buttonHeight\n" "keysdialog_ok=prev.x (prev.y2 + 4) prev.w prev.h\n" "keysdialog_cancel=prev.x (prev.y2 + 4) prev.w prev.h\n" -"keysdialog_list=10 10 (prev.x - 20) (parent.h - kLineHeight * 4 - self.y)\n" -"keysdialog_action=prev.x (parent.h - kLineHeight * 3) (parent.w - self.x * 2) kLineHeight\n" -"keysdialog_mapping=prev.x (prev.y + kLineHeight) prev.w prev.h\n" +"keysdialog_action=10 10 (parent.w - 20) kLineHeight\n" +"keysdialog_action.align=kTextAlignCenter\n" +"keysdialog_list=prev.x (prev.y + 2 * kLineHeight) (parent.w - buttonWidth - 30) (parent.h - kLineHeight * 6)\n" +"keysdialog_mapping=prev.x (prev.y + prev.h + kLineHeight) (parent.w - buttonWidth - 20) kLineHeight\n" "\n" "### mass add dialog\n" "massadddialog=10 20 300 174\n" diff --git a/gui/theme.cpp b/gui/theme.cpp index a3f0cee510..446f746cf3 100644 --- a/gui/theme.cpp +++ b/gui/theme.cpp @@ -243,7 +243,8 @@ bool Theme::themeConfigUseable(const Common::String &stylefile, const Common::St } Common::String temp; - cfg->getKey("type", "theme", temp); + if (!cfg->getKey("type", "theme", temp)) + return false; if (cStyle) *cStyle = temp; if (0 != temp.compareToIgnoreCase(style) && !style.empty()) diff --git a/gui/theme.h b/gui/theme.h index 7f04063391..b8055819d5 100644 --- a/gui/theme.h +++ b/gui/theme.h @@ -183,7 +183,7 @@ public: break; }; return Graphics::kTextAlignCenter; - }; + } TextAlign convertAligment(Graphics::TextAlignment align) const { switch (align) { diff --git a/gui/themebrowser.cpp b/gui/themebrowser.cpp index 233220fa34..515c6d83f7 100644 --- a/gui/themebrowser.cpp +++ b/gui/themebrowser.cpp @@ -24,7 +24,6 @@ #include "gui/ListWidget.h" #include "gui/widget.h" #include "gui/theme.h" -#include "common/fs.h" #ifdef MACOSX #include "CoreFoundation/CoreFoundation.h" diff --git a/gui/widget.cpp b/gui/widget.cpp index a7bc7cc48b..dcf9156165 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -58,6 +58,7 @@ void Widget::resize(int x, int y, int w, int h) { Widget::~Widget() { delete _next; + _next = 0; } void Widget::draw() { diff --git a/sound/adpcm.cpp b/sound/adpcm.cpp index c6feb45aee..72564d7022 100644 --- a/sound/adpcm.cpp +++ b/sound/adpcm.cpp @@ -69,7 +69,7 @@ private: public: ADPCMInputStream(Common::SeekableReadStream *stream, uint32 size, typesADPCM type, int rate, int channels = 2, uint32 blockAlign = 0); - ~ADPCMInputStream() {}; + ~ADPCMInputStream() {} int readBuffer(int16 *buffer, const int numSamples); int readBufferOKI(int16 *buffer, const int numSamples); diff --git a/sound/aiff.cpp b/sound/aiff.cpp index 4942a66762..5d8d823756 100644 --- a/sound/aiff.cpp +++ b/sound/aiff.cpp @@ -46,7 +46,7 @@ uint32 readExtended(Common::SeekableReadStream &stream) { byte buf[10]; uint32 mantissa; - uint32 last; + uint32 last = 0; byte exp; stream.read(buf, 10); @@ -89,8 +89,8 @@ bool loadAIFFFromStream(Common::SeekableReadStream &stream, int &size, int &rate bool foundCOMM = false; bool foundSSND = false; - uint16 numChannels, bitsPerSample; - uint32 numSampleFrames, offset, blockSize, soundOffset; + uint16 numChannels = 0, bitsPerSample = 0; + uint32 numSampleFrames = 0, offset = 0, blockSize = 0, soundOffset = 0; while ((!foundCOMM || !foundSSND) && !stream.ioFailed()) { uint32 length, pos; diff --git a/sound/audiocd.cpp b/sound/audiocd.cpp index 44fb35a5ef..2635c2a0a6 100644 --- a/sound/audiocd.cpp +++ b/sound/audiocd.cpp @@ -23,6 +23,7 @@ #include "common/stdafx.h" #include "sound/audiocd.h" +#include "sound/audiostream.h" #include "sound/mp3.h" #include "sound/vorbis.h" #include "sound/flac.h" @@ -31,91 +32,76 @@ #include "common/util.h" #include "common/system.h" -DECLARE_SINGLETON(Audio::AudioCDManager); - namespace Audio { -struct TrackFormat { - /** Decodername */ - const char* decoderName; - /** - * Pointer to a function which tries to open the specified track - the only argument - * is the number of the track to be played. - * Returns either a DigitalTrackInfo object representing the requested track or null - * in case of an error - */ - DigitalTrackInfo* (*openTrackFunction)(int); -}; - -static const TrackFormat s_trackFormats[] = { - /* decoderName, openTrackFunction */ -#ifdef USE_FLAC - { "Flac", getFlacTrack }, -#endif -#ifdef USE_VORBIS - { "Ogg Vorbis", getVorbisTrack }, -#endif -#ifdef USE_MAD - { "MPEG Layer 3", getMP3Track }, -#endif - - { NULL, NULL } // Terminator -}; - - AudioCDManager::AudioCDManager() { - memset(_cachedTracks, 0, sizeof(_cachedTracks)); - memset(_trackInfo, 0, sizeof(_trackInfo)); _cd.playing = false; _cd.track = 0; _cd.start = 0; _cd.duration = 0; _cd.numLoops = 0; - _currentCacheIdx = 0; _mixer = g_system->getMixer(); assert(_mixer); } void AudioCDManager::play(int track, int numLoops, int startFrame, int duration) { if (numLoops != 0 || startFrame != 0) { - // Try to load the track from a .mp3/.ogg file, and if found, use - // that. If not found, attempt to do regular Audio CD playback of - // the requested track. - int index = getCachedTrack(track); - _cd.track = track; _cd.numLoops = numLoops; _cd.start = startFrame; _cd.duration = duration; - if (index >= 0) { - _mixer->stopHandle(_cd.handle); - _cd.playing = true; + // Try to load the track from a compressed data file, and if found, use + // that. If not found, attempt to start regular Audio CD playback of + // the requested track. + char trackName[2][16]; + sprintf(trackName[0], "track%d", track); + sprintf(trackName[1], "track%02d", track); + Audio::AudioStream *stream = 0; + + for (int i = 0; !stream && i < 2; ++i) { /* FIXME: Seems numLoops == 0 and numLoops == 1 both indicate a single repetition, while all other positive numbers indicate precisely the number of desired repetitions. Finally, -1 means infinitely many */ - numLoops = (numLoops < 1) ? numLoops + 1 : numLoops; - _trackInfo[index]->play(_mixer, &_cd.handle, numLoops, _cd.start, _cd.duration); + // We multiply by 40 / 3 = 1000 / 75 to convert frames to milliseconds + stream = AudioStream::openStreamFile(trackName[i], startFrame * 40 / 3, duration * 40 / 3, (numLoops < 1) ? numLoops + 1 : numLoops); + } + + // Stop any currently playing emulated track + _mixer->stopHandle(_cd.handle); + + // HACK: We abuse _cd.playing to store whether we are playing a real or an emulated track. + if (stream != 0) { + _cd.playing = true; + _mixer->playInputStream(Audio::Mixer::kMusicSoundType, &_cd.handle, stream); } else { - g_system->playCD(track, numLoops, startFrame, duration); _cd.playing = false; + g_system->playCD(track, numLoops, startFrame, duration); } } } void AudioCDManager::stop() { if (_cd.playing) { + // Audio CD emulation _mixer->stopHandle(_cd.handle); _cd.playing = false; } else { + // Real Audio CD g_system->stopCD(); } } bool AudioCDManager::isPlaying() const { - return _cd.playing || g_system->pollCD(); + if (_cd.playing) { + // Audio CD emulation + return _mixer->isSoundHandleActive(_cd.handle); + } else { + // Real Audio CD + return g_system->pollCD(); + } } void AudioCDManager::updateCD() { @@ -125,7 +111,8 @@ void AudioCDManager::updateCD() { // FIXME: We do not update the numLoops parameter here (and in fact, // currently can't do that). Luckily, only one engine ever checks // this part of the AudioCD status, namely the SCUMM engine; and it - // only checks + // only checks whether the track is currently set to infinite looping + // or not. _cd.playing = false; } } else { @@ -141,41 +128,4 @@ AudioCDManager::Status AudioCDManager::getStatus() const { return info; } -int AudioCDManager::getCachedTrack(int track) { - // See if we find the track in the cache - for (int i = 0; i < CACHE_TRACKS; i++) - if (_cachedTracks[i] == track) { - return _trackInfo[i] ? i : -1; - } - - // The track is not already in the cache. Try and see if - // we can load it. - DigitalTrackInfo *newTrack = 0; - for (const TrackFormat *format = s_trackFormats; - format->openTrackFunction != NULL && newTrack == NULL; - ++format) { - newTrack = format->openTrackFunction(track); - } - - int currentIndex = -1; - - if (newTrack != NULL) { - // We successfully loaded a digital track. Store it into _trackInfo. - - currentIndex = _currentCacheIdx++; - _currentCacheIdx %= CACHE_TRACKS; - - // First, delete the previous track info object - delete _trackInfo[currentIndex]; - - // Then, store the new track info object - _trackInfo[currentIndex] = newTrack; - _cachedTracks[currentIndex] = track; - } else { - debug(2, "Track %d not available in compressed format", track); - } - - return currentIndex; -} - } // End of namespace Audio diff --git a/sound/audiocd.h b/sound/audiocd.h index 23367ba262..281bf1b1b4 100644 --- a/sound/audiocd.h +++ b/sound/audiocd.h @@ -32,15 +32,6 @@ namespace Audio { -class DigitalTrackInfo { -public: - virtual ~DigitalTrackInfo() {} - - virtual void play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration) = 0; -// virtual void stop(); -}; - - class AudioCDManager : public Common::Singleton<AudioCDManager> { public: struct Status { @@ -73,27 +64,12 @@ private: friend class Common::Singleton<SingletonBaseType>; AudioCDManager(); - int getCachedTrack(int track); - -private: /* used for emulated CD music */ struct ExtStatus : Status { SoundHandle handle; }; ExtStatus _cd; - enum { -#if defined(__PSP__) - CACHE_TRACKS = 4 //the PSP can't have more than 8 files open simultaneously - //so don't use more than 4 filehandles for CD tracks -#else - CACHE_TRACKS = 10 -#endif - }; - int _cachedTracks[CACHE_TRACKS]; - DigitalTrackInfo *_trackInfo[CACHE_TRACKS]; - int _currentCacheIdx; - Mixer *_mixer; }; diff --git a/sound/flac.cpp b/sound/flac.cpp index 61e8800c31..215ccee26e 100644 --- a/sound/flac.cpp +++ b/sound/flac.cpp @@ -770,96 +770,6 @@ AudioStream *makeFlacStream( return input; } - -#pragma mark - -#pragma mark --- Flac Audio CD emulation --- -#pragma mark - - - -class FlacTrackInfo : public DigitalTrackInfo { -private: - Common::String _filename; - bool _errorFlag; - -public: - FlacTrackInfo(const char *filename); - bool error() { return _errorFlag; } - void play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration); -}; - -FlacTrackInfo::FlacTrackInfo(const char *filename) : - _filename(filename), - _errorFlag(false) { - - // Try to open the file - Common::File file; - if (!file.open(_filename)) { - _errorFlag = true; - return; - } - - // Next, try to create a FlacInputStream from it - FlacInputStream *tempStream = new FlacInputStream(&file, false); - - // If initialising the stream fails, we set the error flag - if (!tempStream || !tempStream->isStreamDecoderReady()) - _errorFlag = true; - - delete tempStream; -} - -void FlacTrackInfo::play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration) { - assert(!_errorFlag); - - if (error()) { - debug(1, "FlacTrackInfo::play: invalid state, method should not been called"); - } - - // Open the file - Common::File *file = new Common::File(); - if (!file || !file->open(_filename)) { - warning("FlacTrackInfo::play: failed to open '%s'", _filename.c_str()); - delete file; - return; - } - - // Convert startFrame & duration from frames (1/75 s) to milliseconds (1/1000s) - uint start = startFrame * 1000 / 75; - uint end = duration ? ((startFrame + duration) * 1000 / 75) : 0; - - // ... create an AudioStream ... - FlacInputStream *input = new FlacInputStream(file, true, start, end, numLoops); - if (!input->isStreamDecoderReady()) { - delete input; - return; - } - - // ... and play it - mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input); -} - -DigitalTrackInfo* getFlacTrack(int track) { - assert(track >= 1); - char trackName[4][32]; - - sprintf(trackName[0], "track%d.flac", track); - sprintf(trackName[1], "track%02d.flac", track); - sprintf(trackName[2], "track%d.fla", track); - sprintf(trackName[3], "track%02d.fla", track); - - for (int i = 0; i < 4; ++i) { - if (Common::File::exists(trackName[i])) { - FlacTrackInfo *trackInfo = new FlacTrackInfo(trackName[i]); - if (!trackInfo->error()) - return trackInfo; - delete trackInfo; - } - } - - return NULL; -} - - } // End of namespace Audio #endif // #ifdef USE_FLAC diff --git a/sound/flac.h b/sound/flac.h index 787a8ad79c..4b4acb3228 100644 --- a/sound/flac.h +++ b/sound/flac.h @@ -36,9 +36,6 @@ namespace Common { namespace Audio { class AudioStream; -class DigitalTrackInfo; - -DigitalTrackInfo *getFlacTrack(int track); /** * Create a new AudioStream from the FLAC data in the given diff --git a/sound/iff.cpp b/sound/iff.cpp new file mode 100644 index 0000000000..2fd6378b13 --- /dev/null +++ b/sound/iff.cpp @@ -0,0 +1,80 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "sound/iff.h" +#include "sound/audiostream.h" +#include "sound/mixer.h" + +namespace Audio { + + +void A8SVXDecoder::readVHDR(Common::IFFChunk &chunk) { + _header.oneShotHiSamples = chunk.readUint32BE(); + _header.repeatHiSamples = chunk.readUint32BE(); + _header.samplesPerHiCycle = chunk.readUint32BE(); + _header.samplesPerSec = chunk.readUint16BE(); + _header.octaves = chunk.readByte(); + _header.compression = chunk.readByte(); + _header.volume = chunk.readUint32BE(); +} + +void A8SVXDecoder::readBODY(Common::IFFChunk &chunk) { + + switch (_header.compression) { + case 0: + _dataSize = chunk.size; + _data = (byte*)malloc(_dataSize); + chunk.read(_data, _dataSize); + break; + + case 1: + warning("compressed IFF audio is not supported"); + break; + } + +} + + +A8SVXDecoder::A8SVXDecoder(Common::ReadStream &input, Voice8Header &header, byte *&data, uint32 &dataSize) : + IFFParser(input), _header(header), _data(data), _dataSize(dataSize) { + if (_typeId != ID_8SVX) + error("unknown audio format"); +} + +void A8SVXDecoder::decode() { + + Common::IFFChunk *chunk; + + while ((chunk = nextChunk()) != 0) { + switch (chunk->id) { + case ID_VHDR: + readVHDR(*chunk); + break; + + case ID_BODY: + readBODY(*chunk); + break; + } + } +} + +} diff --git a/sound/iff.h b/sound/iff.h new file mode 100644 index 0000000000..592cf9c2f0 --- /dev/null +++ b/sound/iff.h @@ -0,0 +1,73 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2006 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SOUND_IFF_H +#define SOUND_IFF_H + +#include "common/iff_container.h" + +namespace Audio { + +struct Voice8Header { + uint32 oneShotHiSamples; + uint32 repeatHiSamples; + uint32 samplesPerHiCycle; + uint16 samplesPerSec; + byte octaves; + byte compression; + uint32 volume; + + Voice8Header() { + memset(this, 0, sizeof(Voice8Header)); + } +}; + + +/* + A8SVX decoder reads 8SVX subtype of IFF files. + + TODO: make a factory function for this kind of stream? + */ +class A8SVXDecoder : public Common::IFFParser { + +protected: + Voice8Header &_header; + byte* &_data; + uint32 &_dataSize; + +protected: + void readVHDR(Common::IFFChunk &chunk); + void readBODY(Common::IFFChunk &chunk); + +public: + A8SVXDecoder(Common::ReadStream &input, Voice8Header &header, byte *&data, uint32 &dataSize); + void decode(); +}; + + +/* + TODO: Implement a parser for AIFF subtype. + */ + +} + +#endif diff --git a/sound/mixer.h b/sound/mixer.h index 5dfef06090..a0a7c93aed 100644 --- a/sound/mixer.h +++ b/sound/mixer.h @@ -132,7 +132,7 @@ public: * * @return whether the mixer is ready and setup */ - bool isReady() const { return _mixerReady; }; + bool isReady() const { return _mixerReady; } diff --git a/sound/mods/paula.h b/sound/mods/paula.h index 134ea8f845..b0c9bc96b8 100644 --- a/sound/mods/paula.h +++ b/sound/mods/paula.h @@ -41,7 +41,7 @@ public: ~Paula(); bool playing() const { return _playing; } - void setInterruptFreq(int freq) { _intFreq = freq; } + void setInterruptFreq(int freq) { _curInt = _intFreq = freq; } void setPanning(byte voice, byte panning) { assert(voice < NUM_VOICES); _voice[voice].panning = panning; @@ -86,7 +86,7 @@ protected: } else *buf++ += tmp; } - virtual void interrupt(void) {}; + virtual void interrupt(void) {} }; } // End of namespace Audio diff --git a/sound/mods/protracker.h b/sound/mods/protracker.h index 939b336b2f..7fefddd20c 100644 --- a/sound/mods/protracker.h +++ b/sound/mods/protracker.h @@ -31,6 +31,17 @@ namespace Audio { class AudioStream; +/* + * Factory function for ProTracker streams. Reads all data from the + * given ReadStream and creates an AudioStream from this. No reference + * to the 'stream' object is kept, so you can safely delete it after + * invoking this factory. + * + * @param stream the ReadStream from which to read the ProTracker data + * @param rate TODO + * @param stereo TODO + * @return a new AudioStream, or NULL, if an error occured + */ AudioStream *makeProtrackerStream(Common::ReadStream *stream, int rate = 44100, bool stereo = true); } // End of namespace Audio diff --git a/sound/mods/soundfx.cpp b/sound/mods/soundfx.cpp new file mode 100644 index 0000000000..27e596ac3b --- /dev/null +++ b/sound/mods/soundfx.cpp @@ -0,0 +1,306 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "sound/mods/paula.h" +#include "sound/mods/soundfx.h" +#include "sound/audiostream.h" + +namespace Audio { + +struct SoundFxInstrument { + char name[23]; + uint16 len; + uint8 finetune; + uint8 volume; + uint16 repeatPos; + uint16 repeatLen; + int8 *data; +}; + +class SoundFx : public Paula { +public: + + enum { + NUM_CHANNELS = 4, + NUM_INSTRUMENTS = 15, + CIA_FREQ = 715909 + }; + + SoundFx(int rate, bool stereo); + virtual ~SoundFx(); + + bool load(Common::SeekableReadStream *data, LoadSoundFxInstrumentCallback loadCb); + void play(); + +protected: + + void handlePattern(int ch, uint32 pat); + void updateEffects(int ch); + void handleTick(); + + void startPaula(); + void stopPaula(); + void setPaulaChannelPeriod(uint8 channel, int16 period); + void setPaulaChannelVolume(uint8 channel, uint8 volume); + void enablePaulaChannel(uint8 channel); + void disablePaulaChannel(uint8 channel); + void setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen); + + virtual void interrupt(); + + uint8 _ticks; + uint16 _delay; + SoundFxInstrument _instruments[NUM_INSTRUMENTS]; + uint8 _numOrders; + uint8 _curOrder; + uint16 _curPos; + uint8 _ordersTable[128]; + uint8 *_patternData; + int _eventsFreq; + uint16 _effects[NUM_CHANNELS]; +}; + +SoundFx::SoundFx(int rate, bool stereo) + : Paula(stereo, rate) { + _ticks = 0; + _delay = 0; + memset(_instruments, 0, sizeof(_instruments)); + _numOrders = 0; + _curOrder = 0; + _curPos = 0; + memset(_ordersTable, 0, sizeof(_ordersTable)); + _patternData = 0; + _eventsFreq = 0; + memset(_effects, 0, sizeof(_effects)); +} + +SoundFx::~SoundFx() { + free(_patternData); + for (int i = 0; i < NUM_INSTRUMENTS; ++i) { + free(_instruments[i].data); + } +} + +bool SoundFx::load(Common::SeekableReadStream *data, LoadSoundFxInstrumentCallback loadCb) { + int instrumentsSize[15]; + if (!loadCb) { + for (int i = 0; i < NUM_INSTRUMENTS; ++i) { + instrumentsSize[i] = data->readUint32BE(); + } + } + uint8 tag[4]; + data->read(tag, 4); + if (memcmp(tag, "SONG", 4) != 0) { + return false; + } + _delay = data->readUint16BE(); + data->skip(7 * 2); + for (int i = 0; i < NUM_INSTRUMENTS; ++i) { + SoundFxInstrument *ins = &_instruments[i]; + data->read(ins->name, 22); ins->name[22] = 0; + ins->len = data->readUint16BE(); + ins->finetune = data->readByte(); + ins->volume = data->readByte(); + ins->repeatPos = data->readUint16BE(); + ins->repeatLen = data->readUint16BE(); + } + _numOrders = data->readByte(); + data->skip(1); + data->read(_ordersTable, 128); + int maxOrder = 0; + for (int i = 0; i < _numOrders; ++i) { + if (_ordersTable[i] > maxOrder) { + maxOrder = _ordersTable[i]; + } + } + int patternSize = (maxOrder + 1) * 4 * 4 * 64; + _patternData = (uint8 *)malloc(patternSize); + if (!_patternData) { + return false; + } + data->read(_patternData, patternSize); + for (int i = 0; i < NUM_INSTRUMENTS; ++i) { + SoundFxInstrument *ins = &_instruments[i]; + if (!loadCb) { + if (instrumentsSize[i] != 0) { + assert(ins->len <= 1 || ins->len * 2 <= instrumentsSize[i]); + assert(ins->repeatLen <= 1 || (ins->repeatPos + ins->repeatLen) * 2 <= instrumentsSize[i]); + ins->data = (int8 *)malloc(instrumentsSize[i]); + if (!ins->data) { + return false; + } + data->read(ins->data, instrumentsSize[i]); + } + } else { + if (ins->name[0]) { + ins->name[8] = '\0'; + ins->data = (int8 *)(*loadCb)(ins->name, 0); + if (!ins->data) { + return false; + } + } + } + } + return true; +} + +void SoundFx::play() { + _curPos = 0; + _curOrder = 0; + _ticks = 0; + _eventsFreq = CIA_FREQ / _delay; + setInterruptFreq(_rate / _eventsFreq); + startPaula(); +} + +void SoundFx::handlePattern(int ch, uint32 pat) { + uint16 note1 = pat >> 16; + uint16 note2 = pat & 0xFFFF; + if (note1 != 0xFFFD) { + int ins = (note2 & 0xF000) >> 12; + if (ins != 0) { + SoundFxInstrument *i = &_instruments[ins - 1]; + setupPaulaChannel(ch, i->data, i->len, i->repeatPos, i->repeatLen); + int effect = (note2 & 0xF00) >> 8; + int volume = i->volume; + switch (effect) { + case 5: // volume up + volume += (note2 & 0xFF); + if (volume > 63) { + volume = 63; + } + break; + case 6: // volume down + volume -= (note2 & 0xFF); + if (volume < 0) { + volume = 0; + } + break; + } + setPaulaChannelVolume(ch, volume); + } + } + _effects[ch] = note2; + if (note1 == 0xFFFD) { // PIC + _effects[ch] = 0; + } else if (note1 == 0xFFFE) { // STP + disablePaulaChannel(ch); + } else if (note1 != 0) { + setPaulaChannelPeriod(ch, note1); + enablePaulaChannel(ch); + } +} + +void SoundFx::updateEffects(int ch) { + // updateEffects() is a no-op in all Delphine Software games using SoundFx : FW,OS,Cruise,AW + if (_effects[ch] != 0) { + switch (_effects[ch]) { + case 1: // appreggiato + case 2: // pitchbend + case 3: // ledon, enable low-pass filter + case 4: // ledoff, disable low-pass filter + case 7: // set step up + case 8: // set step down + warning("Unhandled effect %d\n", _effects[ch]); + break; + } + } +} + +void SoundFx::handleTick() { + ++_ticks; + if (_ticks != 6) { + for (int ch = 0; ch < 4; ++ch) { + updateEffects(ch); + } + } else { + _ticks = 0; + const uint8 *patternData = _patternData + _ordersTable[_curOrder] * 1024 + _curPos; + for (int ch = 0; ch < 4; ++ch) { + handlePattern(ch, READ_BE_UINT32(patternData)); + patternData += 4; + } + _curPos += 4 * 4; + if (_curPos >= 1024) { + _curPos = 0; + ++_curOrder; + if (_curOrder == _numOrders) { + stopPaula(); + } + } + } +} + +void SoundFx::startPaula() { + _playing = true; + _end = false; +} + +void SoundFx::stopPaula() { + _playing = false; + _end = true; +} + +void SoundFx::setPaulaChannelPeriod(uint8 channel, int16 period) { + _voice[channel].period = period; +} + +void SoundFx::setPaulaChannelVolume(uint8 channel, uint8 volume) { + _voice[channel].volume = volume; +} + +void SoundFx::enablePaulaChannel(uint8 channel) { +} + +void SoundFx::disablePaulaChannel(uint8 channel) { + _voice[channel].period = 0; +} + +void SoundFx::setupPaulaChannel(uint8 channel, const int8 *data, uint16 len, uint16 repeatPos, uint16 repeatLen) { + if (data && len > 1) { + Channel *ch = &_voice[channel]; + ch->data = data; + ch->dataRepeat = data + repeatPos * 2; + ch->length = len * 2; + ch->lengthRepeat = repeatLen * 2; + ch->offset = 0; + } +} + +void SoundFx::interrupt() { + handleTick(); +} + +AudioStream *makeSoundFxStream(Common::SeekableReadStream *data, LoadSoundFxInstrumentCallback loadCb, int rate, bool stereo) { + SoundFx *stream = new SoundFx(rate, stereo); + if (stream->load(data, loadCb)) { + stream->play(); + return stream; + } + delete stream; + return 0; +} + +} // End of namespace Audio diff --git a/sound/mods/soundfx.h b/sound/mods/soundfx.h new file mode 100644 index 0000000000..353aa6ecdc --- /dev/null +++ b/sound/mods/soundfx.h @@ -0,0 +1,39 @@ + +/* ScummVM - Scumm Interpreter + * Copyright (C) 2007 The ScummVM project + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef SOUND_MODS_SOUNDFX_H +#define SOUND_MODS_SOUNDFX_H + +#include "common/stream.h" + +namespace Audio { + +class AudioStream; + +typedef byte *(*LoadSoundFxInstrumentCallback)(const char *name, uint32 *size); + +AudioStream *makeSoundFxStream(Common::SeekableReadStream *data, LoadSoundFxInstrumentCallback loadCb, int rate = 44100, bool stereo = true); + +} // End of namespace Audio + +#endif diff --git a/sound/module.mk b/sound/module.mk index dce7ace08e..a204dbadb9 100644 --- a/sound/module.mk +++ b/sound/module.mk @@ -5,6 +5,7 @@ MODULE_OBJS := \ aiff.o \ audiocd.o \ audiostream.o \ + iff.o \ flac.o \ fmopl.o \ mididrv.o \ @@ -24,6 +25,7 @@ MODULE_OBJS := \ mods/protracker.o \ mods/paula.o \ mods/rjp1.o \ + mods/soundfx.o \ softsynth/adlib.o \ softsynth/ym2612.o \ softsynth/fluidsynth.o \ diff --git a/sound/mp3.cpp b/sound/mp3.cpp index ff0e3d61dd..f9efdc4e8c 100644 --- a/sound/mp3.cpp +++ b/sound/mp3.cpp @@ -339,93 +339,6 @@ AudioStream *makeMP3Stream( return new MP3InputStream(stream, disposeAfterUse, start, end, numLoops); } - -#pragma mark - -#pragma mark --- MP3 Audio CD emulation --- -#pragma mark - - - -class MP3TrackInfo : public DigitalTrackInfo { -private: - Common::String _filename; - bool _errorFlag; - -public: - MP3TrackInfo(const char *filename); - bool error() { return _errorFlag; } - void play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration); -}; - -MP3TrackInfo::MP3TrackInfo(const char *filename) : - _filename(filename), - _errorFlag(false) { - - // Try to open the file - Common::File file; - if (!file.open(_filename)) { - _errorFlag = true; - return; - } - - // Next, try to create an MP3InputStream from it - MP3InputStream *tempStream = new MP3InputStream(&file, false); - - // If we see EOS here then that means that not (enough) valid input - // data was given. - _errorFlag = tempStream->endOfData(); - - // Clean up again - delete tempStream; -} - -void MP3TrackInfo::play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration) { - assert(!_errorFlag); - - mad_timer_t start; - mad_timer_t end; - - // Both startFrame and duration are given in frames, where 75 frames are one second. - // Calculate the appropriate mad_timer_t values from them. - mad_timer_set(&start, startFrame / 75, startFrame % 75, 75); - if (duration == 0) { - end = mad_timer_zero; - } else { - int endFrame = startFrame + duration; - mad_timer_set(&end, endFrame / 75, endFrame % 75, 75); - } - - // Open the file - Common::File *file = new Common::File(); - if (!file || !file->open(_filename)) { - warning("MP3TrackInfo::play: failed to open '%s'", _filename.c_str()); - delete file; - return; - } - - // ... create an AudioStream ... - MP3InputStream *input = new MP3InputStream(file, true, start, end, numLoops); - - // ... and play it - mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input); -} - -DigitalTrackInfo *getMP3Track(int track) { - char trackName[2][32]; - - sprintf(trackName[0], "track%d.mp3", track); - sprintf(trackName[1], "track%02d.mp3", track); - - for (int i = 0; i < 2; ++i) { - if (Common::File::exists(trackName[i])) { - MP3TrackInfo *trackInfo = new MP3TrackInfo(trackName[i]); - if (!trackInfo->error()) - return trackInfo; - delete trackInfo; - } - } - return NULL; -} - } // End of namespace Audio #endif // #ifdef USE_MAD diff --git a/sound/mp3.h b/sound/mp3.h index 354e880404..d4992ce10f 100644 --- a/sound/mp3.h +++ b/sound/mp3.h @@ -36,9 +36,6 @@ namespace Common { namespace Audio { class AudioStream; -class DigitalTrackInfo; - -DigitalTrackInfo *getMP3Track(int track); /** * Create a new AudioStream from the MP3 data in the given diff --git a/sound/softsynth/ym2612.cpp b/sound/softsynth/ym2612.cpp index 5ee864b168..e48f44ebc0 100644 --- a/sound/softsynth/ym2612.cpp +++ b/sound/softsynth/ym2612.cpp @@ -90,15 +90,15 @@ void Operator2612::setInstrument(byte const *instrument) { _specifiedSustainRate = instrument[24] & 31; _specifiedSustainLevel = (instrument[28] >> 4) & 15; _specifiedReleaseRate = instrument[28] & 15; - _state = _s_ready; // 本物ではどうなのかな? + _state = _s_ready; velocity(_velocity); } void Operator2612::keyOn() { _state = _s_attacking; _tickCount = 0; - _phase = 0; // どうも、実際こうらしい - _currentLevel = ((int32)0x7f << 15); // これも、実際こうらしい + _phase = 0; + _currentLevel = ((int32)0x7f << 15); } void Operator2612::keyOff() { @@ -116,7 +116,7 @@ void Operator2612::frequency(int freq) { if (r != 0) { r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); if (r >= 64) - r = 63; // するべきなんだろうとは思うんだけど (赤p.207) + r = 63; } r = 63 - r; @@ -125,7 +125,7 @@ void Operator2612::frequency(int freq) { else { value = powtbl[(r&3) << 7]; value *= 1 << (r >> 2); - value *= 41; // r == 20 のとき、0-96[db] が 10.01[ms] == 41.00096 + value *= 41; value /= 1 << (15 + 5); value *= 127 - _specifiedTotalLevel; value /= 127; @@ -156,7 +156,7 @@ void Operator2612::frequency(int freq) { if (r != 0) { r = r * 2 + 1; // (Translated) I cannot know whether the timing is a good choice or not r = r * 2 + (keyscaleTable[freq/262205] >> (3-_keyScale)); - // KS による補正はあるらしい。赤p.206 では記述されてないけど。 + // KS if (r >= 64) r = 63; } @@ -229,11 +229,11 @@ void Operator2612::nextTick(const int *phasebuf, int *outbuf, int buflen) { } if (level < zero_level) { - int phaseShift = *phasebuf >> 2; // 正しい変調量は? 3 じゃ小さすぎで 2 じゃ大きいような。 + int phaseShift = *phasebuf >> 2; if (_feedbackLevel) phaseShift += (output << (_feedbackLevel - 1)) / 1024; output = sintbl[((_phase >> 7) + phaseShift) & 0x7ff]; - output >>= (level >> 18); // 正しい減衰量は? + output >>= (level >> 18); // Here is the original code, which requires 64-bit ints // output *= powtbl[511 - ((level>>25)&511)]; // output >>= 16; @@ -438,13 +438,13 @@ void Voice2612::pitchBend(int value) { } void Voice2612::recalculateFrequency() { - // MIDI とも違うし.... - // どういう仕様なんだろうか? - // と思ったら、なんと、これ (↓) が正解らしい。 + // + // + // int32 basefreq = frequencyTable[_note]; int cfreq = frequencyTable[_note - (_note % 12)]; int oct = _note / 12; - int fnum = (int) (((double)basefreq * (1 << 13)) / cfreq); // OPL の fnum と同じようなもの。 + int fnum = (int) (((double)basefreq * (1 << 13)) / cfreq); fnum += _frequencyOffs - 0x2000; if (fnum < 0x2000) { fnum += 0x2000; @@ -455,7 +455,7 @@ void Voice2612::recalculateFrequency() { oct++; } - // _frequency は最終的にバイアス 256*1024 倍 + // _frequency = (int) ((frequencyTable[oct*12] * (double)fnum) / 8); int i; @@ -515,7 +515,7 @@ void MidiChannel_YM2612::noteOff(byte note) { } void MidiChannel_YM2612::controlChange(byte control, byte value) { - // いいのかこれで? + // if (control == 121) { // Reset controller removeAllVoices(); @@ -537,7 +537,7 @@ void MidiChannel_YM2612::sysEx_customInstrument(uint32 type, const byte *fmInst) } void MidiChannel_YM2612::pitchBend(int16 value) { - // いいのかこれで? + // Voice2612 *voice = _voices; for (; voice; voice = voice->next) voice->pitchBend(value); @@ -696,8 +696,8 @@ void MidiDriver_YM2612::createLookupTables() { 0x03d5, 0x0410, 0x044e, 0x048f, }; - // (int)(880.0 * 256.0 * pow(2.0, (note-0x51)/12.0)); // バイアス 256 倍 - // 0x45 が 440Hz (a4)、0x51 が 880Hz (a5) らしい + // (int)(880.0 * 256.0 * pow(2.0, (note-0x51)/12.0)) + // frequencyTable = new int [120]; for (block = -1; block < 9; block++) { for (i = 0; i < 12; i++) { @@ -707,7 +707,7 @@ void MidiDriver_YM2612::createLookupTables() { } keycodeTable = new int [120]; - // detune 量の計算や KS による rate 変換に使うんじゃないかな + // detune for (block = -1; block < 9; block++) { for (i = 0; i < 12; i++) { // see p.204 @@ -730,7 +730,7 @@ void MidiDriver_YM2612::createLookupTables() { keyscaleTable[0] = 0; for (freq = 1; freq < 8192; freq++) { keyscaleTable[freq] = (int)(log((double)freq) / 9.03 * 32.0) - 1; - // 8368[Hz] (o9c) で 32くらい。9.03 =:= ln 8368 + // 8368[Hz] (o9c) } } diff --git a/sound/vorbis.cpp b/sound/vorbis.cpp index 9b88020974..7e9d9dc286 100644 --- a/sound/vorbis.cpp +++ b/sound/vorbis.cpp @@ -293,86 +293,6 @@ AudioStream *makeVorbisStream( } -#pragma mark - -#pragma mark --- Ogg Vorbis Audio CD emulation --- -#pragma mark - - - -class VorbisTrackInfo : public DigitalTrackInfo { -private: - Common::String _filename; - bool _errorFlag; - -public: - VorbisTrackInfo(const char *filename); - bool error() { return _errorFlag; } - void play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration); -}; - -VorbisTrackInfo::VorbisTrackInfo(const char *filename) : - _filename(filename), - _errorFlag(false) { - - - // Try to open the file - Common::File file; - if (!file.open(_filename)) { - _errorFlag = true; - return; - } - - // Next, try to create a VorbisInputStream from it - VorbisInputStream *tempStream = new VorbisInputStream(&file, false); - - // If an error occured... - // TODO: add an error or init method to VorbisInputStream - _errorFlag = tempStream->endOfData(); - - // Clean up again - delete tempStream; -} - -void VorbisTrackInfo::play(Mixer *mixer, SoundHandle *handle, int numLoops, int startFrame, int duration) { - assert(!_errorFlag); - - // Open the file - Common::File *file = new Common::File(); - if (!file || !file->open(_filename)) { - warning("VorbisTrackInfo::play: failed to open '%s'", _filename.c_str()); - delete file; - return; - } - - // Convert startFrame & duration from frames (1/75 s) to milliseconds (1/1000s), - // i.e. multiply with a factor of 1000/75 = 40/3. - uint start = startFrame * 40 / 3; - uint end = duration ? ((startFrame + duration) * 40 / 3) : 0; - - // ... create an AudioStream ... - VorbisInputStream *input = new VorbisInputStream(file, true, start, end, numLoops); - - // ... and play it - mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input); -} - -DigitalTrackInfo *getVorbisTrack(int track) { - char trackName[2][32]; - - sprintf(trackName[0], "track%d.ogg", track); - sprintf(trackName[1], "track%02d.ogg", track); - - for (int i = 0; i < 2; ++i) { - if (Common::File::exists(trackName[i])) { - VorbisTrackInfo *trackInfo = new VorbisTrackInfo(trackName[i]); - if (!trackInfo->error()) - return trackInfo; - delete trackInfo; - } - } - return NULL; -} - - } // End of namespace Audio #endif // #ifdef USE_VORBIS diff --git a/sound/vorbis.h b/sound/vorbis.h index 9d702172df..88ef913360 100644 --- a/sound/vorbis.h +++ b/sound/vorbis.h @@ -36,9 +36,6 @@ namespace Common { namespace Audio { class AudioStream; -class DigitalTrackInfo; - -DigitalTrackInfo *getVorbisTrack(int track); /** * Create a new AudioStream from the Ogg Vorbis data in the given diff --git a/test/common/array.h b/test/common/array.h index f83c3bf0ea..8e1c53b430 100644 --- a/test/common/array.h +++ b/test/common/array.h @@ -59,4 +59,83 @@ class ArrayTestSuite : public CxxTest::TestSuite TS_ASSERT( array[1] == 33 ); TS_ASSERT( array[2] == -11 ); } + + void test_insert_at( void ) + { + Common::Array<int> array; + + // First of all some data + array.push_back(-12); + array.push_back(17); + array.push_back(25); + array.push_back(-11); + + // Insert some data + array.insert_at(2, 33); + + TS_ASSERT( array[0] == -12 ); + TS_ASSERT( array[1] == 17 ); + TS_ASSERT( array[2] == 33 ); + TS_ASSERT( array[3] == 25 ); + TS_ASSERT( array[4] == -11 ); + } + + void test_remove_at( void ) + { + Common::Array<int> array; + + // First of all some data + array.push_back(-12); + array.push_back(17); + array.push_back(33); + array.push_back(25); + array.push_back(-11); + + // Remove some data + array.remove_at(1); + + TS_ASSERT( array[0] == -12 ); + TS_ASSERT( array[1] == 33 ); + TS_ASSERT( array[2] == 25 ); + TS_ASSERT( array[3] == -11 ); + } + + void test_push_back( void ) + { + Common::Array<int> array1, array2; + + // Some data for both + array1.push_back(-3); + array1.push_back(5); + array1.push_back(9); + + array2.push_back(3); + array2.push_back(-2); + array2.push_back(-131); + + array1.push_back(array2); + + TS_ASSERT( array1[0] == -3 ); + TS_ASSERT( array1[1] == 5 ); + TS_ASSERT( array1[2] == 9 ); + TS_ASSERT( array1[3] == 3 ); + TS_ASSERT( array1[4] == -2 ); + TS_ASSERT( array1[5] == -131 ); + } + + void test_copy_constructor( void ) + { + Common::Array<int> array1; + + // Some data for both + array1.push_back(-3); + array1.push_back(5); + array1.push_back(9); + + Common::Array<int> array2(array1); + + TS_ASSERT( array2[0] == -3 ); + TS_ASSERT( array2[1] == 5 ); + TS_ASSERT( array2[2] == 9 ); + } }; diff --git a/test/common/str.h b/test/common/str.h index 8b7b966935..2691a5420d 100644 --- a/test/common/str.h +++ b/test/common/str.h @@ -109,6 +109,15 @@ class StringTestSuite : public CxxTest::TestSuite TS_ASSERT_EQUALS( str.hasSuffix("hahah"), false ); } + void test_contains( void ) + { + Common::String str("this/is/a/test, haha"); + TS_ASSERT_EQUALS( str.contains(""), true ); + TS_ASSERT_EQUALS( str.contains("haha"), true ); + TS_ASSERT_EQUALS( str.contains("hahb"), false ); + TS_ASSERT_EQUALS( str.contains("test"), true ); + } + void test_toLowercase( void ) { Common::String str("Test it, NOW! 42"); diff --git a/tools/create_lure/create_lure_dat.cpp b/tools/create_lure/create_lure_dat.cpp index b1c81830b9..109b4f268b 100644 --- a/tools/create_lure/create_lure_dat.cpp +++ b/tools/create_lure/create_lure_dat.cpp @@ -269,7 +269,8 @@ void read_hotspot_data(byte *&data, uint16 &totalSize) r->scriptLoadFlag = entry.scriptLoadFlag; r->loadOffset = entry.loadOffset; r->colourOffset = entry.colourOffset; - r->sequenceOffset = entry.sequenceOffset; + r->hotspotScriptOffset = entry.hotspotScriptOffset; + r->talkScriptOffset = entry.talkScriptOffset; r->tickProcOffset = entry.tickProcOffset; r->flags = entry.flags; @@ -473,6 +474,8 @@ void read_anim_data(byte *&data, uint16 &totalSize) { add_anim_record(0x5ce9); // Blacksmith in bar? add_anim_record(0x5915); // Blacksmith hammering add_anim_record(0x59ED); // Ewan's alternate animation + add_anim_record(0x5CAA); // Selena animation + add_anim_record(0x5D28); // Goewin animation // Get the animation data records AnimRecord inRec; @@ -884,7 +887,7 @@ void read_room_exit_coordinate_data(byte *&data, uint16 &totalSize) // Post process the list to adjust data RoomExitCoordinateEntryResource *rec = (RoomExitCoordinateEntryResource *) data; - for (roomNum = 0; roomNum < EXIT_COORDINATES_NUM_ROOMS; ++roomNum, ++rec) { + for (roomNum = 1; roomNum <= EXIT_COORDINATES_NUM_ROOMS; ++roomNum, ++rec) { for (entryNum = 0; entryNum < ROOM_EXIT_COORDINATES_NUM_ENTRIES; ++entryNum) { if ((rec->entries[entryNum].x != 0) || (rec->entries[entryNum].y != 0)) { rec->entries[entryNum].x = TO_LE_16(FROM_LE_16(rec->entries[entryNum].x) - 0x80); @@ -897,6 +900,10 @@ void read_room_exit_coordinate_data(byte *&data, uint16 &totalSize) for (entryNum = 0; entryNum < ROOM_EXIT_COORDINATES_ENTRY_NUM_ROOMS; ++entryNum) { rec->roomIndex[entryNum] = TO_LE_16(FROM_LE_16(rec->roomIndex[entryNum]) / 6); } + + // Bugfix for the original game data to get to room #27 via rooms #10 or #11 + if ((roomNum == 10) || (roomNum == 11)) + rec->roomIndex[26] = 1; } } diff --git a/tools/create_lure/create_lure_dat.h b/tools/create_lure/create_lure_dat.h index 50ddf4bfe0..b3fd6d198a 100644 --- a/tools/create_lure/create_lure_dat.h +++ b/tools/create_lure/create_lure_dat.h @@ -27,7 +27,7 @@ #include "common/endian.h" #define VERSION_MAJOR 1 -#define VERSION_MINOR 17 +#define VERSION_MINOR 19 #define ENGLISH_LURE #define DATA_SEGMENT 0xac50 @@ -136,11 +136,13 @@ struct HotspotResource { uint16 tickTimeout; uint16 animOffset; byte colourOffset; - uint16 sequenceOffset; - byte unknown4[15]; + uint16 hotspotScriptOffset; + byte unused1[7]; + uint16 talkScriptOffset; + byte unused2[6]; int8 talkX; int8 talkY; - byte unused5[11]; + byte unused3[11]; uint16 delayCtr; uint8 characterMode; uint16 tickSequenceOffset; @@ -176,7 +178,8 @@ struct HotspotResourceOutput { int8 talkY; uint16 colourOffset; uint16 animRecordId; - uint16 sequenceOffset; + uint16 hotspotScriptOffset; + uint16 talkScriptOffset; uint16 tickProcOffset; uint16 tickTimeout; uint16 tickSequenceOffset; diff --git a/tools/credits.pl b/tools/credits.pl index af3d13865b..00a19944fa 100755 --- a/tools/credits.pl +++ b/tools/credits.pl @@ -484,6 +484,7 @@ begin_credits("Credits"); begin_section("AGI"); add_person("Stuart George", "darkfiber", ""); + add_person("Filippos Karapetis", "[md5]", ""); add_person("Paweł Kołodziejski", "aquadran", ""); add_person("Eugene Sandulenko", "sev", ""); add_person("David Symonds", "dsymonds", ""); @@ -511,11 +512,16 @@ begin_credits("Credits"); end_section(); begin_section("Cinematique evo 1"); + add_person("Vincent Hamm", "yazoo", "original CinE engine author"); add_person("Paweł Kołodziejski", "aquadran", ""); add_person("Gregory Montoir", "cyx", ""); add_person("Eugene Sandulenko", "sev", ""); end_section(); + begin_section("Cinematique evo 2"); + add_person("Vincent Hamm", "yazoo", ""); + end_section(); + begin_section("FOTAQ"); # Flight of the Amazon Queen add_person("David Eriksson", "twogood", ""); add_person("Gregory Montoir", "cyx", ""); @@ -540,8 +546,13 @@ begin_credits("Credits"); add_person("Paul Gilbert", "dreammaster", ""); end_section(); + begin_section("Parallaction"); + add_person("", "peres", ""); + end_section(); + begin_section("SAGA"); add_person("Torbjörn Andersson", "eriktorbjorn", ""); + add_person("Filippos Karapetis", "[md5]", ""); add_person("Andrew Kurushin", "ajax16384", ""); add_person("Eugene Sandulenko", "sev", ""); end_section(); @@ -576,7 +587,7 @@ begin_credits("Credits"); begin_section("PocketPC / WinCE"); add_person("Nicolas Bacca", "arisme", ""); - add_person("Kostas Nakos", "knakos", ""); + add_person("Kostas Nakos", "Jubanka", ""); end_section(); begin_section("PlayStation 2"); @@ -632,7 +643,6 @@ begin_credits("Credits"); add_person("Tore Anderson", "tore", "Former Debian GNU/Linux maintainer"); add_person("Ralph Brorsen", "painelf", "Help with GUI implementation"); add_person("Jamieson Christian", "jamieson630", "iMUSE, MIDI, all things musical"); - add_person("Vincent Hamm", "yazoo", "Co-Founder, original CinE engine author"); add_person("Rüdiger Hanke", "", "Port: MorphOS"); add_person("Felix Jakschitsch", "yot", "Zak256 reverse engineering"); add_person("Mutwin Kraus", "mutle", "Original MacOS porter"); @@ -733,6 +743,7 @@ begin_credits("Credits"); add_person("Andreas Karlsson", "Sprawl", "Initial port for EPOC/SymbianOS"); add_person("Claudio Matsuoka", "", "Daily Linux builds"); add_person("Thomas Mayer", "", "PSP port contributions"); + add_person("", "n0p", "Windows CE port aspect ratio correction scaler and right click input method"); add_person("Mikesch Nepomuk", "", "MI1 VGA floppy patches"); add_person("Nicolas Noble", "pixels", "Config file and ALSA support"); add_person("", "Quietust", "Sound support for Amiga SCUMM V2/V3 games, MM NES support"); @@ -741,6 +752,7 @@ begin_credits("Credits"); add_person("Daniel Schepler", "", "Final MI1 CD music support, initial Ogg Vorbis support"); add_person("André Souza", "", "SDL-based OpenGL renderer"); add_person("Tim Phillips", "realmz", "Initial MI1 CD music support"); + add_person("Robin Watts", "", "ARM assembly routines for the Windows CE port"); end_persons(); end_section(); diff --git a/tools/module.mk b/tools/module.mk index ec88fefc4e..eb8b47aec0 100644 --- a/tools/module.mk +++ b/tools/module.mk @@ -43,7 +43,6 @@ tools/md5table$(EXEEXT): $(srcdir)/tools/md5table.c credits: $(srcdir)/tools/credits.pl --text > AUTHORS - $(srcdir)/tools/credits.pl --tex > doc/credits.tex $(srcdir)/tools/credits.pl --rtf > Credits.rtf $(srcdir)/tools/credits.pl --cpp > gui/credits.h $(srcdir)/tools/credits.pl --html > ../../web/trunk/credits.inc diff --git a/tools/scumm-md5.txt b/tools/scumm-md5.txt index bf3ff24f3d..711b59dc87 100644 --- a/tools/scumm-md5.txt +++ b/tools/scumm-md5.txt @@ -155,6 +155,7 @@ loom Loom 73e5ab7dbb9a8061cc6d25df02dbd1e7 -1 en DOS EGA EGA v1.0 alt Andrea Petrucci 37f56ceb13e401a7ac7d9e6b37fecaf7 5748 en DOS EGA EGA v1.1 from 16 Mar 90 Kirben, Andrea Petrucci, Peter Eckerlein 22f4ea88a09da12df9308ba30bcb7d0f -1 en DOS EGA EGA v1.1 from 29 Mar 90 James Grosbeck, Peter Eckerlein + cd46c9f122272d02bbf79332ff521898 5748 ru DOS EGA EGA v1.1 sev b886b0a5d909c7158a914e1d7c1c6c65 -1 fr DOS EGA EGA - Andrea Petrucci 6f8a22bfa397be1f7ed4b74aba0e397e -1 fr DOS EGA EGA v1.2 26 Jun 90 Jorpho 470c45b636139bb40716daa1c7edaad0 -1 de DOS EGA EGA v1.2 Deutsch from 7 Jun 90 Peter Eckerlein @@ -481,6 +482,7 @@ freddi4 Freddi Fish 4: The Case of the Hogfish Rustlers of Briny Gulch 4f580a021eee026f3b4589e17d130d78 -1 All All - - - Kirben, sev 14d48c95b43ddeb983254cf6c43851f1 -1 nl All - - - adutchguy, daniel9 d74122362a77ec24525fdd50297dfd82 -1 fr Mac - - - ThierryFR + 3b832f4a90740bf22e9b8ed42ca0128c -1 gb Windows HE 99 - - Reckless 07b810e37be7489263f7bc7627d4765d -1 ru Windows unenc Unencrypted - sev b5298a5c15ffbe8b381d51ea4e26d35c -1 de All HE 99 - - Joachim Eberhard 4f138ac6f9b2ac5a41bc68b2c3296064 -1 fr Windows HE 99 - - gist974 @@ -618,6 +620,7 @@ puttrace Putt-Putt Enters the Race 981e1e1891f2be7e25a01f50ae55a5af -1 us All HE 98 - - Kirben 1ed22f601f8b3695804a6583cc3083f1 -1 nl All HE 98.5 - - daniel9 33e989f85da700e2014d00f345cab3d7 -1 fr Windows HE 98.5 - - gist974 + b47be81e39a9710f6f595f7b527b60f8 -1 gb Windows HE 99 - - Reckless 055ffe4f47753e47594ac67823220c54 -1 de All HE 99 - - Joachim Eberhard 62050da376483d8edcbd98cd26b6cb57 -1 ru Windows HE 99 - - sev @@ -645,6 +648,7 @@ puttcircus Putt-Putt Joins the Circus ecc4340c2b801f5af8da4e00c0e432d9 -1 nl All - - - daniel9 ab0693e9324cfcf498fdcbb12acf8bb4 -1 en All - - - sev 7bad72e332a59f9fcc1d437f4edad32a -1 ru All - - - sev + db74136c20557eca6ed3411bff39f7a1 -1 gb Windows - - - Reckless d0ad929def3e9cfe39dea55bd12098d4 -1 fr Windows - - - gist974 febf4a983ea5faea1c9dd6c710ebb09c -1 de Windows - - - andy482 |